diff -u --recursive --new-file v1.3.77/linux/CREDITS linux/CREDITS
--- v1.3.77/linux/CREDITS	Thu Mar 21 20:36:50 1996
+++ linux/CREDITS	Mon Mar 25 08:58:19 1996
@@ -298,6 +298,7 @@
 
 N: Bjorn Ekwall
 E: bj0rn@blox.se
+W: http://www.pi.se/blox/
 D: Extended support for loadable modules
 D: D-Link pocket adapter drivers
 S: Myrstuguv. 83
@@ -735,6 +736,15 @@
 D: XF86_Mach8
 D: XF86_8514
 D: cfdisk (curses based disk partitioning program)
+
+N: Mike McLagan
+E: mike.mclagan@linux.org
+W: http://www.invlogic.com/~mmclagan
+S: Innovative Logic Corp
+S: P.O. Box 1068
+S: Laurel, MD  20732
+S: USA
+D: DLCI/FRAD drivers for Sangoma SDLAs
 
 N: Bradley McLean
 E: brad@bradpc.gaylord.com
diff -u --recursive --new-file v1.3.77/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v1.3.77/linux/Documentation/Configure.help	Wed Mar 20 10:59:53 1996
+++ linux/Documentation/Configure.help	Mon Mar 25 08:58:19 1996
@@ -654,6 +654,26 @@
   later on, such as a user level "beeper" and a generic screen blanker.
   The "kerneld" daemon is included in "modules-1.2.8" and later.
 
+ARP daemon support
+CONFIG_ARPD
+  Normally, the kernel maintains an internal cache which maps IP 
+  addresses to hardware addresses on the local network, so that
+  Ethernet/Token Ring/ etc. frames are sent to the proper address
+  on the physical networking layer.  For small networks having
+  a few hundred directly connected hosts or less, keeping  this
+  address resolution cache (ARP) inside the kernel works well.
+  However, maintaining an internal ARP cache does not work well for
+  very large switched networks, and will use a lot of kernel memory
+  if TCP/IP connections are made to many machines on the network.
+  By enabling this option, the kernel's internal ARP cache will
+  never grow to more than 256 entries (the oldest entries are 
+  expired in a LIFO manner) and communication will be attempted
+  with an external ARP daemon, arpd, via the kerneld message
+  queue.  This code is still experimental.  If you do enable
+  arpd support, you should obtain a copy of arpd from
+  http://www.loran.com/~layes/arpd/index.html.  If unsure,
+  say N.  
+
 TCP/IP networking
 CONFIG_INET
   These are the protocols used on the Internet and on most local
diff -u --recursive --new-file v1.3.77/linux/Documentation/cdrom/optcd linux/Documentation/cdrom/optcd
--- v1.3.77/linux/Documentation/cdrom/optcd	Wed Feb 28 11:49:58 1996
+++ linux/Documentation/cdrom/optcd	Fri Mar 22 15:45:13 1996
@@ -7,7 +7,7 @@
 please drop me a mail.
 
 The support for multisession CDs is in ALPHA stage. If you use it,
-please mail me your experiences. Multisession support can be disables
+please mail me your experiences. Multisession support can be disabled
 at compile time.
 
 You can find some older versions of the driver at
diff -u --recursive --new-file v1.3.77/linux/Documentation/devices.tex linux/Documentation/devices.tex
--- v1.3.77/linux/Documentation/devices.tex	Wed Mar 13 10:09:08 1996
+++ linux/Documentation/devices.tex	Sun Mar 24 20:07:00 1996
@@ -416,7 +416,7 @@
 \noindent
 The loopback devices are used to mount filesystems not associated with
 block devices.  The binding to the loopback devices is usually handled
-by mount(1).
+by mount(8).
 
 \begin{devicelist}
 \major{11}{}{char }{Raw keyboard device}
diff -u --recursive --new-file v1.3.77/linux/Documentation/devices.txt linux/Documentation/devices.txt
--- v1.3.77/linux/Documentation/devices.txt	Wed Mar 13 10:09:08 1996
+++ linux/Documentation/devices.txt	Sun Mar 24 20:07:00 1996
@@ -194,7 +194,7 @@
 
 		The loopback devices are used to mount filesystems not
 		associated with block devices.  The binding to the
-		loopback devices is usually handled by mount(1).
+		loopback devices is usually handled by mount(8).
 
   8 block	SCSI disk devices
     		  0 = /dev/sda		First SCSI disk whole disk
diff -u --recursive --new-file v1.3.77/linux/Documentation/framerelay.txt linux/Documentation/framerelay.txt
--- v1.3.77/linux/Documentation/framerelay.txt	Thu Jan  1 02:00:00 1970
+++ linux/Documentation/framerelay.txt	Mon Mar 25 08:58:20 1996
@@ -0,0 +1,33 @@
+Frame Relay (FR) support for linux is built into a two tiered system of device 
+drivers.  The upper layer implements RFC1490 FR specification, and uses the
+Data Link Connection Identifier (DLCI) as it's hardware address.  Usually these
+are assigned by your network supplier, they give you the number/numbers of
+the Virtual Connections (VC) assigned to you.
+
+Each DLCI is a point-to-point link between your machine and a remote one.
+As such, a seperate device is needed to accomodate the routing.  Within the
+net-tools archives is 'dlcicfg'.  This program will communicate with the
+base "DLCI" device, and create new net devices named 'dlci00', 'dlci01'... 
+The configuration script will ask you how many DLCI's you need, as well as
+how many DLCI's you want to assign to each Frame Relay Access Device (FRAD).
+
+The DLCI uses a number of function calls to communicate with the FRAD, all
+of which are stored in the FRAD's private data area.  assoc/deassoc, 
+activate/deactivate and dlci_config.  The DLCI supplies a receive function
+to the FRAD to accept incoming packets.
+
+With this initial offering, only 1 FRAD driver is available.  With many thanks
+to Sangoma Technologies, David Mandelstam & Gene Kozin, the S502A, S502E & 
+S508 are supported.  This driver is currently set up for only FR, but as 
+Sangoma makes more firmware modules available, it can be updated to provide
+them as well.
+
+Configuration of the FRAD makes use of another net-tools program, 'fradcfg'.
+This program makes use of a configuration file (which dlcicfg can also read)
+to specify the types of boards to be configured as FRADs, as well as perform
+any board specific configuration.  The Sangoma module of fradcfg loads the
+FR firmware into the card, sets the irq/port/memory information, and provides
+an initial configuration.
+
+Additional FRAD device drivers can be added as hardware is available.
+
diff -u --recursive --new-file v1.3.77/linux/MAGIC linux/MAGIC
--- v1.3.77/linux/MAGIC	Tue Mar  5 10:10:44 1996
+++ linux/MAGIC	Fri Mar 22 12:58:41 1996
@@ -94,6 +94,7 @@
 'f'	linux/ext2_fs.h
 'm'	linux/mtio.h		conflict!
 'm'	linux/soundcard.h	conflict!
+'n'	linux/ncp_fs.h
 's'	linux/cdk.h
 't'	linux/if_ppp.h
 'u'	linux/smb_fs.h
diff -u --recursive --new-file v1.3.77/linux/MAINTAINERS linux/MAINTAINERS
--- v1.3.77/linux/MAINTAINERS	Wed Mar 20 10:59:53 1996
+++ linux/MAINTAINERS	Mon Mar 25 08:58:20 1996
@@ -48,6 +48,7 @@
 P: Person
 M: Mail patches to
 L: Mailing list that is relevant to this area
+W: Web-page with status/info
 S: Status
 	Supported:	Someone is actually paid to look after this (wildly
 			improbable).
@@ -89,6 +90,12 @@
 L:	None
 S:	Maintained
 
+FRAME RELAY DLCI/FRAD (Sangoma drivers too)
+P:	Mike McLagan
+M:	mike.mclagan@linux.org
+L:	linux-net@vger.rutgers.edu
+S:	Maintained
+
 FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
 P:      Rik Faith
 M:      faith@cs.unc.edu
@@ -122,7 +129,14 @@
 MODULE SUPPORT [GENERAL], KERNELD
 P:	Bjorn Ekwall
 M:	bj0rn@blox.se
+W:	http://www.pi.se/blox/modules/
 L:	linux-kernel@vger.rutgers.edu
+S:	Maintained
+
+ARPD SUPPORT
+P:	Jonathan Layes
+M:	layes@loran.com
+L:	linux-net@vger.rutgers.edu
 S:	Maintained
 
 NCP FILESYSTEM:
diff -u --recursive --new-file v1.3.77/linux/Makefile linux/Makefile
--- v1.3.77/linux/Makefile	Thu Mar 21 20:36:50 1996
+++ linux/Makefile	Thu Mar 21 20:37:45 1996
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 77
+SUBLEVEL = 78
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.77/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v1.3.77/linux/arch/alpha/config.in	Sun Mar 17 09:04:03 1996
+++ linux/arch/alpha/config.in	Sun Mar 24 12:09:35 1996
@@ -55,14 +55,15 @@
 	define_bool CONFIG_PCI y
 	define_bool CONFIG_ALPHA_EV5 y
 	define_bool CONFIG_ALPHA_ALCOR y
+else
+	# EV5 and newer supports all rounding modes in hw:
+	define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
 fi
 
 if [ "$CONFIG_ALPHA_JENSEN" = "y" ]
 then
 	bool 'Using SRM as bootloader' CONFIG_ALPHA_SRM
 fi
-
-define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
 
 bool 'Echo console messages on /dev/ttyS1' CONFIG_SERIAL_ECHO
 if [ "$CONFIG_PCI" = "y" ]; then
diff -u --recursive --new-file v1.3.77/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v1.3.77/linux/arch/alpha/defconfig	Wed Mar 20 10:59:53 1996
+++ linux/arch/alpha/defconfig	Mon Mar 25 11:56:11 1996
@@ -24,7 +24,6 @@
 CONFIG_PCI=y
 CONFIG_ALPHA_EV5=y
 CONFIG_ALPHA_ALCOR=y
-CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
 # CONFIG_SERIAL_ECHO is not set
 # CONFIG_TGA_CONSOLE is not set
 CONFIG_PCI_OPTIMIZE=y
@@ -134,6 +133,7 @@
 # CONFIG_SCC is not set
 # CONFIG_PLIP is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_FRAD is not set
 # CONFIG_NET_ALPHA is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_LANCE is not set
diff -u --recursive --new-file v1.3.77/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v1.3.77/linux/arch/alpha/kernel/time.c	Wed Oct  4 14:14:28 1995
+++ linux/arch/alpha/kernel/time.c	Sun Mar 24 12:09:35 1996
@@ -20,23 +20,62 @@
 
 #include <asm/segment.h>
 #include <asm/io.h>
+#include <asm/hwrpb.h>
 
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
 #define TIMER_IRQ 0
 
+extern struct hwrpb_struct *hwrpb;
+
 static int set_rtc_mmss(unsigned long);
 
+
+/*
+ * Shift amount by which scaled_ticks_per_cycle is scaled.  Shifting
+ * by 48 gives us 16 bits for HZ while keeping the accuracy good even
+ * for large CPU clock rates.
+ */
+#define FIX_SHIFT	48
+
+/* lump static variables together for more efficient access: */
+static struct {
+	__u32		last_time;		/* cycle counter last time it got invoked */
+	__u32		max_cycles_per_tick;	/* more makes us think we lost an interrupt */
+	unsigned long	scaled_ticks_per_cycle;	/* ticks/cycle * 2^48 */
+	long		last_rtc_update;	/* last time the cmos clock got updated */
+} state;
+
+
+static inline __u32 rpcc(void)
+{
+    __u32 result;
+
+    asm volatile ("rpcc %0" : "r="(result));
+    return result;
+}
+
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
 void timer_interrupt(struct pt_regs * regs)
 {
-	/* last time the cmos clock got updated */
-	static long last_rtc_update=0;
+	__u32 delta, now;
 
+	now = rpcc();
+	delta = now - state.last_time;
+	state.last_time = now;
+	if (delta > state.max_cycles_per_tick) {
+		int i, missed_ticks;
+
+		missed_ticks = ((delta * state.scaled_ticks_per_cycle) >> FIX_SHIFT) - 1;
+		for (i = 0; i < missed_ticks; ++i) {
+			do_timer(regs);
+		}
+	}
 	do_timer(regs);
 
 	/*
@@ -44,13 +83,13 @@
 	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
 	 * called as close as possible to 500 ms before the new second starts.
 	 */
-	if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+	if (time_state != TIME_BAD && xtime.tv_sec > state.last_rtc_update + 660 &&
 	    xtime.tv_usec > 500000 - (tick >> 1) &&
 	    xtime.tv_usec < 500000 + (tick >> 1))
 	  if (set_rtc_mmss(xtime.tv_sec) == 0)
-	    last_rtc_update = xtime.tv_sec;
+	    state.last_rtc_update = xtime.tv_sec;
 	  else
-	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	    state.last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 }
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
@@ -130,6 +169,15 @@
 		year += 100;
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
 	xtime.tv_usec = 0;
+
+	if (HZ > (1<<16)) {
+		extern void __you_loose (void);
+		__you_loose();
+	}
+	state.last_time = rpcc();
+	state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
+	state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ;
+	state.last_rtc_update = 0;
 }
 
 /*
diff -u --recursive --new-file v1.3.77/linux/arch/alpha/math-emu/fp-emul.c linux/arch/alpha/math-emu/fp-emul.c
--- v1.3.77/linux/arch/alpha/math-emu/fp-emul.c	Tue Mar  5 10:10:45 1996
+++ linux/arch/alpha/math-emu/fp-emul.c	Sun Mar 24 12:09:35 1996
@@ -175,7 +175,7 @@
 
 	insn = get_user((__u32*)pc);
 	fc     = (insn >>  0) &  0x1f;	/* destination register */
-	func   = (insn >>  5) & 0x3ff;
+	func   = (insn >>  5) & 0x7ff;
 	fb     = (insn >> 16) &  0x1f;
 	fa     = (insn >> 21) &  0x1f;
 	opcode = insn >> 26;
diff -u --recursive --new-file v1.3.77/linux/arch/alpha/math-emu/ieee-math.c linux/arch/alpha/math-emu/ieee-math.c
--- v1.3.77/linux/arch/alpha/math-emu/ieee-math.c	Tue Dec 26 04:45:35 1995
+++ linux/arch/alpha/math-emu/ieee-math.c	Sun Mar 24 12:09:35 1996
@@ -501,7 +501,7 @@
 
 
 static unsigned long
-round_t_ieee (EXTENDED *a, unsigned long *b, int f)
+round_t_ieee (int f, EXTENDED *a, unsigned long *b)
 {
 	unsigned long diff1, diff2, res;
 	EXTENDED z1, z2;
@@ -626,7 +626,7 @@
 		}
 		return 0;
 	}
-	return round_s_ieee(f, &temp, b);
+	return round_t_ieee(f, &temp, b);
 }
 
 
@@ -717,7 +717,7 @@
 	}
 	op_b.e = 55;
 	normalize(&op_b);
-	return round_t_ieee(&op_b, b, f);
+	return round_t_ieee(f, &op_b, b);
 }
 
 
@@ -993,7 +993,7 @@
 	if (a_type == ZERO && b_type == ZERO)
 		op_c.s = op_a.s && op_b.s;
 
-	return round_t_ieee(&op_c, c, f);	
+	return round_t_ieee(f, &op_c, c);
 }
 
 
@@ -1093,7 +1093,7 @@
 	if (a_type == ZERO && b_type == ZERO)
 		op_c.s = op_a.s && op_b.s;
 
-	return round_t_ieee(&op_c, c, f);
+	return round_t_ieee(f, &op_c, c);
 }
 
 
@@ -1206,7 +1206,7 @@
 	normalize(&op_c);
 	op_c.e -= 55;	/* drop the 55 original bits. */
 
-	return round_t_ieee(&op_c, c, f);
+	return round_t_ieee(f, &op_c, c);
 }
 
 
@@ -1339,5 +1339,5 @@
 		op_c.f[0] |= STICKY_T;
 	normalize(&op_c);
 	op_c.e -= 9;		/* remove excess exp from original shift */
-	return round_t_ieee(&op_c, c, f);
+	return round_t_ieee(f, &op_c, c);
 }
diff -u --recursive --new-file v1.3.77/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- v1.3.77/linux/arch/i386/boot/setup.S	Wed Mar 20 10:59:53 1996
+++ linux/arch/i386/boot/setup.S	Mon Mar 25 08:14:44 1996
@@ -74,8 +74,10 @@
 					!      Bootlin, SYSLX, bootsect...)
 					! else it is set by the loader:
 					! 0xTV: T=0 for LILO
-					!       T=1 for Loadlin
-					!       T=2 for bootsect-loader
+					!	T=1 for Loadlin
+					!	T=2 for bootsect-loader
+					!	T=3 for SYSLX
+					!	T=4 for ETHERBOOT
 					!       V = version
 loadflags:	.byte	0	! unused bits =0 (reserved for future development)
 LOADED_HIGH	= 1		! bit within loadflags,
diff -u --recursive --new-file v1.3.77/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v1.3.77/linux/arch/i386/defconfig	Sun Mar 17 09:04:04 1996
+++ linux/arch/i386/defconfig	Mon Mar 25 10:00:22 1996
@@ -47,6 +47,7 @@
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_MD is not set
+
 #
 # Networking options
 #
@@ -90,6 +91,7 @@
 # CONFIG_SCC is not set
 # CONFIG_PLIP is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_FRAD is not set
 # CONFIG_NET_ALPHA is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_LANCE is not set
diff -u --recursive --new-file v1.3.77/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v1.3.77/linux/arch/i386/kernel/entry.S	Wed Mar 13 10:09:11 1996
+++ linux/arch/i386/kernel/entry.S	Fri Mar 22 08:34:24 1996
@@ -688,4 +688,5 @@
 	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
 	.long SYMBOL_NAME(sys_sched_rr_get_interval)
 	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
 	.space (NR_syscalls-163)*4
diff -u --recursive --new-file v1.3.77/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v1.3.77/linux/arch/i386/kernel/smp.c	Wed Mar 20 10:59:54 1996
+++ linux/arch/i386/kernel/smp.c	Mon Mar 25 08:58:20 1996
@@ -51,14 +51,14 @@
 int smp_found_config=0;					/* Have we found an SMP box 				*/
 
 unsigned long cpu_present_map = 0;			/* Bitmask of existing CPU's 				*/
-int smp_num_cpus;					/* Total count of live CPU's 				*/
+int smp_num_cpus = 1;					/* Total count of live CPU's 				*/
 int smp_threads_ready=0;				/* Set when the idlers are all forked 			*/
 volatile int cpu_number_map[NR_CPUS];			/* which CPU maps to which logical number		*/
+volatile int cpu_logical_map[NR_CPUS];			/* which logical number maps to which CPU		*/
 volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};	/* We always use 0 the rest is ready for parallel delivery */
 volatile unsigned long smp_invalidate_needed;		/* Used for the invalidate map thats also checked in the spinlock */
 struct cpuinfo_x86 cpu_data[NR_CPUS];			/* Per cpu bogomips and other parameters 		*/
 static unsigned int num_processors = 1;			/* Internal processor count				*/
-int smp_top_cpu = 0;					/* Highest used APIC id 				*/
 static unsigned long io_apic_addr = 0xFEC00000;		/* Address of the I/O apic (not yet used) 		*/
 unsigned char boot_cpu_id = 0;				/* Processor that is doing the boot up 			*/
 static unsigned char *kstack_base,*kstack_end;		/* Kernel stack list pointers 				*/
@@ -220,7 +220,6 @@
 					{
 						SMP_PRINTK(("    Bootup CPU\n"));
 						boot_cpu_id=m->mpc_apicid;
-						nlong = boot_cpu_id<<24;	/* Dummy 'self' for bootup */
 					}
 					else	/* Boot CPU already counted */
 						num_processors++;
@@ -294,7 +293,7 @@
  *	Scan the memory blocks for an SMP configuration block.
  */
  
-void smp_scan_config(unsigned long base, unsigned long length)
+int smp_scan_config(unsigned long base, unsigned long length)
 {
 	unsigned long *bp=(unsigned long *)base;
 	struct intel_mp_floating *mpf;
@@ -325,54 +324,18 @@
 				 */
 				if(mpf->mpf_feature1!=0)
 				{
-					num_processors=2;
-					printk("I/O APIC at 0xFEC00000.\n");
-					printk("Bus#0 is ");
-				}
-				switch(mpf->mpf_feature1)
-				{
-					case 1:
-					case 5:
-						printk("ISA\n");
-						break;
-					case 2:
-						printk("EISA with no IRQ8 chaining\n");
-						break;
-					case 6:
-					case 3:
-						printk("EISA\n");
-						break;
-					case 4:
-					case 7:
-						printk("MCA\n");
-						break;
-					case 0:
-						break;
-					default:
-						printk("???\nUnknown standard configuration %d\n",
-							mpf->mpf_feature1);
-						return;
-				}
-				if(mpf->mpf_feature1>4)
-					printk("Bus #1 is PCI\n");
-				/*
-				 *	Read the physical hardware table.
-				 */
-				if(mpf->mpf_physptr)
-					smp_read_mpc((void *)mpf->mpf_physptr);
-				else
-				{
 					unsigned long cfg;
 
 					/*
-					 *	If no table present, determine
-					 *	what the CPU mapping is.
+					 *	We need to know what the local
+					 *	APIC id of the boot CPU is!
 					 */
 
 /*
  *
  *	HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
  *
+ *	It's not just a crazy hack...  ;-)
  */
 					/*
 					 *	Standard page mapping
@@ -386,7 +349,6 @@
 					local_invalidate();
 
 					boot_cpu_id = GET_APIC_ID(*((volatile unsigned long *) APIC_ID));
-					nlong = boot_cpu_id<<24;	/* Dummy 'self' for bootup */
 
 					/*
 					 *	Give it back
@@ -400,26 +362,79 @@
  *	END OF HACK   END OF HACK   END OF HACK   END OF HACK   END OF HACK
  *
  */					
+					/*
+					 *	2 CPUs, numbered 0 & 1.
+					 */
+					cpu_present_map=3;
+					num_processors=2;
+					printk("I/O APIC at 0xFEC00000.\n");
+					printk("Bus#0 is ");
+				}
+				switch(mpf->mpf_feature1)
+				{
+					case 1:
+					case 5:
+						printk("ISA\n");
+						break;
+					case 2:
+						printk("EISA with no IRQ8 chaining\n");
+						break;
+					case 6:
+					case 3:
+						printk("EISA\n");
+						break;
+					case 4:
+					case 7:
+						printk("MCA\n");
+						break;
+					case 0:
+						break;
+					default:
+						printk("???\nUnknown standard configuration %d\n",
+							mpf->mpf_feature1);
+						return 1;
+				}
+				if(mpf->mpf_feature1>4)
+				{
+					printk("Bus #1 is PCI\n");
 
 					/*
-					 *	If boot CPU != 0, other CPU
-					 *	is 0, else other CPU is 1.
+					 *	Set local APIC version to
+					 *	the integrated form.
+					 *	It's initialized to zero
+					 *	otherwise, representing
+					 *	a discrete 82489DX.
 					 */
-					if (boot_cpu_id)
-						cpu_present_map=1 | (1 << boot_cpu_id);
-					else
-						cpu_present_map=3;
+					apic_version[0] = 0x10;
+					apic_version[1] = 0x10;
 				}
+				/*
+				 *	Read the physical hardware table.
+				 *	Anything here will override the
+				 *	defaults.
+				 */
+				if(mpf->mpf_physptr)
+					smp_read_mpc((void *)mpf->mpf_physptr);
+
+				/*
+				 *	Now that the boot CPU id is known,
+				 *	set some other information about it.
+				 */
+				nlong = boot_cpu_id<<24;	/* Dummy 'self' for bootup */
+				cpu_logical_map[0] = boot_cpu_id;
+
 				printk("Processors: %d\n", num_processors);
 				/*
-				 *	Only use the first one found.
+				 *	Only use the first configuration found.
 				 */
-				return;
+				return 1;
 			}
 		}
 		bp+=4;
 		length-=16;
 	}
+
+	return 0;
 }
 
 /*
@@ -565,7 +580,7 @@
  
 void smp_boot_cpus(void)
 {
-	int i,j;
+	int i;
 	int cpucount=0;
 	unsigned long cfg;
 	void *stack;
@@ -667,15 +682,12 @@
 		 *	Don't even attempt to start the boot CPU!
 		 */
 		if (i == boot_cpu_id)
-		{
-			smp_top_cpu=max(smp_top_cpu,i);
 			continue;
-		}
 		
 		if (cpu_present_map & (1 << i))
 		{
 			unsigned long send_status, accept_status;
-			int timeout, num_starts;
+			int timeout, num_starts, j;
 			
 			/*
 			 *	We need a kernel stack for each processor.
@@ -719,8 +731,11 @@
 			 *	Be paranoid about clearing APIC errors.
 			 */
 
-			apic_write(APIC_ESR, 0);
-			accept_status = (apic_read(APIC_ESR) & 0xEF);
+			if ( apic_version[i] & 0xF0 )
+			{
+				apic_write(APIC_ESR, 0);
+				accept_status = (apic_read(APIC_ESR) & 0xEF);
+			}
 			
 			/*
 			 *	Status is now clean
@@ -777,8 +792,8 @@
 			 *	Run STARTUP IPI loop.
 			 */
 
-			for (j = 0; !(send_status || accept_status)
-				    && (j < num_starts) ; j++)
+			for (j = 1; !(send_status || accept_status)
+				    && (j <= num_starts) ; j++)
 			{
 				SMP_PRINTK(("Sending STARTUP #%d.\n",j));
 
@@ -826,8 +841,7 @@
 					cpucount++;
 					/* number CPUs logically, starting from 1 (BSP is 0) */
 					cpu_number_map[i] = cpucount;
-					smp_top_cpu=max(smp_top_cpu,i);
-					
+					cpu_logical_map[cpucount] = i;
 				}
 				else
 				{
@@ -951,10 +965,12 @@
 	/*
 	 *	Sanity check we don't re-enter this across CPU's. Only the kernel
 	 *	lock holder may send messages. For a STOP_CPU we are bringing the
-	 *	entire box to the fastest halt we can.. 
+	 *	entire box to the fastest halt we can.. A reschedule carries
+	 *	no data and can occur during an invalidate.. guess what panic
+	 *	I got to notice this bug...
 	 */
 	 
-	if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU)
+	if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU && msg!=MSG_RESCHEDULE)
 	{
 		panic("CPU #%d: Message pass %d but pass in progress by %d of %d\n",
 			smp_processor_id(),msg,message_cpu, smp_msg_id);
diff -u --recursive --new-file v1.3.77/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- v1.3.77/linux/arch/i386/mm/init.c	Sun Mar 17 09:04:04 1996
+++ linux/arch/i386/mm/init.c	Mon Mar 25 08:58:20 1996
@@ -128,13 +128,15 @@
 	memset((void *) 0, 0, PAGE_SIZE);
 #endif
 #ifdef __SMP__
-	smp_scan_config(0x0,0x400);	/* Scan the bottom 1K for a signature */
-	/*
-	 *	FIXME: Linux assumes you have 640K of base ram.. this continues
-	 *	the error...
-	 */
-	smp_scan_config(639*0x400,0x400);	/* Scan the top 1K of base RAM */
-	smp_scan_config(0xF0000,0x10000);	/* Scan the 64K of bios */
+	if (!smp_scan_config(0x0,0x400))	/* Scan the bottom 1K for a signature */
+	{
+		/*
+		 *	FIXME: Linux assumes you have 640K of base ram.. this continues
+		 *	the error...
+		 */
+		if (!smp_scan_config(639*0x400,0x400))	/* Scan the top 1K of base RAM */
+			smp_scan_config(0xF0000,0x10000);	/* Scan the 64K of bios */
+	}
 	/*
 	 *	If it is an SMP machine we should know now, unless the configuration
 	 *	is in an EISA/MCA bus machine with an extended bios data area. I don't
diff -u --recursive --new-file v1.3.77/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v1.3.77/linux/drivers/block/floppy.c	Wed Mar 20 10:59:54 1996
+++ linux/drivers/block/floppy.c	Sun Mar 24 18:57:04 1996
@@ -2597,7 +2597,7 @@
 	}
 
 	while(1){
-		if (!CURRENT) {
+		if (!CURRENT || CURRENT_PLUGGED) {
 			CLEAR_INTR;
 			unlock_fdc();
 			return;
diff -u --recursive --new-file v1.3.77/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.3.77/linux/drivers/block/ide.c	Wed Mar 20 10:59:56 1996
+++ linux/drivers/block/ide.c	Sun Mar 24 18:57:04 1996
@@ -1469,6 +1469,8 @@
 			 */
 			hwif = hwgroup->next_hwif;
 			do {
+				if (IS_PLUGGED(blk_dev + hwif->major))
+					continue;
 				rq = blk_dev[hwif->major].current_request;
 				if (rq != NULL && rq->rq_status != RQ_INACTIVE)
 					goto got_rq;
diff -u --recursive --new-file v1.3.77/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v1.3.77/linux/drivers/block/ll_rw_blk.c	Tue Mar  5 10:10:52 1996
+++ linux/drivers/block/ll_rw_blk.c	Sun Mar 24 20:07:00 1996
@@ -76,40 +76,30 @@
 int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
 
 /*
- * "plug" the device if there are no outstanding requests: this will
- * force the transfer to start only after we have put all the requests
- * on the list.
+ * remove the plug and let it rip..
  */
-static inline void plug_device(struct blk_dev_struct * dev, struct request * plug)
+static void unplug_device(void * data)
 {
+	struct blk_dev_struct * dev = (struct blk_dev_struct *) data;
 	unsigned long flags;
 
-	plug->rq_status = RQ_INACTIVE;
-	plug->cmd = -1;
-	plug->next = NULL;
 	save_flags(flags);
 	cli();
-	if (!dev->current_request)
-		dev->current_request = plug;
+	if (dev->current_request)
+		(dev->request_fn)();
 	restore_flags(flags);
 }
 
 /*
- * remove the plug and let it rip..
+ * "plug" the device if there are no outstanding requests: this will
+ * force the transfer to start only after we have put all the requests
+ * on the list.
  */
-static inline void unplug_device(struct blk_dev_struct * dev)
+static inline void plug_device(struct blk_dev_struct * dev)
 {
-	struct request * req;
-	unsigned long flags;
-
-	save_flags(flags);
-	cli();
-	req = dev->current_request;
-	if (req && req->rq_status == RQ_INACTIVE && req->cmd == -1) {
-		dev->current_request = req->next;
-		(dev->request_fn)();
+	if (!dev->current_request && !IS_PLUGGED(dev)) {
+		queue_task_irq_off(&dev->plug_tq, &tq_scheduler);
 	}
-	restore_flags(flags);
 }
 
 /*
@@ -154,7 +144,6 @@
 
 	add_wait_queue(&wait_for_request, &wait);
 	for (;;) {
-		unplug_device(MAJOR(dev)+blk_dev);
 		current->state = TASK_UNINTERRUPTIBLE;
 		cli();
 		req = get_request(n, dev);
@@ -261,7 +250,8 @@
 	if (!(tmp = dev->current_request)) {
 		dev->current_request = req;
 		up (&request_lock);
-		(dev->request_fn)();
+		if (!IS_PLUGGED(dev))
+			(dev->request_fn)();
 		sti();
 		return;
 	}
@@ -276,7 +266,7 @@
 
 	up (&request_lock);
 /* for SCSI devices, call request_fn unconditionally */
-	if (scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
+	if (!IS_PLUGGED(dev) && scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
 		(dev->request_fn)();
 
 	sti();
@@ -340,8 +330,8 @@
 	}
 
 /* look for a free request. */
-	cli();
 	down (&request_lock);
+	cli();
 
 /* The scsi disk and cdrom drivers completely remove the request
  * from the queue when they start processing an entry.  For this reason
@@ -479,7 +469,6 @@
 void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
 {
 	unsigned int major;
-	struct request plug;
 	int correct_size;
 	struct blk_dev_struct * dev;
 	int i;
@@ -531,8 +520,7 @@
 	   from starting until we have shoved all of the blocks into the
 	   queue, and then we let it rip.  */
 
-	if (nr > 1)
-		plug_device(dev, &plug);
+	plug_device(dev);
 	for (i = 0; i < nr; i++) {
 		if (bh[i]) {
 			set_bit(BH_Req, &bh[i]->b_state);
@@ -543,7 +531,6 @@
 			make_request(major, rw, bh[i]);
 		}
 	}
-	unplug_device(dev);
 	return;
 
       sorry:
@@ -622,6 +609,8 @@
 	for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
 		dev->request_fn      = NULL;
 		dev->current_request = NULL;
+		dev->plug_tq.routine = &unplug_device;
+		dev->plug_tq.data    = dev;
 	}
 
 	req = all_requests + NR_REQUEST;
diff -u --recursive --new-file v1.3.77/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v1.3.77/linux/drivers/block/loop.c	Wed Mar 13 10:09:15 1996
+++ linux/drivers/block/loop.c	Sun Mar 24 20:07:00 1996
@@ -181,7 +181,10 @@
 		offset -= blksize;
 	}
 	len = CURRENT->current_nr_sectors << 9;
-	if ((CURRENT->cmd != WRITE) && (CURRENT->cmd != READ)) {
+	if (CURRENT->cmd == WRITE) {
+		if (lo->lo_flags & LO_FLAGS_READ_ONLY)
+			goto error_out;
+	} else if (CURRENT->cmd != READ) {
 		printk("unknown loop device command (%d)?!?", CURRENT->cmd);
 		goto error_out;
 	}
@@ -235,11 +238,11 @@
 	goto repeat;
 }
 
-static int loop_set_fd(struct loop_device *lo, unsigned int arg)
+static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
 {
 	struct file	*file;
 	struct inode	*inode;
-	
+
 	if (arg >= NR_OPEN || !(file = current->files->fd[arg]))
 		return -EBADF;
 	if (lo->lo_inode)
@@ -261,7 +264,14 @@
 	} else
 		return -EINVAL;
 
-	invalidate_inode_pages (inode);
+	if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) {
+		lo->lo_flags |= LO_FLAGS_READ_ONLY;
+		set_device_ro(dev, 1);
+	} else {
+		invalidate_inode_pages (inode);
+		set_device_ro(dev, 0);
+	}
+
 	lo->lo_inode = inode;
 	lo->lo_inode->i_count++;
 	lo->transfer = NULL;
@@ -274,7 +284,7 @@
 {
 	if (!lo->lo_inode)
 		return -ENXIO;
-	if (lo->lo_refcnt > 1)
+	if (lo->lo_refcnt > 1)	/* we needed one fd for the ioctl */
 		return -EBUSY;
 	if (S_ISBLK(lo->lo_inode->i_mode))
 		blkdev_release (lo->lo_inode);
@@ -378,7 +388,7 @@
 	lo = &loop_dev[dev];
 	switch (cmd) {
 	case LOOP_SET_FD:
-		return loop_set_fd(lo, arg);
+		return loop_set_fd(lo, inode->i_rdev, arg);
 	case LOOP_CLR_FD:
 		return loop_clr_fd(lo, inode->i_rdev);
 	case LOOP_SET_STATUS:
@@ -442,8 +452,6 @@
 		lo->lo_refcnt--;
 		MOD_DEC_USE_COUNT;
 	}
-
-	return;
 }
 
 static struct file_operations lo_fops = {
diff -u --recursive --new-file v1.3.77/linux/drivers/block/md.c linux/drivers/block/md.c
--- v1.3.77/linux/drivers/block/md.c	Tue Mar  5 10:10:52 1996
+++ linux/drivers/block/md.c	Sun Mar 24 20:07:00 1996
@@ -7,6 +7,8 @@
 
    A lot of inspiration came from hd.c ...
 
+   kerneld support by Boris Tobotras <boris@xtalk.msk.su>
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
@@ -29,6 +31,9 @@
 #include <linux/proc_fs.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
 #include <errno.h>
 
 #define MAJOR_NR MD_MAJOR
@@ -92,14 +97,14 @@
 /* Picked up from genhd.c */
 char *partition_name (kdev_t dev)
 {
-  static char name[10];		/* This should be long
+  static char name[40];		/* This should be long
 				   enough for a device name ! */
-  struct gendisk *hd=find_gendisk (dev);
+  struct gendisk *hd = find_gendisk (dev);
 
   if (!hd)
   {
-    printk ("No gendisk entry for dev %04x\n", dev);
-    sprintf (name, "dev %04x", dev);
+    printk ("No gendisk entry for dev %s\n", kdevname(dev));
+    sprintf (name, "dev %s", kdevname(dev));
     return (name);
   }
 
@@ -197,10 +202,20 @@
     md_dev[minor].repartition=(int) arg;
     
     if ((index=PERSONALITY(md_dev+minor) >> (PERSONALITY_SHIFT))
-	>= MAX_PERSONALITY ||
-	!pers[index])
+	>= MAX_PERSONALITY)
       return -EINVAL;
 
+    if (!pers[index])
+    {
+#ifdef CONFIG_KERNELD
+      char module_name[80];
+      sprintf (module_name, "md-personality-%d", index);
+      request_module (module_name);
+      if (!pers[index])
+#endif
+	return -EINVAL;
+    }
+
     md_dev[minor].pers=pers[index];
 
     if ((err=md_dev[minor].pers->run (minor, md_dev+minor)))
@@ -404,7 +419,7 @@
     minor = MINOR(req->rq_dev);
     if ((MAJOR(req->rq_dev) != MD_MAJOR) || (minor >= MAX_REAL))
     {
-      printk("md: bad device number: 0x%04x\n", req->rq_dev);
+      printk("md: bad device: %s\n", kdevname(req->rq_dev));
       end_request(0, req);
       continue;
     }
@@ -437,16 +452,17 @@
   kdev_t dev;
   struct buffer_head *bh;
   struct request *req;
+  long flags;
   
   down (&request_lock);
+  save_flags (flags);
+  cli();
 
   for (i=0; i<n; i++)
   {
     if (!pending[i].bh)
       continue;
 
-    cli();
-
     found=0;
     rw=pending[i].cmd;
     bh=pending[i].bh;
@@ -470,7 +486,7 @@
 
       while (req && !found)
       {
-	if (req->rq_status!=RQ_INACTIVE && req->rq_status!=RQ_ACTIVE)
+	if (req->rq_status!=RQ_ACTIVE)
 	  printk ("Saw bad status request !\n");
 
 	if (req->rq_dev == dev &&
@@ -494,7 +510,7 @@
 	    (req->nr_sectors + pending[i].nr_sectors) < 245)
 	{
 	  req->nr_sectors += pending[i].nr_sectors;
-	  bh->b_reqnext = req->bh;
+	  pending[i].bhtail->b_reqnext = req->bh;
 	  req->buffer = bh->b_data;
 	  req->current_nr_sectors = bh->b_size >> 9;
 	  req->sector = pending[i].sector;
@@ -511,6 +527,7 @@
       continue;
 
     up (&request_lock);
+    sti ();
     req=get_md_request (max_req, dev);
     
     /* Build it up... */
@@ -530,9 +547,11 @@
 
     add_request (blk_dev + MAJOR(dev), req);
     down (&request_lock);
+    cli ();
   }
 
   up (&request_lock);
+  restore_flags (flags);
   for (j=0; j<n; j++)
   {
     if (!pending[j].bh)
@@ -540,8 +559,6 @@
     
     pending[j].bh=NULL;
   }
-
-  sti ();
 }
 
 
@@ -656,7 +673,7 @@
     sz+=sprintf (page+sz, "\n");
     sz+=md_dev[i].pers->status (page+sz, i, md_dev+i);
   }
-  
+
   return (sz);
 }
 
diff -u --recursive --new-file v1.3.77/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v1.3.77/linux/drivers/cdrom/cdu31a.c	Thu Mar 21 20:36:51 1996
+++ linux/drivers/cdrom/cdu31a.c	Sun Mar 24 18:57:04 1996
@@ -1525,7 +1525,7 @@
        * The beginning here is stolen from the hard disk driver.  I hope
        * it's right.
        */
-      if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE)
+      if (!(CURRENT) || CURRENT_PLUGGED || CURRENT->rq_status == RQ_INACTIVE)
       {
          goto end_do_cdu31a_request;
       }
diff -u --recursive --new-file v1.3.77/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- v1.3.77/linux/drivers/cdrom/mcdx.c	Sun Mar 17 09:04:05 1996
+++ linux/drivers/cdrom/mcdx.c	Fri Mar 22 09:42:18 1996
@@ -1,7 +1,7 @@
 /*
  * The Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.8
+ * VERSION: 1.9
  *
  ****************** H E L P *********************************
  * If you ever plan to update your CD ROM drive and perhaps
@@ -44,7 +44,7 @@
 
 #if RCS
 static const char *mcdx_c_version
-		= "$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $";
+		= "mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp";
 #endif
 
 #include <linux/version.h>
@@ -850,7 +850,7 @@
 	I wanna make this independend of cpu speed. [1 jiffie is 1/HZ] sec */
 {
     unsigned long tout = jiffies + jifs;
-	if (jifs < 0) printk ("********\n");
+    if (jifs < 0) return;
 
     /* TRACE((INIT, "mcdx_delay %d\n", jifs)); */
 
@@ -1102,12 +1102,12 @@
 	int drive;
 
 #ifdef MODULE
-	WARN(("Version 1.8 for %s\n", kernel_version));
+	WARN(("Version 1.9 for %s\n", kernel_version));
 #else
-	WARN(("Version 1.8\n"));
+	WARN(("Version 1.9\n"));
 #endif
 
-	WARN(("$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $\n"));
+	WARN(("mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp\n"));
 
 	/* zero the pointer array */
 	for (drive = 0; drive < MCDX_NDRIVES; drive++)
diff -u --recursive --new-file v1.3.77/linux/drivers/cdrom/optcd_isp16.h linux/drivers/cdrom/optcd_isp16.h
--- v1.3.77/linux/drivers/cdrom/optcd_isp16.h	Tue Jan 23 21:15:39 1996
+++ linux/drivers/cdrom/optcd_isp16.h	Thu Jan  1 02:00:00 1970
@@ -1,337 +0,0 @@
-/* linux/drivers/cdrom/optcd_isp16.h - ISP16 CDROM interface configuration
-   $Id: optcd_isp16.h,v 1.3 1996/01/15 18:43:11 root Exp root $
-
-   Extracts from linux/drivers/cdrom/sjcd.c
-   For copyrights see linux/drivers/cdrom/optcd.c
-*/
-
-
-/* Some (Media)Magic */
-/* define types of drive the interface on an ISP16 card may be looking at */
-#define ISP16_DRIVE_X 0x00
-#define ISP16_SONY  0x02
-#define ISP16_PANASONIC0 0x02
-#define ISP16_SANYO0 0x02
-#define ISP16_MITSUMI  0x04
-#define ISP16_PANASONIC1 0x06
-#define ISP16_SANYO1 0x06
-#define ISP16_DRIVE_NOT_USED 0x08  /* not used */
-#define ISP16_DRIVE_SET_MASK 0xF1  /* don't change 0-bit or 4-7-bits*/
-/* ...for port */
-#define ISP16_DRIVE_SET_PORT 0xF8D
-/* set io parameters */
-#define ISP16_BASE_340  0x00
-#define ISP16_BASE_330  0x40
-#define ISP16_BASE_360  0x80
-#define ISP16_BASE_320  0xC0
-#define ISP16_IRQ_X  0x00
-#define ISP16_IRQ_5  0x04  /* shouldn't be used due to soundcard conflicts */
-#define ISP16_IRQ_7  0x08  /* shouldn't be used due to soundcard conflicts */
-#define ISP16_IRQ_3  0x0C
-#define ISP16_IRQ_9  0x10
-#define ISP16_IRQ_10  0x14
-#define ISP16_IRQ_11  0x18
-#define ISP16_DMA_X  0x03
-#define ISP16_DMA_3  0x00
-#define ISP16_DMA_5  0x00
-#define ISP16_DMA_6  0x01
-#define ISP16_DMA_7  0x02
-#define ISP16_IO_SET_MASK  0x20  /* don't change 5-bit */
-/* ...for port */
-#define ISP16_IO_SET_PORT  0xF8E
-/* enable the card */
-#define ISP16_C928__ENABLE_PORT  0xF90  /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__ENABLE_PORT  0xF91  /* ISP16 with OPTi 82C929 chip */
-#define ISP16_ENABLE_CDROM  0x80  /* seven bit */
-
-/* the magic stuff */
-#define ISP16_CTRL_PORT  0xF8F
-#define ISP16_C928__CTRL  0xE2  /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__CTRL  0xE3  /* ISP16 with OPTi 82C929 chip */
-
-static short isp16_detect(void);
-static short isp16_c928__detect(void);
-static short isp16_c929__detect(void);
-static short isp16_cdi_config( int base, u_char drive_type, int irq, int dma );
-static void isp16_sound_config( void );
-static short isp16_type; /* dependent on type of interface card */
-static u_char isp16_ctrl;
-static u_short isp16_enable_port;
-
-/*static int sjcd_present = 0;*/
-static u_char special_mask = 0;
-
-static unsigned char defaults[ 16 ] = {
-  0xA8, 0xA8, 0x18, 0x18, 0x18, 0x18, 0x8E, 0x8E,
-  0x03, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00
-};
-/* ------------- */
-/*
- * -- ISP16 detection and configuration
- *
- *    Copyright (c) 1995, Eric van der Maarel <maarel@marin.nl>
- *
- *    Version 0.5
- *
- *    Detect cdrom interface on ISP16 soundcard.
- *    Configure cdrom interface.
- *    Configure sound interface.
- *
- *    Algorithm for the card with OPTi 82C928 taken
- *    from the CDSETUP.SYS driver for MSDOS,
- *    by OPTi Computers, version 2.03.
- *    Algorithm for the card with OPTi 82C929 as communicated
- *    to me by Vadim Model and Leo Spiekman.
- *
- *    Use, modifification or redistribution of this software is
- *    allowed under the terms of the GPL.
- *
- */
-
-
-#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
-#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
-
-static short
-isp16_detect(void)
-{
-
-  if ( !( isp16_c929__detect() < 0 ) )
-    return(2);
-  else
-    return( isp16_c928__detect() );
-}
-
-static short
-isp16_c928__detect(void)
-{
-  u_char ctrl;
-  u_char enable_cdrom;
-  u_char io;
-  short i = -1;
-
-  isp16_ctrl = ISP16_C928__CTRL;
-  isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
-  /* read' and write' are a special read and write, respectively */
-
-  /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
-  /* read' 3,4 and 5-bit from the cdrom enable port */
-  enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38;
-
-  if ( !(enable_cdrom & 0x20) ) {  /* 5-bit not set */
-    /* read' last 2 bits of ISP16_IO_SET_PORT */
-    io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
-    if ( ((io&0x01)<<1) == (io&0x02) ) {  /* bits are the same */
-      if ( io == 0 ) {  /* ...the same and 0 */
-        i = 0;
-        enable_cdrom |= 0x20;
-      }
-      else {  /* ...the same and 1 */  /* my card, first time 'round */
-        i = 1;
-        enable_cdrom |= 0x28;
-      }
-      ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom );
-    }
-    else {  /* bits are not the same */
-      ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-      return(i); /* -> not detected: possibly incorrect conclusion */
-    }
-  }
-  else if ( enable_cdrom == 0x20 )
-    i = 0;
-  else if ( enable_cdrom == 0x28 )  /* my card, already initialised */
-    i = 1;
-
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
-  return(i);
-}
-
-static short
-isp16_c929__detect(void)
-{
-  u_char ctrl;
-  u_char tmp;
-
-  isp16_ctrl = ISP16_C929__CTRL;
-  isp16_enable_port = ISP16_C929__ENABLE_PORT;
-
-  /* read' and write' are a special read and write, respectively */
-
-  /* read' ISP16_CTRL_PORT and save */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT );
-
-  /* write' zero to the ctrl port and get response */
-  ISP16_OUT( ISP16_CTRL_PORT, 0 );
-  tmp = ISP16_IN( ISP16_CTRL_PORT );
-
-  if ( tmp != 2 )  /* isp16 with 82C929 not detected */
-    return(-1);
-
-  /* restore ctrl port value */
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-  
-  return(2);
-}
-
-static short
-isp16_cdi_config( int base, u_char drive_type, int irq, int dma )
-{
-  u_char base_code;
-  u_char irq_code;
-  u_char dma_code;
-  u_char i;
-
-  if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
-    printk( "Mitsumi cdrom drive has no dma support.\n" );
-
-  switch (base) {
-  case 0x340: base_code = ISP16_BASE_340; break;
-  case 0x330: base_code = ISP16_BASE_330; break;
-  case 0x360: base_code = ISP16_BASE_360; break;
-  case 0x320: base_code = ISP16_BASE_320; break;
-  default:
-    printk( "Base address 0x%03X not supported by cdrom interface on ISP16.\n", base );
-    return(-1);
-  }
-  switch (irq) {
-  case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
-  case 5: irq_code = ISP16_IRQ_5;
-          printk( "Irq 5 shouldn't be used by cdrom interface on ISP16,"
-            " due to possible conflicts with the soundcard.\n");
-          break;
-  case 7: irq_code = ISP16_IRQ_7;
-          printk( "Irq 7 shouldn't be used by cdrom interface on ISP16,"
-            " due to possible conflicts with the soundcard.\n");
-          break;
-  case 3: irq_code = ISP16_IRQ_3; break;
-  case 9: irq_code = ISP16_IRQ_9; break;
-  case 10: irq_code = ISP16_IRQ_10; break;
-  case 11: irq_code = ISP16_IRQ_11; break;
-  default:
-    printk( "Irq %d not supported by cdrom interface on ISP16.\n", irq );
-    return(-1);
-  }
-  switch (dma) {
-  case 0: dma_code = ISP16_DMA_X; break;  /* disable dma */
-  case 1: printk( "Dma 1 cannot be used by cdrom interface on ISP16,"
-            " due to conflict with the soundcard.\n");
-          return(-1); break;
-  case 3: dma_code = ISP16_DMA_3; break;
-  case 5: dma_code = ISP16_DMA_5; break;
-  case 6: dma_code = ISP16_DMA_6; break;
-  case 7: dma_code = ISP16_DMA_7; break;
-  default:
-    printk( "Dma %d not supported by cdrom interface on ISP16.\n", dma );
-    return(-1);
-  }
-
-  if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
-    drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
-    drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
-    drive_type != ISP16_DRIVE_X ) {
-    printk( "Drive type (code 0x%02X) not supported by cdrom"
-     " interface on ISP16.\n", drive_type );
-    return(-1);
-  }
-
-  /* set type of interface */
-  i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;  /* clear some bits */
-  ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
-
-  /* enable cdrom on interface with 82C929 chip */
-  if ( isp16_type > 1 )
-    ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM );
-
-  /* set base address, irq and dma */
-  i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;  /* keep some bits */
-  ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
-
-  return(0);
-}
-
-static void isp16_sound_config( void )
-{
-  int i;
-  u_char saved;
-
-  saved = ISP16_IN( 0xF8D ) & 0x8F;
-    
-  ISP16_OUT( 0xF8D, 0x40 );
-
-  /*
-   * Now we should wait for a while...
-   */
-  for( i = 16*1024; i--; );
-  
-  ISP16_OUT( 0xF8D, saved );
-
-  ISP16_OUT( 0xF91, 0x1B );
-
-  for( i = 5*64*1024; i != 0; i-- )
-    if( !( inb( 0x534 ) & 0x80 ) ) break;
-
-  if( i > 0 ) {
-    saved = ( inb( 0x534 ) & 0xE0 ) | 0x0A;
-    outb( saved, 0x534 );
-
-    special_mask = ( inb( 0x535 ) >> 4 ) & 0x08;
-
-    saved = ( inb( 0x534 ) & 0xE0 ) | 0x0C;
-    outb( saved, 0x534 );
-
-    switch( inb( 0x535 ) ) {
-      case 0x09:
-      case 0x0A:
-        special_mask |= 0x05;
-        break;
-      case 0x8A:
-        special_mask = 0x0F;
-        break;
-      default:
-        i = 0;
-    }
-  }
-  if ( i == 0 ) {
-    printk( "Strange MediaMagic, but\n" );
-  }
-  else {
-    printk( "Conf:" );
-    saved = inb( 0x534 ) & 0xE0;
-    for( i = 0; i < 16; i++ ) {
-      outb( 0x20 | ( u_char )i, 0x534 );
-      outb( defaults[i], 0x535 );
-    }
-    for ( i = 0; i < 16; i++ ) {
-      outb( 0x20 | ( u_char )i, 0x534 );
-      saved = inb( 0x535 );
-      printk( " %02X", saved );
-    }
-    printk( "\n" );
-  }
-
-  ISP16_OUT( 0xF91, 0xA0 | special_mask );
-
-  /*
-   * The following have no explaination yet.
-   */
-  ISP16_OUT( 0xF90, 0xA2 );
-  ISP16_OUT( 0xF92, 0x03 );
-
-  /*
-   * Turn general sound on and set total volume.
-   */
-  ISP16_OUT( 0xF93, 0x0A );
-
-/*
-  outb( 0x04, 0x224 );
-  saved = inb( 0x225 );
-  outb( 0x04, 0x224 );
-  outb( saved, 0x225 );
-*/
-
-}
diff -u --recursive --new-file v1.3.77/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v1.3.77/linux/drivers/char/cyclades.c	Sun Mar 10 09:49:47 1996
+++ linux/drivers/char/cyclades.c	Sun Mar 24 12:09:36 1996
@@ -2376,7 +2376,7 @@
     if (info->flags & ASYNC_CALLOUT_ACTIVE)
 	info->callout_termios = *tty->termios;
     if (info->flags & ASYNC_INITIALIZED)
-	tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
+	tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
     shutdown(info);
     if (tty->driver.flush_buffer)
 	tty->driver.flush_buffer(tty);
diff -u --recursive --new-file v1.3.77/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v1.3.77/linux/drivers/char/lp.c	Thu Mar 21 20:36:52 1996
+++ linux/drivers/char/lp.c	Sun Mar 24 20:07:00 1996
@@ -602,7 +602,9 @@
 {
 	int offset = 0;
 	int count = 0;
+#ifdef MODULE
 	int failed = 0;
+#endif
 
 	if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) {
 		printk("lp: unable to get major %d\n", LP_MAJOR);
diff -u --recursive --new-file v1.3.77/linux/drivers/char/pty.c linux/drivers/char/pty.c
--- v1.3.77/linux/drivers/char/pty.c	Thu Nov  9 11:23:48 1995
+++ linux/drivers/char/pty.c	Sat Mar 23 18:04:50 1996
@@ -195,9 +195,13 @@
 	tty->driver_data = pty;
 
 	if (!tmp_buf) {
-		tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
-		if (!tmp_buf)
-			return -ENOMEM;
+		unsigned long page = get_free_page(GFP_KERNEL);
+		if (!tmp_buf) {
+			if (!page)
+				return -ENOMEM;
+			tmp_buf = (unsigned char *) page;
+		} else
+			free_page(page);
 	}
 
 	if (tty->driver.subtype == PTY_TYPE_SLAVE)
diff -u --recursive --new-file v1.3.77/linux/drivers/char/tga.c linux/drivers/char/tga.c
--- v1.3.77/linux/drivers/char/tga.c	Tue Jan 23 21:15:40 1996
+++ linux/drivers/char/tga.c	Sun Mar 24 12:09:36 1996
@@ -328,7 +328,6 @@
 {
 	memcpyw((unsigned short *)vc_scrbuf[currcons],
 		(unsigned short *)origin, video_screen_size);
-	__scrollback_mode = 0 ;
 	origin = video_mem_start = (unsigned long)vc_scrbuf[currcons];
 	scr_end = video_mem_end = video_mem_start + video_screen_size;
 	pos = origin + y*video_size_row + (x<<1);
diff -u --recursive --new-file v1.3.77/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v1.3.77/linux/drivers/net/Config.in	Fri Mar 15 16:03:14 1996
+++ linux/drivers/net/Config.in	Mon Mar 25 08:58:20 1996
@@ -14,6 +14,14 @@
 tristate 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC
 tristate 'PLIP (parallel port) support' CONFIG_PLIP
 tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
+
+tristate 'FRAD (Frame Relay Access Device) support' CONFIG_FRAD
+if [ "$CONFIG_FRAD" = "y" -o "$CONFIG_FRAD" = "m" ]; then
+  int '  Max open DLCI' CONFIG_DLCI_COUNT 24
+  int '  Max DLCI per device' CONFIG_DLCI_MAX 8
+  tristate '  Sangoma S502A FRAD support' CONFIG_SDLA
+fi
+
 bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA
 bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
 if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
diff -u --recursive --new-file v1.3.77/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v1.3.77/linux/drivers/net/Makefile	Sun Mar 17 09:04:06 1996
+++ linux/drivers/net/Makefile	Mon Mar 25 08:58:20 1996
@@ -419,6 +419,22 @@
   endif
 endif
 
+ifeq ($(CONFIG_SDLA),y)
+L_OBJS += sdla.o
+else
+  ifeq ($(CONFIG_SDLA),m)
+  M_OBJS += sdla.o
+  endif
+endif
+
+ifeq ($(CONFIG_FRAD),y)
+L_OBJS += dlci.o 
+else
+  ifeq ($(CONFIG_FRAD),m)
+  M_OBJS += dlci.o
+  endif
+endif
+
 include $(TOPDIR)/Rules.make
 
 clean:
@@ -475,3 +491,8 @@
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(LANCE_OPTS) -c $<
 
 8390.o: 8390.c 8390.h CONFIG
+
+sdla.o: sdla.c CONFIG 
+
+dlci.o: dlci.c CONFIG
+
diff -u --recursive --new-file v1.3.77/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v1.3.77/linux/drivers/net/Space.c	Fri Mar 15 16:03:14 1996
+++ linux/drivers/net/Space.c	Mon Mar 25 08:58:20 1996
@@ -188,6 +188,22 @@
     return 0;
 }
 
+#ifdef CONFIG_SDLA
+    extern int sdla_init(struct device *);
+    static struct device sdla0_dev = { "sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, };
+
+#   undef NEXT_DEV
+#   define NEXT_DEV	(&sdla0_dev)
+#endif
+
+/* This must be AFTER the various FRADs so it initializes FIRST! */
+	
+#ifdef CONFIG_FRAD
+    extern int dlci_init(struct device *);
+    static struct device dlci_dev = { "dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, dlci_init, };
+#   undef NEXT_DEV
+#   define NEXT_DEV	(&dlci_dev)
+#endif
 
 #ifdef CONFIG_NETROM
 	extern int nr_init(struct device *);
@@ -366,7 +382,7 @@
 
 #endif 
 #endif
-	
+
 extern int loopback_init(struct device *dev);
 struct device loopback_dev = {
 	"lo",			/* Software Loopback interface		*/
diff -u --recursive --new-file v1.3.77/linux/drivers/net/bsd_comp.c linux/drivers/net/bsd_comp.c
--- v1.3.77/linux/drivers/net/bsd_comp.c	Thu Nov  9 11:23:49 1995
+++ linux/drivers/net/bsd_comp.c	Sun Mar 24 12:09:36 1996
@@ -78,7 +78,7 @@
 #include <asm/bitops.h>
 #include <asm/segment.h>
 
-#include <net/if.h>
+#include <linux/if.h>
 
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
@@ -92,9 +92,9 @@
 #include <linux/netprotocol.h>
 #endif
 
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <net/if_arp.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/if_arp.h>
 
 #undef   PACKETPTR
 #define  PACKETPTR 1
diff -u --recursive --new-file v1.3.77/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v1.3.77/linux/drivers/net/de4x5.c	Sun Mar 10 09:49:50 1996
+++ linux/drivers/net/de4x5.c	Thu Mar 21 20:38:37 1996
@@ -176,11 +176,17 @@
 			    Changed driver to autprobe as a module. No irq
 			    checking is done now - assume BIOS is good!
 			  Added SMC9332 detection <manabe@Roy.dsl.tutics.ac.jp>
+      0.41    21-Mar-96   Don't check for get_hw_addr checksum unless DEC card
+                          only <niles@axp745gsfc.nasa.gov>
+			  Fix for multiple PCI cards reported by <jos@xos.nl>
+			  Duh, put the SA_SHIRQ flag into request_interrupt().
+			  Fix SMC ethernet address in enet_det[].
+			  Print chip name instead of "UNKNOWN" during boot.
 
     =========================================================================
 */
 
-static const char *version = "de4x5.c:v0.40 96/3/5 davies@wanton.lkg.dec.com\n";
+static const char *version = "de4x5.c:v0.41 96/3/21 davies@wanton.lkg.dec.com\n";
 
 #include <linux/module.h>
 
@@ -255,7 +261,7 @@
 ** Define special SROM detection cases
 */
 static c_char enet_det[][ETH_ALEN] = {
-    {0x00, 0x00, 0x0c, 0x00, 0x00, 0x00}
+    {0x00, 0x00, 0xc0, 0x00, 0x00, 0x00}
 };
 
 #define SMC 1
@@ -897,7 +903,8 @@
     
     de4x5_dbg_open(dev);
     
-    if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name, dev)) {
+    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 {
@@ -1577,7 +1584,7 @@
     u_int iobase;
     struct bus_type *lp = &bus;
     
-    if (!ioaddr && autoprobed) return;       /* Been here before ! */
+    if ((!ioaddr || !loading_module) && autoprobed) return;
     
     if (!pcibios_present()) return;          /* No PCI bus in this machine! */
     
@@ -2811,8 +2818,11 @@
     if (i == siglen) {
 	if (dec_only) {
 	    *name = '\0';
-	} else {
-	    strcpy(name, "UNKNOWN");
+	} else {                        /* Use chip name to avoid confusion */
+	    strcpy(name, (((lp->chipset == DC21040) ? "DC21040" :
+			   ((lp->chipset == DC21041) ? "DC21041" :
+			    ((lp->chipset == DC21140) ? "DC21140" : "UNKNOWN"
+			     )))));
 	}
     }
     
@@ -2885,12 +2895,12 @@
 	    chksum = (u_char) tmp;
 	    while ((tmp = inl(DE4X5_APROM)) < 0);
 	    chksum |= (u_short) (tmp << 8);
-	    if (k != chksum) status = -1;
+	    if ((k != chksum) && (dec_only)) status = -1;
 	}
     } else {
 	chksum = (u_char) inb(EISA_APROM);
 	chksum |= (u_short) (inb(EISA_APROM) << 8);
-	if (k != chksum) status = -1;
+	if ((k != chksum) && (dec_only)) status = -1;
     }
     
     return status;
diff -u --recursive --new-file v1.3.77/linux/drivers/net/dlci.c linux/drivers/net/dlci.c
--- v1.3.77/linux/drivers/net/dlci.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/dlci.c	Mon Mar 25 10:06:39 1996
@@ -0,0 +1,609 @@
+/*
+ * DLCI		Implementation of Frame Relay protocol for Linux, according to
+ *		RFC 1490.  This generic device provides en/decapsulation for an
+ *		underlying hardware driver.  Routes & IPs are assigned to these
+ *		interfaces.  Requires 'dlcicfg' program to create usable 
+ *		interfaces, the initial one, 'dlci' is for IOCTL use only.
+ *
+ * Version:	@(#)dlci.c	0.10	23 Mar 1996
+ *
+ * Author:	Mike McLagan <mike.mclagan@linux.org>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#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 <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/if_frad.h>
+
+#include <net/sock.h>
+
+static const char *devname = "dlci";
+static const char *version = "DLCI driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
+
+static struct device *open_dev[CONFIG_DLCI_COUNT];
+
+static char *basename[16];
+
+int dlci_init(struct device *dev);
+
+/* allow FRAD's to register their name as a valid FRAD */
+int register_frad(const char *name)
+{
+   int i;
+
+   if (!name)
+      return(-EINVAL);
+
+   for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+   {
+      if (!basename[i])
+         break;
+
+      /* take care of multiple registrations */
+      if (strcmp(basename[i], name) == 0)
+         return(0);
+   }
+
+   if (i == sizeof(basename) / sizeof(char *))
+      return(-ENOMEM);
+
+   basename[i] = (char *) name;
+
+   return(0);
+}
+
+int unregister_frad(const char *name)
+{
+   int i;
+
+   if (!name)
+      return(-EINVAL);
+
+   for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+      if (basename[i] && (strcmp(basename[i], name) == 0))
+         break;
+
+   if (i == sizeof(basename) / sizeof(char *))
+      return(-EINVAL);
+
+   basename[i] = NULL;
+
+   return(0);
+}
+
+/* 
+   these encapsulate the RFC 1490 requirements as well as 
+   deal with packet transmission and reception, working with
+   the upper network layers 
+ */
+
+static int dlci_header(struct sk_buff *skb, struct device *dev, 
+                           unsigned short type, void *daddr, void *saddr, 
+                           unsigned len)
+{
+   struct fradhdr    hdr;
+   struct dlci_local *dlp;
+   unsigned          hlen;
+   char              *dest;
+
+   dlp = dev->priv;
+
+   hdr.control = FRAD_I_UI;
+   switch(type)
+   {
+      case ETH_P_IP:
+         hdr.pad = FRAD_P_IP;
+         hlen = sizeof(hdr.control) + sizeof(hdr.pad);
+         break;
+
+      /* feel free to add other types, if necessary */
+
+      default:
+         hdr.pad = FRAD_P_PADDING;
+         hdr.NLPID = FRAD_P_SNAP;
+         memset(hdr.OUI, 0, sizeof(hdr.OUI));
+         hdr.PID = type;
+         hlen = sizeof(hdr);
+         break;
+   }
+
+   dest = skb_push(skb, hlen);
+   if (!dest)
+      return(0);
+
+   memcpy(dest, &hdr, hlen);
+
+   return(hlen);
+}
+
+static void dlci_receive(struct sk_buff *skb, struct device *dev)
+{
+   struct dlci_local *dlp;
+   struct fradhdr    *hdr;
+   int               process, header;
+
+   dlp = dev->priv;
+   hdr = (struct fradhdr *) skb->data;
+   process = 0;
+   header = 0;
+   skb->dev = dev;
+
+   if (hdr->control != FRAD_I_UI)
+   {
+      printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control);
+      dlp->stats.rx_errors++;
+   }
+   else
+      switch(hdr->pad)
+      {
+         case FRAD_P_PADDING:
+            if (hdr->NLPID != FRAD_P_SNAP)
+            {
+               printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID);
+               dlp->stats.rx_errors++;
+               break;
+            }
+    
+            if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0)
+            {
+               printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]);
+               dlp->stats.rx_errors++;
+               break;
+            }
+
+            /* at this point, it's an EtherType frame */
+            header = sizeof(struct fradhdr);
+            skb->protocol = htons(hdr->PID);
+            process = 1;
+            break;
+
+         case FRAD_P_IP:
+            header = sizeof(hdr->control) + sizeof(hdr->pad);
+            skb->protocol = htons(ETH_P_IP);
+            process = 1;
+            break;
+
+         case FRAD_P_SNAP:
+         case FRAD_P_Q933:
+         case FRAD_P_CLNP:
+            printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad);
+            dlp->stats.rx_errors++;
+            break;
+
+         default:
+            printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad);
+            dlp->stats.rx_errors++;
+            break;            
+      }
+
+   if (process)
+   {
+      /* we've set up the protocol, so discard the header */
+      skb->mac.raw = skb->data; 
+      skb_pull(skb, header);
+      netif_rx(skb);
+      dlp->stats.rx_packets++;
+   }
+   else
+      dev_kfree_skb(skb, FREE_WRITE);
+}
+
+static int dlci_transmit(struct sk_buff *skb, struct device *dev)
+{
+   struct dlci_local *dlp;
+   int               ret;
+
+   ret = 0;
+
+   if (!skb || !dev)
+      return(0);
+
+   if (dev->tbusy)
+      return(1);
+
+   dlp = dev->priv;
+
+   if (set_bit(0, (void*)&dev->tbusy) != 0)
+      printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
+   else
+   {
+      ret = dlp->slave->hard_start_xmit(skb, dlp->slave); 
+      if (ret)
+         dlp->stats.tx_errors++;
+      else 
+         dlp->stats.tx_packets++;
+
+      /* per Alan Cox, always return 0, let the slave free the packet */
+      ret = 0;
+      dev->tbusy = 0;
+   }
+
+   return(ret);
+}
+
+int dlci_add(struct dlci_add *new)
+{
+   struct device       *master, *slave;
+   struct dlci_local   *dlp;
+   struct frad_local   *flp;
+   struct dlci_add     dlci;
+   int                 err, i;
+   char                buf[10];
+
+   err = verify_area(VERIFY_READ, new, sizeof(*new));
+   if (err)
+      return(err);
+
+   memcpy_fromfs(&dlci, new, sizeof(dlci));
+
+   /* validate slave device */
+   slave = dev_get(dlci.devname);
+   if (!slave)
+      return(-ENODEV);
+
+   if (slave->type != ARPHRD_FRAD)
+      return(-EINVAL);
+
+   /* check for registration */
+   for (i=0;i<sizeof(basename) / sizeof(char *); i++)
+      if ((basename[i]) && 
+          (strncmp(dlci.devname, basename[i], strlen(basename[i])) == 0) && 
+          (strlen(dlci.devname) > strlen(basename[i])))
+         break;
+
+   if (i == sizeof(basename) / sizeof(char *))
+      return(-EINVAL);
+
+   /* check for too many open devices : should this be dynamic ? */
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      if (!open_dev[i])
+         break;
+
+   if (i == CONFIG_DLCI_COUNT)
+      return(-ENOSPC);  /*  #### Alan: Comments on this?? */
+
+   /* create device name */
+   sprintf(buf, "%s%02i", devname, i);
+
+   master = kmalloc(sizeof(*master), GFP_KERNEL);
+   if (!master)
+      return(-ENOMEM);
+
+   memset(master, 0, sizeof(*master));
+   master->name = kmalloc(strlen(buf), GFP_KERNEL);
+
+   if (!master->name)
+   {
+      kfree(master);
+      return(-ENOMEM);
+   }
+
+   strcpy(master->name, buf);
+   master->init = dlci_init;
+   master->flags = 0;
+
+   err = register_netdev(master);
+   if (err < 0)
+   {
+      kfree(master->name);
+      kfree(master);
+      return(err);
+   }
+
+   *(short *)(master->dev_addr) = dlci.dlci;
+
+   dlp = (struct dlci_local *) master->priv;
+   dlp->slave = slave;
+
+   flp = slave->priv;
+   err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
+   if (err < 0)
+   {
+      unregister_netdev(master);
+      kfree(master->priv);
+      kfree(master->name);
+      kfree(master);
+      return(err);
+   }
+
+   memcpy_tofs(new->devname, buf, strlen(buf) + 1);
+   open_dev[i] = master;
+
+   MOD_INC_USE_COUNT;
+
+   return(0);
+}
+
+int dlci_del(struct device *master)
+{
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   struct device     *slave;
+   int               i, err;
+
+   if (master->start)
+      return(-EBUSY);
+
+   dlp = master->priv;
+   slave = dlp->slave;
+   flp = slave->priv;
+
+   err = (*flp->deassoc)(slave, master);
+   if (err)
+      return(err);
+
+   unregister_netdev(master);
+
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      if (master == open_dev[i])
+         break;
+
+   if (i<CONFIG_DLCI_COUNT)
+      open_dev[i] = NULL;
+
+   kfree(master->priv);
+   kfree(master->name);
+   kfree(master);
+
+   MOD_DEC_USE_COUNT;
+
+   return(0);
+}
+
+int dlci_config(struct device *dev, struct dlci_conf *conf, int get)
+{
+   struct dlci_conf  config;
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   int               err;
+
+   dlp = dev->priv;
+
+   flp = dlp->slave->priv;
+
+   if (!get)
+   {
+      memcpy_fromfs(&config, conf, sizeof(struct dlci_conf));
+      if (config.flags & ~DLCI_VALID_FLAGS)
+         return(-EINVAL);
+      memcpy(&dlp->config, &config, sizeof(struct dlci_conf));
+      dlp->configured = 1;
+   }
+
+   err = (*flp->dlci_conf)(dlp->slave, dev, get);
+   if (err)
+      return(err);
+
+   if (get)
+      memcpy_tofs(conf, &dlp->config, sizeof(struct dlci_conf));
+
+   return(0);
+}
+
+int dlci_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+   struct dlci_local *dlp;
+
+   if (!suser())
+      return(-EPERM);
+
+   dlp = dev->priv;
+
+   switch(cmd)
+   {
+      case DLCI_GET_SLAVE:
+         if (!*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         strcpy(ifr->ifr_slave, dlp->slave->name);
+         break;
+
+      case DLCI_DEVADD:
+         /* can only add on the primary device */
+         if (*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         return(dlci_add((struct dlci_add *) ifr->ifr_data));
+         break;
+
+      case DLCI_DEVDEL:
+         /* can't delete the primary device */
+         if (!*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         if (dev->start)
+            return(-EBUSY);
+
+         return(dlci_del(dev));
+         break;
+
+      case DLCI_GET_CONF:
+      case DLCI_SET_CONF:
+         if (!*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         return(dlci_config(dev, (struct dlci_conf *) ifr->ifr_data, cmd == DLCI_GET_CONF));
+         break;
+
+      default: 
+         return(-EOPNOTSUPP);
+   }
+   return(0);
+}
+
+static int dlci_change_mtu(struct device *dev, int new_mtu)
+{
+   struct dlci_local *dlp;
+
+   dlp = dev->priv;
+
+   return((*dlp->slave->change_mtu)(dlp->slave, new_mtu));
+}
+
+static int dlci_open(struct device *dev)
+{
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   int               err;
+
+   dlp = dev->priv;
+
+   if (!*(short *)(dev->dev_addr))
+      return(-EINVAL);
+
+   if (!dlp->slave->start)
+      return(-ENOTCONN);
+
+   dev->flags = 0;
+   dev->tbusy = 0;
+   dev->interrupt = 0;
+   dev->start = 1;
+
+   flp = dlp->slave->priv;
+   err = (*flp->activate)(dlp->slave, dev);
+   if (err)
+      return(err);
+
+   return 0;
+}
+
+static int dlci_close(struct device *dev)
+{
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   int               err;
+
+   dlp = dev->priv;
+
+   flp = dlp->slave->priv;
+   err = (*flp->deactivate)(dlp->slave, dev);
+
+   dev->start = 0;
+
+   return 0;
+}
+
+static struct enet_statistics *dlci_get_stats(struct device *dev)
+{
+   struct dlci_local *dlp;
+
+   dlp = dev->priv;
+
+   return(&dlp->stats);
+}
+
+int dlci_init(struct device *dev)
+{
+   struct dlci_local *dlp;
+   int i;
+
+   dev->priv = kmalloc(sizeof(struct dlci_local), GFP_KERNEL);
+   if (!dev->priv)
+      return(-ENOMEM);
+
+   memset(dev->priv, 0, sizeof(struct dlci_local));
+   dlp = dev->priv;
+
+   dev->flags           = 0;
+   dev->open            = dlci_open;
+   dev->stop            = dlci_close;
+   dev->do_ioctl        = dlci_ioctl;
+   dev->hard_start_xmit = dlci_transmit;
+   dev->hard_header     = dlci_header;
+   dev->get_stats       = dlci_get_stats;
+   dev->change_mtu	= dlci_change_mtu;
+
+   dlp->receive         = dlci_receive;
+
+   dev->type            = ARPHRD_DLCI;
+   dev->family          = AF_INET;
+   dev->hard_header_len = sizeof(struct fradhdr);
+   dev->pa_alen         = sizeof(unsigned long);
+
+   memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
+
+   for (i = 0; i < DEV_NUMBUFFS; i++) 
+      skb_queue_head_init(&dev->buffs[i]);
+
+   return(0);
+}
+
+int dlci_setup(void)
+{
+   int i;
+
+   printk("%s.\n", version);
+   
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      open_dev[i] = NULL;
+
+   for(i=0;i<sizeof(basename) / sizeof(char *);i++)
+      basename[i] = NULL;
+
+   return(0);
+}
+
+#ifdef MODULE
+static struct device dlci = {"dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, dlci_init, };
+
+int init_module(void)
+{
+   dlci_setup();
+   return(register_netdev(&dlci));
+}
+
+void cleanup_module(void)
+{
+   struct dlci_local   *dlp;
+   struct frad_local   *flp;
+   int                 i;
+
+   unregister_netdev(&dlci);
+
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      if (open_dev[i])
+      {
+         dlp = open_dev[i]->priv;
+         flp = open_dev[i]->slave->priv;
+
+         if (open_dev[i]->start)
+         {
+            if (flp->deactivate)
+               (*flp->deactivate)(open_dev[i]->slave, open_dev[i]);
+            open_dev[i]->start = 0;
+         }
+
+         (*flp->deassoc)(open_dev[i]->slave, open_dev[i]);
+         kfree(open_dev[i]->priv);
+         kfree(open_dev[i]->name);
+         kfree(open_dev[i]);
+         open_dev[i] = NULL;
+      }
+
+   if (dlci.priv)
+      kfree(dlci.priv);
+}
+#endif /* MODULE */
diff -u --recursive --new-file v1.3.77/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v1.3.77/linux/drivers/net/ibmtr.c	Sun Mar 10 09:49:50 1996
+++ linux/drivers/net/ibmtr.c	Sun Mar 24 12:09:36 1996
@@ -1,14 +1,14 @@
 /* ibmtr.c:  A shared-memory IBM Token Ring 16/4 driver for linux */
 /*
-	Written 1993 by Mark Swanson and Peter De Schrijver.
-	This software may be used and distributed according to the terms
-	of the GNU Public License, incorporated herein by reference.
+  Written 1993 by Mark Swanson and Peter De Schrijver.
+  This software may be used and distributed according to the terms
+  of the GNU Public License, incorporated herein by reference.
 
-	This device driver should work with Any IBM Token Ring Card that does
-   not use DMA.
+  This device driver should work with Any IBM Token Ring Card that does
+  not use DMA.
 
-	I used Donald Becker's (becker@super.org) device driver work
-	as a base for most of my initial work.
+  I used Donald Becker's (becker@super.org) device driver work
+  as a base for most of my initial work.
 */
 
 /*
@@ -34,6 +34,12 @@
         - removed redundant information display
         - some code reworking
 
+   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 
+          alpha platform (structure access -> readb/writeb)
+
    Chagnes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com)
                            (January 18 1996):
         - swapped WWOR and WWCR in ibmtr.h
@@ -69,26 +75,29 @@
 
 /* changes the output format of driver initialisation */
 #define TR_NEWFORMAT	1
+#define TR_VERBOSE	0
 
 /* some 95 OS send many non UI frame; this allow removing the warning */
 #define TR_FILTERNONUI	1
 
 /* version and credits */
-static const char *version = "ibmtr.c: v1.3.24 8/7/94 Peter De Schrijver and Mark Swanson\n"
-"   modified 10/3/94 DW Morris, 3/9/95 F Farid and P Andre, 9/7/95 P Andre\n";
-
+static const char *version = 
+"ibmtr.c: v1.3.57 8/7/94 Peter De Schrijver and Mark Swanson\n"
+"  modified 10/3/94 DW Morris, modified at VIA, ECP, France\n"
+"  (3/9/95 F Farid and P Andre, 9/7/95 PA and 2/20/95 ML/PA/YD)\n";
+ 
 static char pcchannelid[]={0x05, 0x00, 0x04, 0x09,
-			 0x04, 0x03, 0x04, 0x0f,
-			 0x03, 0x06, 0x03, 0x01,
-			 0x03, 0x01, 0x03, 0x00,
-			 0x03, 0x09, 0x03, 0x09,
-			 0x03, 0x00, 0x02, 0x00};
+			   0x04, 0x03, 0x04, 0x0f,
+			   0x03, 0x06, 0x03, 0x01,
+			   0x03, 0x01, 0x03, 0x00,
+			   0x03, 0x09, 0x03, 0x09,
+			   0x03, 0x00, 0x02, 0x00};
 static char mcchannelid[]={0x04, 0x0d, 0x04, 0x01,
-			 0x05, 0x02, 0x05, 0x03,
-			 0x03, 0x06, 0x03, 0x03,
-			 0x05, 0x08, 0x03, 0x04,
-			 0x03, 0x05, 0x03, 0x01,
-			 0x03, 0x08, 0x02, 0x00};
+			   0x05, 0x02, 0x05, 0x03,
+			   0x03, 0x06, 0x03, 0x03,
+			   0x05, 0x08, 0x03, 0x04,
+			   0x03, 0x05, 0x03, 0x01,
+			   0x03, 0x08, 0x02, 0x00};
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -114,29 +123,21 @@
 #define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)
 #define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)
 
-#ifdef TR_NEWFORMAT
+#if TR_NEWFORMAT
 /* this allows displaying full adapter information */
 const char *channel_def[] = { "ISA", "MCA", "ISA P&P" };
+
 char *adapter_def(char type)
 {
-       switch (type)
-       {
-               case 0xF : return "Adapter/A";
-               case 0xE : return "16/4 Adapter/II";
-               default : return "adapter";
-       };
+	switch (type) {
+	      case 0xF : return "Adapter/A";
+	      case 0xE : return "16/4 Adapter/II";
+	      default : return "adapter";
+	};
 };
 #endif
 
-#if 0
-struct tok_info tok_info1;   /*  WARNING: this area must be replicated
-                                 or 'malloced' to support > 1 adapter */
-
-static struct wait_queue *wait_for_tok_int=NULL, *wait_for_reset;
-void (*do_tok_int)(struct device *dev)=NULL;
-#endif
-
-#ifndef TR_NEWFORMAT
+#if !TR_NEWFORMAT
 unsigned char ibmtr_debug_trace=1;  /*  Patch or otherwise alter to
                                          control tokenring tracing.  */
 #else
@@ -145,8 +146,8 @@
 #define TRC_INIT 0x01              /*  Trace initialization & PROBEs */
 #define TRC_INITV 0x02             /*  verbose init trace points     */
 
-static short TokBaseAddrs[]={MMIOStartLocP, /* Addr-s to scan */
-                             MMIOStartLocA};
+/* addresses to scan */
+static short TokBaseAddrs[] = { MMIOStartLocP, MMIOStartLocA };
 
 
 int tok_probe(struct device *dev);
@@ -170,17 +171,29 @@
 
 static struct timer_list tr_timer={NULL,NULL,0,0L,tok_open_adapter};
 
+#if 0
 int DummyCallCount=0;
 
 /*  This routine combined with the #DEFINE DPRINTD serves
     to workaround the gcc apparent bug.   in tr_tx() */
 
-static void DummyCall(const char * fmt,...) {DummyCallCount++;return;}
+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=j+stride) printk("%1x",((int) pcid[j])&0x0f);
-  printk("\n");
+	short i, j;
+	for (i=0, j=0; i<24; i++, j+=stride) 
+		printk("%1x", ((int) pcid[j]) & 0x0f);
+	printk("\n");
+}
+
+static void HWPrtChanID (__u32 pcid, short stride)
+{
+	short i, j;
+	for (i=0, j=0; i<24; i++, j+=stride)
+		printk("%1x", ((int)readb(pcid + j)) & 0x0f);
+	printk("\n");
 }
 
 /* tok_probe():  Routine specified in the network device structure
@@ -196,1147 +209,1232 @@
 
 int tok_probe(struct device *dev)
 {
+	unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0;
+	__u32 t_mmio=0;
+	short PIOaddr=0, iAddr;
+	struct tok_info *ti=0;
+	static struct tok_info *badti=0;  /* if fail after kmalloc, reuse */
+	
+	static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE;
+	
+	/* this is the major adapter probe loop.  For each call to tok_probe,
+	   we try each remaining entry in TokBaseAddrs[] as a possible
+	   adapter.  Once an entry is rejected or assigned, we zero it to
+	   avoid duplicate use or worthless trial for the tok probe call*/
+	
+	for (iAddr=0;
+	     iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0; iAddr++) { 
+		
+		__u32 cd_chanid;
+		unsigned char *tchanid, ctemp;
+		
+		PIOaddr=TokBaseAddrs[iAddr];  /* address to try           */
+		TokBaseAddrs[iAddr] = 0;      /* (and marked already used */
+		if (PIOaddr == 0) continue;   /* already tried this addr */
+		
+		/* Make sure PIO address not already assigned
+		   elsewhere before we muck with IO address */
+		if (check_region(PIOaddr,TR_IO_EXTENT)) {
+			if (ibmtr_debug_trace & TRC_INIT)
+				DPRINTK("check_region(%4hx,%d) failed.\n", PIOaddr, TR_IO_EXTENT);
+			PIOaddr = 0; 
+			continue; /* clear to flag fail and try next */
+		}
+		/* Query the adapter PIO base port which will return
+		   indication of where MMIO was placed (per tech ref
+		   this assignment is done by BIOS - what is rational for
+		   where it is?).  We also have a coded interrupt address. */
+		
+		segment = inb(PIOaddr);
+		/* out of range values so we'll assume non-existant IO device */
+		if (segment < 0x40 || segment > 0xe0) { 
+			PIOaddr = 0; 
+			continue; /* clear to flag fail and try next */
+		}
+		
+		/* Compute the linear base address of the MMIO area
+		   as LINUX doesn't care about segments          */
+		t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000);
+		intr = segment & 0x03;   /* low bits is coded interrupt # */
+		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 */
+		/* !!!WARNING:!!!! It seems pretty silly to blunder ahead
+		   w/o verification that the mmio address we have found
+		   is valid storage -- perhaps this is tolerable for current
+		   hardware state??? */
+		
+		cd_chanid = (CHANNEL_ID + t_mmio);  /* for efficiency */
+		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; 
+			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]) {
+					cardpresent=NOTOK;   /* match failed, not TR card */
+					break;
+				}
+			}
+		}
+		
+		/* 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);
+				DPRINTK("Expected for ISA: ");  PrtChanID(pcchannelid,1);
+				DPRINTK("           found: ");  HWPrtChanID(cd_chanid,2);
+				DPRINTK("Expected for MCA: ");  PrtChanID(mcchannelid,1);
+			}
+			PIOaddr = 0;  /* all to know not found yet */
+			continue;
+		}
+		
+	/* !!!! we could tighten validation by checking the HW Address
+	   against the 1-s complement..  Move the get HW logic to here */
+		
+	}
+	
+	/* The search loop has either completed with a presumed TR adapter
+	   or none found.  Check situation ... march on if possible */
+	
+	if (PIOaddr == 0) { /* failed to find a valid TR adapter */
+		if (ibmtr_debug_trace & TRC_INIT)
+			DPRINTK("Unable to assign adapter to device.\n");
+		return ENODEV;
+	}
+	
+	/*?? Now, allocate some of the pl0 buffers for this driver.. */
+	
+	if (!badti) {
+		ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
+		if (ti == NULL) return -ENOMEM;
+	} else {
+		ti = badti; 
+		badti = NULL;
+	} /*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */
+	
+	memset(ti, 0, sizeof(struct tok_info));
 
-  unsigned char segment=0, intr=0, irq=0, i=0, j=0,
-                cardpresent=NOTOK,temp=0;
-  unsigned char *t_mmio=0;
-  short PIOaddr=0, iAddr;
-  struct tok_info *ti=0;
-  static struct tok_info *badti=0;  /* if fail after kmalloc, reuse */
-
-  static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE;
-
-  /*  this is the major adapter probe loop.  For each call to tok_probe,
-      we try each remaining entry in TokBaseAddrs[] as a possible
-      adapter.  Once an entry is rejected or assigned, we zero it to
-      avoid duplicate use or worthless trial for the tok probe call*/
-
-  for (iAddr=0;
-       iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0;
-       iAddr++) { char *tchanid, *cd_chanid, ctemp;
-    PIOaddr=TokBaseAddrs[iAddr];  /* address to try           */
-    TokBaseAddrs[iAddr] = 0;      /* (and marked already used */
-    if (PIOaddr == 0) continue;   /* already tried this addr */
-    if ( check_region(PIOaddr,TR_IO_EXTENT) ) { /* Make sure PIO address not
-						   already assigned elsewhere
-						   before we muck with I/O
-						   addresses */
-      if (ibmtr_debug_trace & TRC_INIT)
-	DPRINTK("check_region(%4hx,%d) failed.\n",PIOaddr, TR_IO_EXTENT);
-      PIOaddr = 0; continue; /* clear to flag fail and try next */
-    }
-           /*  Query the adapter PIO base port which will return
-               indication of where MMIO was placed (per tech ref
-               this assignment is done by BIOS - what is rational for
-               where it is?).  We also have a coded interrupt address.*/
-
-    segment = inb(PIOaddr);
-    if (segment < 0x40 || segment > 0xe0) { /* out of range values
-                            so we will assume non-existant IO dev */
-      PIOaddr = 0; continue; /* clear to flag fail and try next */
-    }
-
-                 /*  Compute the linear base address of the MMIO area
-                     as LINUX doesn't care about segments          */
-    t_mmio=(char *) (((segment & 0xfc) << 11) + 0x80000);
-    intr = segment & 0x03;   /* low bits is coded interrupt # */
-    if (ibmtr_debug_trace & TRC_INIT)
-      DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p 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 */
-        /*  !!!WARNING:!!!! It seems pretty silly to blunder ahead
-            w/o verification that the mmio address we have found
-            is valid storage -- perhaps this is tolerable for current
-            hardware state??? */
-    cd_chanid = (char *)(CHANNEL_ID + t_mmio);  /* for efficiency */
-    tchanid=pcchannelid; cardpresent=TR_ISA;  /* try ISA ? */
-                       /* suboptimize knowing first byte different */
-    ctemp = (* cd_chanid) & 0x0f;
-    if (  ctemp != *tchanid) { /* NOT ISA card, try MCA */
-      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 ( (cd_chanid[i] & 0x0f) != tchanid[j]) {
-          cardpresent=NOTOK;   /* match failed, not TR card */
-          break;
-        }
-      }
-    }
-
-    /* If we have an ISA board check for the ISA P&P version, as it has
-       different IRQ settings */
-    if (cardpresent == TR_ISA && (*(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);
-        DPRINTK("Expected for ISA: ");  PrtChanID(pcchannelid,1);
-        DPRINTK("           found: ");  PrtChanID(cd_chanid,2);
-        DPRINTK("Expected for MCA: ");  PrtChanID(mcchannelid,1);
-      }
-      PIOaddr = 0;  /* all to know not found yet */
-      continue;
-    }
-
-   /* !!!! we could tighten validation by checking the HW Address
-      against the 1-s complement..  Move the get HW logic to here */
-
-  }
-
-  /*   The search loop has either completed with a presumed TR adapter
-       or none found.  Check situation ... march on if possible */
-
-  if (PIOaddr == 0) { /* failed to find a valid TR adapter */
-    if (ibmtr_debug_trace & TRC_INIT)
-         DPRINTK("Unable to assign adapter to device.\n");
-    return ENODEV;
-  }
-
-  /*?? Now, allocate some of the pl0 buffers for this driver.. */
-
-  if (!badti) {
-    ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
-    if (ti == NULL)
-          return -ENOMEM;
-  } else {
-    ti = badti; badti = NULL;
-  }/*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */
-
-  memset(ti,0,sizeof(struct tok_info));
-
-  ti->mmio= t_mmio;
+	ti->mmio= t_mmio;
 
-  dev->priv = ti;     /* this seems like the logical use of the
+	dev->priv = ti;     /* this seems like the logical use of the
                          field ... lets try some empirical tests
                          using the token-info structure -- that
                          should fit with out future hope of multiple
                          adapter support as well /dwm   */
 
-  switch (cardpresent) {
-    case TR_ISA:
-      if (intr==0) irq=9; /* irq2 really is irq9 */
-      if (intr==1) irq=3;
-      if (intr==2) irq=6;
-      if (intr==3) irq=7;
-      ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
-      ti->sram=NULL;
-#ifndef TR_NEWFORMAT
-      DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
-#endif
-      break;
-    case TR_MCA:
-      if (intr==0) irq=9;
-      if (intr==1) irq=3;
-      if (intr==2) irq=10;
-      if (intr==3) irq=11;
-      ti->global_int_enable=0;
-      ti->sram=(unsigned char *)((inb(PIOaddr+ADAPTRESETREL) & 0xfe)
-                                  << 12);
-      break;
-    case TR_ISAPNP:
-      if (intr==0) irq=9;
-      if (intr==1) irq=3;
-      if (intr==2) irq=10;
-      if (intr==3) irq=11;
-      while(!(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN));
-      ti->sram=(unsigned char *)((unsigned long)(*(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)) <<12);
-      ti->global_int_enable=PIOaddr+ADAPTINTREL;
-      break;
+	switch (cardpresent) {
+	      case TR_ISA:
+		if (intr==0) irq=9; /* irq2 really is irq9 */
+		if (intr==1) irq=3;
+		if (intr==2) irq=6;
+		if (intr==3) irq=7;
+		ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
+		ti->sram=0;
+#if !TR_NEWFORMAT
+		DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
+#endif
+		break;
+	      case TR_MCA:
+		if (intr==0) irq=9;
+		if (intr==1) irq=3;
+		if (intr==2) irq=10;
+		if (intr==3) irq=11;
+		ti->global_int_enable=0;
+		ti->sram=((__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12);
+		break;
+	      case TR_ISAPNP:
+		if (intr==0) irq=9;
+		if (intr==1) irq=3;
+		if (intr==2) irq=10;
+		if (intr==3) irq=11;
+		while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN));
+		ti->sram=((__u32)readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12);
+		ti->global_int_enable=PIOaddr+ADAPTINTREL;
+		break;
       
-  }
+	}
 
-  if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
-    DPRINTK("irq=%d",irq);
-    if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
-      DPRINTK(", ti->mmio=%p",ti->mmio);
-      printk(", segment=%02X",segment);
-    }
-    printk(".\n");
-  }
-
-  /* Get hw address of token ring card */
-#ifndef TR_NEWFORMAT 
-  DPRINTK("hw address: ");
-#endif
-  j=0;
-  for (i=0; i<0x18; i=i+2) {
-    temp = *(char *)((ulong)AIP + (ulong)i + ti->mmio) & 0x0f; /* Tech ref states must do this */
-#ifndef TR_NEWFORMAT
-    printk("%1X",ti->hw_address[j]=temp);
+	if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
+		DPRINTK("irq=%d",irq);
+		if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
+			DPRINTK(", ti->mmio=%08X",ti->mmio);
+			printk(", segment=%02X",segment);
+		}
+		printk(".\n");
+	}
+
+	/* Get hw address of token ring card */
+#if !TR_NEWFORMAT 
+	DPRINTK("hw address: ");
+#endif
+	j=0;
+	for (i=0; i<0x18; i=i+2) {
+		/* technical reference states to do this */
+		temp = readb(ti->mmio + AIP + i) & 0x0f;
+#if !TR_NEWFORMAT
+		printk("%1X",ti->hw_address[j]=temp);
 #else
-    ti->hw_address[j]=temp;
+		ti->hw_address[j]=temp;
 #endif
-    if(j&1)
-      dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
-    ++j;
-  }
+		if(j&1)
+			dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
+		++j;
+	}
 #ifndef TR_NEWFORMAT
-  printk("\n");
+	printk("\n");
 #endif
 
+	/* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
+	ti->adapter_type = readb(ti->mmio + AIPADAPTYPE);
 
-  /* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
-  ti->adapter_type = *(char *)(ti->mmio + AIPADAPTYPE);
-
-  /* get Data Rate:  F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
-  ti->data_rate = *(char *)(ti->mmio + AIPDATARATE);
+	/* get Data Rate:  F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
+	ti->data_rate = readb(ti->mmio + AIPDATARATE);
 
-  /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
-  ti->token_release = *(char *)(ti->mmio + AIPEARLYTOKEN);
+	/* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
+	ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);
 
-  /* How much shared RAM is on adapter ? */
-  ti->avail_shared_ram = get_sram_size(ti);
+	/* How much shared RAM is on adapter ? */
+	ti->avail_shared_ram = get_sram_size(ti);
 
-  /* We need to set or do a bunch of work here based on previous results.. */
-  /* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */
-  ti->shared_ram_paging = *(char *)(ti->mmio + AIPSHRAMPAGE);
+	/* We need to set or do a bunch of work here based on previous results.. */
+	/* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */
+	ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);
 
   /* Available DHB  4Mb size:   F=2048, E=4096, D=4464 */
-  ti->dhb_size4mb = *(char *) (ti->mmio + AIP4MBDHB);
+	ti->dhb_size4mb = readb(ti->mmio + AIP4MBDHB);
 
-  /* Available DHB 16Mb size:  F=2048, E=4096, D=8192, C=16384, B=17960 */
-  ti->dhb_size16mb = *(char *)(ti->mmio + AIP16MBDHB);
+	/* Available DHB 16Mb size:  F=2048, E=4096, D=8192, C=16384, B=17960 */
+	ti->dhb_size16mb = readb(ti->mmio + AIP16MBDHB);
 
-#ifndef 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->shared_ram_paging,
-	  ti->dhb_size4mb, ti->dhb_size16mb);
-#endif
-
-  /* We must figure out how much shared memory space this adapter
-     will occupy so that if there are two adapters we can fit both
-     in.  Given a choice, we will limit this adapter to 32K.  The
-     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<<(((*(unsigned char *)
-                       (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
-  ti->page_mask=0;
-  if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
-    ti->mapped_ram_size = ti->avail_shared_ram;
-  } else {
+#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->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb);
+#endif
+
+	/* We must figure out how much shared memory space this adapter
+	   will occupy so that if there are two adapters we can fit both
+	   in.  Given a choice, we will limit this adapter to 32K.  The
+	   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) +4);
+	ti->page_mask=0;
+	if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
+		ti->mapped_ram_size = ti->avail_shared_ram;
+	} else {
 #ifdef ENABLE_PAGING
-    unsigned char pg_size;
+		unsigned char pg_size;
 #endif
 
-#ifndef TR_NEWFORMAT
-    DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
+#if !TR_NEWFORMAT
+		DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
 #endif
 #ifdef ENABLE_PAGING
-    switch(ti->shared_ram_paging) {
-      case 0xf:
-        break;
-      case 0xe:
-	ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
-	pg_size=32;   /* 16KB page size */
-	break;
-      case 0xd:
-	ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
-	pg_size=64;   /* 32KB page size */
-	break;
-      case 0xc:
-	ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
-	ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
-	DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");
-	/* nb/dwm: I did this because RRR (3,2) bits are documented as
-	 * R/O and I can't find how to select which page size
-	 * Also, the above conditional statement sequence is invalid
-	 *       as page_mask will always be set by the second stmt
-	 */
-	badti=ti;
-	break;
-      default:
-	DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
-	badti=ti;    /* bail out if bad code */
-	break;
-    }
-    if(ti->page_mask) {
-      if(pg_size > ti->mapped_ram_size) {
-	DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
-		pg_size, ti->mapped_ram_size);
-	ti->page_mask = 0;    /* reset paging */
-      } else {
-	ti->mapped_ram_size=ti->avail_shared_ram; /****** ?????????? *******/
-	DPRINTK("Shared RAM paging enabled. Page size : %uK\n",((ti->page_mask^ 0xff)+1)>>2);
-      }
-    }
-#else
+	switch(ti->shared_ram_paging) {
+	      case 0xf:
+		break;
+	      case 0xe:
+		ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
+		pg_size=32;   /* 16KB page size */
+		break;
+	      case 0xd:
+		ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
+		pg_size=64;   /* 32KB page size */
+		break;
+	      case 0xc:
+		ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
+		ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
+		DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");
+		/* nb/dwm: I did this because RRR (3,2) bits are documented as
+		   R/O and I can't find how to select which page size
+		   Also, the above conditional statement sequence is invalid
+		   as page_mask will always be set by the second stmt */
+		badti=ti;
+		break;
+	      default:
+		DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
+		badti=ti;    /* bail out if bad code */
+		break;
+	}
+	if (ti->page_mask) {
+		if (pg_size > ti->mapped_ram_size) {
+			DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
+				pg_size, ti->mapped_ram_size);
+				ti->page_mask = 0;    /* reset paging */
+		} else {
+			ti->mapped_ram_size=ti->avail_shared_ram; 
+			DPRINTK("Shared RAM paging enabled. Page size : %uK\n",
+				((ti->page_mask^ 0xff)+1)>>2);
+		}
 #endif
-  }
+	}
 
-  if (cardpresent==TR_ISA) { /* finish figuring the shared RAM address */
-    static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0};
-    unsigned char new_base, rrr_32, chk_base, rbm;
-    rrr_32 = (*(unsigned char *)
-                       (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2;
-    rbm = ram_bndry_mask[rrr_32];
-    new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */
-    chk_base = new_base + (ti->mapped_ram_size>>3);
-    if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) {
-      DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
-              " limit (%05x), adapter not started.\n",
-              chk_base<<12, (IBMTR_SHARED_RAM_BASE+
-                              IBMTR_SHARED_RAM_SIZE)<<12);
-      badti=ti;
-    } else {  /* seems cool, record what we have figured out */
-      ti->sram_base = new_base;
-      Shared_Ram_Base = new_base;
-    }
-  }
-
-  /* dwm: irq and other final setup moved here so if we find other
-        unrecognized values OR shared ram conflicts, we can still
-        bail out in a rather benign fashion.    */
+	/* finish figuring the shared RAM address */
+	if (cardpresent==TR_ISA) {
+		static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0};
+		unsigned char new_base, rrr_32, chk_base, rbm;
+		rrr_32 = (readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2;
+		rbm = ram_bndry_mask[rrr_32];
+		new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */
+		chk_base = new_base + (ti->mapped_ram_size>>3);
+		if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) {
+			DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
+				" limit (%05x), adapter not started.\n",
+				chk_base<<12, (IBMTR_SHARED_RAM_BASE+
+					       IBMTR_SHARED_RAM_SIZE)<<12);
+			badti=ti;
+		} else {  /* seems cool, record what we have figured out */
+			ti->sram_base = new_base;
+			Shared_Ram_Base = new_base;
+		}
+	}
 
-  if (badti) return ENODEV;
-#ifndef TR_NEWFORMAT
-  DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
+	/* dwm: irq and other final setup moved here so if we find other
+           unrecognized values OR shared ram conflicts, we can still
+           bail out in a rather benign fashion.    */
+
+	if (badti) return ENODEV;
+#if !TR_NEWFORMAT
+	DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
 #endif
 
-  if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) {
-    DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
-    badti = ti;    /*  keep track of unused tok_info */
-    return ENODEV;
-  }
-  irq2dev_map[irq]=dev;
-
-  /*?? Now, allocate some of the PIO PORTs for this driver.. */
-  request_region(PIOaddr,TR_IO_EXTENT,"ibmtr");  /* record PIOaddr range
-						    as busy */
-#ifndef TR_NEWFORMAT
-   DPRINTK("%s",version); /* As we have passed card identification,
-                             let the world know we're here! */
+	if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) {
+		DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
+		badti = ti;    /*  keep track of unused tok_info */
+		return ENODEV;
+	}
+	irq2dev_map[irq]=dev;
+
+ /*?? Now, allocate some of the PIO PORTs for this driver.. */
+	request_region(PIOaddr,TR_IO_EXTENT,"ibmtr");  /* record PIOaddr range
+								  as busy */
+#if !TR_NEWFORMAT
+	DPRINTK("%s",version); /* As we have passed card identification,
+                                  let the world know we're here! */
 #else
-  printk("%s",version);
-  DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n",
-       channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq,
-        PIOaddr, ti->mapped_ram_size/2);
-  DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
-       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-        dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+	printk("%s",version);
+	DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n",
+		channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq,
+		PIOaddr, ti->mapped_ram_size/2);
+	DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 #endif
 
-  dev->base_addr=PIOaddr; /* set the value for device */
-
-  trdev_init(dev);
-  tok_init_card(dev);
-
-  return 0;  /* Return 0 to indicate we have found a Token Ring card. */
+	dev->base_addr=PIOaddr; /* set the value for device */
+	
+	dev->open=tok_open;
+	dev->stop=tok_close;
+	dev->hard_start_xmit=tok_send_packet;
+	dev->get_stats = NULL;
+	dev->get_stats = tok_get_stats;
+	dev->set_multicast_list = NULL;
+	tr_setup(dev);
+	tok_init_card((unsigned long)dev);
+	
+	return 0;  /* Return 0 to indicate we have found a Token Ring card. */
 }
 
 /* query the adapter for the size of shared RAM  */
 
-unsigned char get_sram_size(struct tok_info *adapt_info) {
-
+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
+	   'C' -- 32kb  'A' -- 64KB
+	   'B' - 64KB less 512 bytes at top
+	   (WARNING ... must zero top bytes in INIT */
 
-           /*  Adapter gives
-                'F' -- use RRR bits 3,2
-                'E' -- 8kb   'D' -- 16kb
-                'C' -- 32kb  'A' -- 64KB
-                'B' - 64KB less 512 bytes at top
-                      (WARNING ... must zero top bytes in INIT */
-
-	avail_sram_code=0xf-*(adapt_info->mmio + AIPAVAILSHRAM);
-	if(avail_sram_code)
+	avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM);
+	if (avail_sram_code) 
 		return size_code[avail_sram_code];
 	else  /* for code 'F', must compute size from RRR(3,2) bits */
-
-		return 1<<(((*(unsigned char *)
-              (adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
+		return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
 }
 
-
-int trdev_init(struct device *dev)
+static int tok_open(struct device *dev) 
 {
-  struct tok_info *ti=(struct tok_info *)dev->priv;
-
-  ti->open_status=CLOSED;
-
-  dev->init=tok_init_card;
-  dev->open=tok_open;
-  dev->stop=tok_close;
-  dev->hard_start_xmit=tok_send_packet;
-  dev->get_stats = NULL;
-  dev->get_stats = tok_get_stats;
-  dev->set_multicast_list = NULL;
-  tr_setup(dev);
-
-  return 0;
-}
-
-
-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);
-	}
+	struct tok_info *ti=(struct tok_info *)dev->priv;
+	
+	if (ti->open_status==CLOSED) tok_init_card((unsigned long)dev);
+	
+	if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
+	
+	if (ti->open_status==SUCCES) {
+		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;
 	
-   if(ti->open_status==SUCCES) {
-      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) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-
-	struct srb_close_adapter *close_adapter=(struct srb_close_adapter *)ti->srb;
-
-	close_adapter->command=DIR_CLOSE_ADAPTER;
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-
-   ti->open_status=CLOSED;
-
+static int tok_close(struct device *dev) 
+{
+	
+	struct tok_info *ti=(struct tok_info *) dev->priv;
+	
+	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);		
-
-	if(close_adapter->ret_code)
-		DPRINTK("close adapter failed: %02X\n",close_adapter->ret_code);
 	
+	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)));
+		
 	MOD_DEC_USE_COUNT;
-
+	
 	return 0;
 }
 
 void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
-
 	unsigned char status;
-  struct tok_info *ti;
-/*   int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); */
-   struct device *dev = (struct device *)(irq2dev_map[irq]);
-#if 0
-   DPRINTK("Int from tok_driver, dev : %p\n",dev);
-#endif
-  ti=(struct tok_info *) dev->priv;
-
-  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.   */
-
-
-	dev->interrupt=1;
-
-	/* Disable interrupts till processing is finished */
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
-
-	/* Reset interrupt for ISA boards */
-	if(ti->global_int_enable)
-		outb(0,ti->global_int_enable);
+	struct tok_info *ti;
+	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	
-	status=*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
-
-#ifdef PCMCIA
-	/* Check if the PCMCIA card was pulled. */
-	if (status == 0xFF)
-	{
-	   DPRINTK("PCMCIA card removed.\n");
-	   dev->interrupt = 0;
-	   return;
-	}
-
-	/* Check ISRP EVEN too. */
-	if ( *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF)
-	{
-	   DPRINTK("PCMCIA card removed.\n");
-	   dev->interrupt = 0;
-	   return;
-	}
+#if TR_VERBOSE
+	DPRINTK("Int from tok_driver, dev : %p\n",dev);
 #endif
-
-	if(status & ADAP_CHK_INT) {
-		int i;
-                unsigned char *check_reason=ti->sram + ntohs(*(unsigned short *)(ti->mmio + 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 ",*check_reason);	
-		printk("\n");
-
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=(~ADAP_CHK_INT);
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN)=INT_ENABLE;
-		dev->interrupt=0;
-	}	
-
-	else if((*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)) & (TCR_INT + ERR_INT + ACCESS_INT)) {
-
-		DPRINTK("adapter error: ISRP_EVEN : %02x\n",
-				*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
+	
+	ti=(struct tok_info *) dev->priv;
+	
+	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.   */
+		
+		dev->interrupt=1;
+		
+		/* Disable interrupts till processing is finished */
+		writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+
+		/* Reset interrupt for ISA boards */
+		if (ti->global_int_enable)
+			outb(0, ti->global_int_enable);
+		
+		status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
+		
+		if (status & ADAP_CHK_INT) {
+			
+			int i;
+			__u32 check_reason;
+
+			check_reason=ti->mmio + ntohs(readw(ti->mmio + 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("\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", 
+				(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 
+			   & (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 */
 				
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(TCR_INT + ERR_INT + ACCESS_INT);
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN)=INT_ENABLE;
-		dev->interrupt=0;
-	}
+				switch(readb(ti->srb)) { /* SRB command check */
 					
-	else if(status & (SRB_RESP_INT + ASB_FREE_INT + ARB_CMD_INT + SSB_RESP_INT)) {
-
-		if(status & SRB_RESP_INT) {
-			switch(*ti->srb) {
-				case XMIT_DIR_FRAME: {
-					struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
-					if(xmit->ret_code!=0xff) {
-						DPRINTK("error on xmit_dir_frame request: %02X\n",xmit->ret_code);
-						if(ti->current_skb) {
-							dev_kfree_skb(ti->current_skb, FREE_WRITE);
-							ti->current_skb=NULL;
-						}
-						dev->tbusy=0;
-					}												
-				}
-				break;
-				
-				case XMIT_UI_FRAME: {
-					struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
-					if(xmit->ret_code!=0xff) {
-						DPRINTK("error on xmit_ui_frame request: %02X\n",xmit->ret_code);
-						if(ti->current_skb) {
-							dev_kfree_skb(ti->current_skb, FREE_WRITE);
-							ti->current_skb=NULL;
-						}
-						dev->tbusy=0;
-					}												
-				}
-				break;
-	
-				case DIR_OPEN_ADAPTER: {
-					struct srb_open_response *open_response=(struct srb_open_response *)(ti->init_srb);
-
-					ti->srb=ti->sram+ntohs(open_response->srb_addr);
-					ti->ssb=ti->sram+ntohs(open_response->ssb_addr);
-					ti->arb=ti->sram+ntohs(open_response->arb_addr);
-					ti->asb=ti->sram+ntohs(open_response->asb_addr);
-					ti->current_skb=NULL;
-
-					if(open_response->ret_code==7) {
-						if(!ti->auto_ringspeedsave && (open_response->error_code==0x24)) {
-							DPRINTK("open failed: Adapter speed must match ring speed if Automatic Ring Speed Save is disabled\n");
-							ti->open_status=FAILURE;
-							wake_up(&ti->wait_for_reset);
-						}
-						else if(open_response->error_code==0x24) 
-							DPRINTK("retrying open to adjust to ring speed\n");
-
-						else if((open_response->error_code==0x2d) && ti->auto_ringspeedsave)
-							DPRINTK("No signal detected for Auto Speed Detection\n");
-						else DPRINTK("Unrecoverable error: error code = %02X\n",open_response->error_code);
-					}
-					else if(!open_response->ret_code) {
-#ifndef TR_NEWFORMAT
-						DPRINTK("board opened...\n");
+				      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", 
+							      xmit_ret_code);
+						      if (ti->current_skb) {
+							      dev_kfree_skb(ti->current_skb, FREE_WRITE);
+							      ti->current_skb=NULL;
+						      }
+						      dev->tbusy=0;
+					      }
+				      }
+				      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",
+							      xmit_ret_code);
+						      if (ti->current_skb) {
+							      dev_kfree_skb(ti->current_skb, FREE_WRITE);
+							      ti->current_skb=NULL;
+						      }
+						      dev->tbusy=0;
+					      }
+				      }
+				      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 = 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");
+							      ti->open_status=FAILURE;
+							      wake_up(&ti->wait_for_reset);
+						      } else if (open_error_code==0x24)
+							      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 = %02X\n", 
+								   open_error_code);
+						      
+					      } else if (!open_ret_code) {
+#if !TR_NEWFORMAT
+						      DPRINTK("board opened...\n");
 #else
-						DPRINTK("Adapter initialized and opened.\n");
+						      DPRINTK("Adapter initialized and opened.\n");
 #endif
-						*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
-						*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
-						open_sap(EXTENDED_SAP,dev);
-/* YdW probably hates me */
-						goto skip_reset;
-					}
-					else {	
-						DPRINTK("open failed: ret_code = %02X, retrying\n",open_response->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:
+						      writeb(~(SRB_RESP_INT), 
+							     ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+						      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: {
-					struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
-					if(open_sap->ret_code) {
-						DPRINTK("open_sap failed: ret_code = %02X,retrying\n",open_sap->ret_code);
+					
+				      case DLC_OPEN_SAP:
+					if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
+						DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
+							(int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));
 						tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
 						tr_timer.data=(unsigned long)dev;
 						tr_timer.next=tr_timer.prev=NULL;
 						add_timer(&tr_timer);
-					}
-					else {
-						ti->exsap_station_id=open_sap->station_id;
+					} else {
+						ti->exsap_station_id=
+							readw(ti->srb+offsetof(struct dlc_open_sap, station_id));
 						ti->open_status=SUCCES; /* TR adapter is now available */
 						wake_up(&ti->wait_for_reset);
 					}
-				}
-				break;
-
-				case DIR_INTERRUPT:
-				case DIR_MOD_OPEN_PARAMS:	
-				case DIR_SET_GRP_ADDR:
-				case DIR_SET_FUNC_ADDR:
-				case DLC_CLOSE_SAP: {
-					struct srb_interrupt *intr=(struct srb_interrupt *)(ti->srb);
-					if(intr->ret_code)
-						DPRINTK("error on %02X: %02X\n",intr->command,intr->ret_code);	
-				}
-				break;
-
-				case DIR_READ_LOG: {
-					struct srb_read_log *read_log=(struct srb_read_log *)(ti->srb);
-					if(read_log->ret_code)
-						DPRINTK("error on dir_read_log: %02X\n",read_log->ret_code);
-					else {
-						DPRINTK("Line errors %02X, Internal errors %02X, Burst errors %02X\n",
-                          read_log->line_errors,read_log->internal_errors,read_log->burst_errors);
-						DPRINTK("A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n",
-                          read_log->A_C_errors,read_log->abort_delimiters,read_log->lost_frames);
-						DPRINTK("Receive congestion count %02X, Frame copied errors %02X, Frequency errors %02X\n",
-                          read_log->recv_congest_count,read_log->frame_copied_errors,read_log->frequency_errors);
-						DPRINTK("Token errors %02X\n",read_log->token_errors);
-					}
+					break;
+					
+				      case DIR_INTERRUPT:
+				      case DIR_MOD_OPEN_PARAMS:	
+				      case DIR_SET_GRP_ADDR:
+				      case DIR_SET_FUNC_ADDR:
+				      case DLC_CLOSE_SAP:
+					if (readb(ti->srb+offsetof(struct srb_interrupt, ret_code)))
+						DPRINTK("error on %02X: %02X\n",
+							(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",
+							(int)readb(ti->srb+offsetof(struct srb_read_log, ret_code)));
+					else
+						DPRINTK(
+							"Line errors %02X, Internal errors %02X, Burst errors %02X\n"
+							"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, 
+										    line_errors)),
+							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+										    internal_errors)),
+							(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, 
+										    abort_delimiters)),
+							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+										    lost_frames)),
+							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+												    recv_congest_count)),
+							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+										    frame_copied_errors)),
+							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+										    frequency_errors)),
+							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+												    token_errors)));
 					dev->tbusy=0;
-				}
-				break;
-
-				default:
-					DPRINTK("Unknown command %02X encountered\n",*(ti->srb));
-			}
-			*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
-			*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
-skip_reset:
-		}
-
-		if(status & ASB_FREE_INT) {
-			switch(*ti->asb) {
-				case REC_DATA:
-				case XMIT_UI_FRAME:
-				case XMIT_DIR_FRAME:
-					if(*(ti->asb+2)!=0xff)
-						DPRINTK("ASB error %02X in cmd %02X\n",	*(ti->asb+2),*(ti->asb));
 					break;
-				default:
-					DPRINTK("unknown command in asb %02X\n",*ti->asb);
-			}
-			*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ASB_FREE_INT);
-		}
-
-		if(status & ARB_CMD_INT) {
-			switch(*ti->arb) {
-				case DLC_STATUS: {
-					struct arb_dlc_status *dlc_status=(struct arb_dlc_status *)(ti->arb);			
-					DPRINTK("DLC_STATUS new status: %02X on station %02X\n",ntohs(dlc_status->status),ntohs(dlc_status->station_id));
-				}
-				break;
-
-				case REC_DATA:
+					
+				      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:
+					if (readb(ti->asb+2)!=0xff) /* checks ret_code */
+						DPRINTK("ASB error %02X in cmd %02X\n", 
+							(int)readb(ti->asb+2), 
+									(int)readb(ti->asb));
+					break;
+					
+				      default:
+					DPRINTK("unknown command in asb %02X\n",
+						(int)readb(ti->asb));
+					
+				} /* ASB command check */
+				
+				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", 
+						ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))),
+						ntohs(readw(ti->arb 
+									    +offsetof(struct arb_dlc_status, station_id))));
+					break;
+					
+				      case REC_DATA:
 					tr_rx(dev);
 					break;
-
-				case RING_STAT_CHANGE: {
-					struct arb_ring_stat_change *ring_stat_change=(struct arb_ring_stat_change *)(ti->arb);
-					unsigned short ring_status=ntohs(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");	
-						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 +
-								  AUTO_REMOVAL + REMOVE_RECV + RING_RECOVER))
-						DPRINTK("New ring status: %02X\n",ring_status);
-
-					if(ring_status & LOG_OVERFLOW) {
-						*(ti->srb)=DIR_READ_LOG;
-						*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-						*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-						dev->tbusy=1; /* really srb busy... */
-					}
-				}
-				break;
-
-				case XMIT_DATA_REQ:
+					
+				      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");	
+						      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 
+											| AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
+						      DPRINTK("New ring status: %02X\n", ring_status);
+					      
+					      if (ring_status & LOG_OVERFLOW) {
+						      
+						      writeb(DIR_READ_LOG, ti->srb);
+						      writeb(INT_ENABLE, 
+							     ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+						      writeb(CMD_IN_SRB, 
+							     ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+						      dev->tbusy=1; /* really srb busy... */
+						      
+					      }
+				      }
+				      break;
+				      
+				      case XMIT_DATA_REQ:
 					tr_tx(dev);
 					break;
-
-				default:
-					DPRINTK("Unknown command %02X in arb\n",*(ti->arb));
+					
+				      default:
+					DPRINTK("Unknown command %02X in arb\n", 
+						(int)readb(ti->arb));
 					break;
-			}
-			*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ARB_CMD_INT);
-			*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=ARB_FREE;
-		}
-
-		if(status & SSB_RESP_INT) {
-			switch(*ti->ssb) {
-				case XMIT_DIR_FRAME:
-				case XMIT_UI_FRAME:
-					if(*(ti->ssb+2))
-						DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",*(ti->ssb+2),*(ti->ssb+6));		
-					else
-						ti->tr_stats.tx_packets++;
+					
+				} /* 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));		
+					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 */
 				
-				case XMIT_XID_CMD:
-					DPRINTK("xmit xid ret_code: %02X\n",*(ti->ssb+2));
+				writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+				writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 				
-				default:
-					DPRINTK("Unknown command %02X in ssb\n",*(ti->ssb));
-			}
-			*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SSB_RESP_INT);
-			*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=SSB_FREE;
-		}
-	}	
-
-	dev->interrupt=0;
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-
-	return;
+			} /* SSB response */
+			
+		}	 /* SRB, ARB, ASB or SSB response */
+		
+		dev->interrupt=0;
+		writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+		break;
 
-      break;
-    case FIRST_INT:
-      initial_tok_int(dev);
-      break;
-    default:
-      DPRINTK("Unexpected interrupt from tr adapter\n");
-  }
+	      case FIRST_INT:
+		initial_tok_int(dev);
+		break;
+		
+	      default:
+		DPRINTK("Unexpected interrupt from tr adapter\n");
 
+	}
 }
 
-static void initial_tok_int(struct device *dev) {
-
-#ifndef TR_NEWFORMAT
-  int i;
-#endif
-  unsigned char *encoded_addr;
-  struct tok_info *ti;
-
-  ti=(struct tok_info *) dev->priv;
+static void initial_tok_int(struct device *dev) 
+{
 
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
+	__u32 encoded_addr;
+	__u32 hw_encoded_addr;
+	struct tok_info *ti;
+	
+	ti=(struct tok_info *) dev->priv;
+	
+	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
 	
 	/* Reset interrupt for ISA boards */
-	if(ti->global_int_enable)
-		outb(0,ti->global_int_enable);
-
+	if (ti->global_int_enable) outb(0,ti->global_int_enable);
+	
 	ti->do_tok_int=NOT_FIRST;
-
+	
 #ifndef TR_NEWFORMAT
 	DPRINTK("Initial tok int received\n");
 #endif
 
-	if(!ti->sram) {  /* we assign the address for ISA devices */
-			/* set RRR even to D000 for shared ram address */
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)=
-		                       ti->sram_base;
-		ti->sram=(char *)(ti->sram_base << 12);
+	/* we assign the address for ISA devices; set RRR even to D000 for 
+	   shared RAM address */
+	if(!ti->sram) {
+		writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
+		ti->sram=((__u32)ti->sram_base << 12);
+	}
+	ti->init_srb=ti->sram
+		+ntohs((unsigned short)readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
+	SET_PAGE(ntohs((unsigned short)readw(ti->mmio+ACA_OFFSET + WRBR_EVEN)));
+	
+#if TR_VERBOSE
+	{
+		int i;
+		DPRINTK("init_srb(%p):", ti->init_srb);
+		for (i=0;i<17;i++) printk("%02X ", (int)readb(ti->init_srb+i));
+		printk("\n");
 	}
-	ti->init_srb=ti->sram+ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
-	SET_PAGE(ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN)));
-
-#if 0
-	DPRINTK("init_srb(%p):",ti->init_srb);
-	for(i=0;i<17;i++)
-		printk("%02X ",*(ti->init_srb+i));
-	printk("\n");
 #endif
-
-#ifndef TR_NEWFORMAT		
-	DPRINTK("srb_init_response->encoded_address: %04X\n",((struct srb_init_response *)ti->init_srb)->encoded_address);
-	DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
+	
+	hw_encoded_addr = readw(ti->init_srb 
+				+ offsetof(struct srb_init_response, encoded_address));
+	
+#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=(unsigned char *)(ti->sram + ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
-
-#ifndef TR_NEWFORMAT
-	DPRINTK("encoded addr (%04X,%04X,%p): ",
-			((struct srb_init_response *)ti->init_srb)->encoded_address,
-			ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address),	
-			encoded_addr);
+	
+	encoded_addr=(ti->sram + ntohs(hw_encoded_addr));
+	
+#if !TR_NEWFORMAT
+	DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr, 
+		ntohs(hw_encoded_addr), encoded_addr);
 #else
-       DPRINTK("Initial interrupt : shared RAM located at %p.\n", encoded_addr);
-#endif
-	ti->auto_ringspeedsave=((struct srb_init_response *)ti->init_srb)->init_status_2 & 0x4 ? TRUE : FALSE;
-
-#ifndef TR_NEWFORMAT
-	for(i=0;i<TR_ALEN;i++)
-		printk("%02X%s",dev->dev_addr[i]=encoded_addr[i],(i==TR_ALEN-1) ? "" : ":" );
+	DPRINTK("Initial interrupt : shared RAM located at %08X.\n", encoded_addr);
+#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);
+		printk("%02X%s", dev->dev_addr[i], (i==TR_ALEN-1) ? "" : ":" );
+	}
 	printk("\n");
 #endif
-
+	
 	tok_open_adapter((unsigned long)dev);
-
 }
 
-static int tok_init_card(struct device *dev) {
-
-   struct tok_info *ti;
+static void tok_init_card(unsigned long dev_addr) 
+{
+	struct tok_info *ti;
 	short PIOaddr;
-        PIOaddr = dev->base_addr;
-        ti=(struct tok_info *) dev->priv;
-
-      /* Special processing for first interrupt after reset */
+	int i;
+	struct device *dev=(struct device *)dev_addr;
+	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) {
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)=SRPR_ENABLE_PAGING;
-	}
+	if(ti->page_mask)
+		writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
 #endif
-
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(INT_ENABLE);
-#ifndef TR_NEWFORMAT
+	
+	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+	
+#if !TR_NEWFORMAT
 	DPRINTK("resetting card\n");
 #endif
-	outb(0,PIOaddr+ADAPTRESET);
-        udelay(50000);
+	
+	outb(0, PIOaddr+ADAPTRESET);
+	for (i=jiffies+TR_RESET_INTERVAL; jiffies<=i;); /* wait 50ms */
 	outb(0,PIOaddr+ADAPTRESETREL);
-#ifndef TR_NEWFORMAT
+	
+#if !TR_NEWFORMAT
 	DPRINTK("card reset\n");
 #endif
-
-        ti->open_status=IN_PROGRESS;
-
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-        return 0;
+	
+	ti->open_status=IN_PROGRESS;
+	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+		
 }
 
-static void open_sap(unsigned char type,struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-	struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
-
+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);
-	memset(open_sap,0,sizeof(struct dlc_open_sap));
-
-	open_sap->command=DLC_OPEN_SAP;
-	open_sap->max_i_field=htons(MAX_I_FIELD);
-	open_sap->sap_options=SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY;
-	open_sap->station_count=SAP_OPEN_STATION_CNT;
-	open_sap->sap_value=type;
-
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_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), 
+	       ti->srb + offsetof(struct dlc_open_sap, max_i_field));
+	writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, 
+	       ti->srb + offsetof(struct dlc_open_sap, sap_options));
+	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 dir_open_adapter *open_adapter;
-  struct tok_info *ti;
-  ti=(struct tok_info *) dev->priv;
-
-#ifndef TR_NEWFORMAT
+	struct tok_info *ti;
+	int i;
+	
+	ti=(struct tok_info *) dev->priv;
+	
+#if !TR_NEWFORMAT
 	DPRINTK("now opening the board...\n");
 #endif
-
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
-
-	open_adapter=(struct dir_open_adapter *)(ti->init_srb);
-	memset(open_adapter,0,sizeof(struct dir_open_adapter));
-
-	open_adapter->command=DIR_OPEN_ADAPTER;
-	open_adapter->open_options=htons(OPEN_PASS_BCON_MAC);
-	open_adapter->num_rcv_buf=htons(NUM_RCV_BUF);
-	open_adapter->rcv_buf_len=htons(RCV_BUF_LEN);
-	open_adapter->dhb_length=htons(DHB_LENGTH);
-	open_adapter->num_dhb=NUM_DHB;
-	open_adapter->dlc_max_sap=DLC_MAX_SAP;
-	open_adapter->dlc_max_sta=DLC_MAX_STA;
-
+	
+	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, 
+	       ti->init_srb + offsetof(struct dir_open_adapter, command));
+	writew(htons(OPEN_PASS_BCON_MAC), 
+	       ti->init_srb + offsetof(struct dir_open_adapter, open_options));
+	writew(htons(NUM_RCV_BUF), 
+	       ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
+	writew(htons(RCV_BUF_LEN), 
+	       ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
+	writew(htons(DHB_LENGTH), 
+	       ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
+	writeb(NUM_DHB, 
+	       ti->init_srb + offsetof(struct dir_open_adapter, num_dhb));
+	writeb(DLC_MAX_SAP, 
+	       ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap));
+	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 */
-
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-
+	
+	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) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-	struct asb_xmit_resp *xmit_resp=(struct asb_xmit_resp *)ti->asb;
-	struct arb_xmit_req *xmit_req=(struct arb_xmit_req *)ti->arb;
-	struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
+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;
 	unsigned int hdr_len;
-	unsigned char *dhb;
-
-/* */
-  DPRINTD("ti=%p asb=(%p,%p) arb=(%p,%p) srb=(%p,%p)\n",
-       ti , ti->asb, xmit_resp, ti->arb, xmit_req, ti->srb, xmit);
-/* */
-
-#if 0
-DPRINTK("transmitting...\n");
-#endif
-
-	if(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+ntohs(xmit_req->dhb_address);
-
-	xmit_resp->command=xmit->command;
-	xmit_resp->station_id=xmit_req->station_id;
-	xmit_resp->rsap_value=EXTENDED_SAP;
-	xmit_resp->cmd_corr=xmit_req->cmd_corr;
-	xmit_resp->ret_code=0;
-
-	if((xmit->command==XMIT_XID_CMD) || (xmit->command==XMIT_TEST_CMD)) {
-		xmit_resp->frame_length=htons(0x11);
-		xmit_resp->hdr_length=0x0e;
-		dhb[0]=AC;
-		dhb[1]=LLC_FRAME;
-		memset(dhb+2,(int)0x0ff,TR_ALEN);
-		memset(dhb+2+TR_ALEN,0,TR_ALEN);
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET
-		                                         + ISRA_ODD)=RESP_IN_ASB;
+	__u32 dhb;
+	unsigned char xmit_command;
+	int i;
+	
+	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 
+		+ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
+	
+	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));
+	writeb(EXTENDED_SAP, ti->asb + offsetof(struct asb_xmit_resp, rsap_value));
+	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), 
+		       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
+	   sized route information field so here we must compress
+	   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 */
 
-     /* 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
-        sized route information field so here we must compress
-        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)) {
-    hdr_len=sizeof(struct trh_hdr)-18;
-#if 0
-DPRINTK(("hdr_length: %d, frame length: %ld\n",hdr_len,
-      ti->current_skb->len-18));
+	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
-  }   /*  TR packet includes RIF data ... preserve it */
-  else {
-    hdr_len=((ntohs(trhdr->rcf)
-             & TR_RCF_LEN_MASK)>>8)+sizeof(struct trh_hdr)-18;
-#if 0
-/* rework the following if activated, hdr_len <> rif_len */
-DPRINTK("rcf: %02X rif_len: %d\n", trhdr->rcf,wrk_len);
-DPRINTK("hdr_length: %d, frame length: %ld\n",sizeof(struct trh_hdr)-18+hdr_len,
-      ti->current_skb->len-18+hdr_len);
-#endif
-  }
-
-  /* header length including rif is computed above, now move the data
-     and set fields appropriately.     */
-
-  memcpy(dhb,ti->current_skb->data,hdr_len);
-  dhb+=hdr_len;
-  xmit_resp->hdr_length= hdr_len;
-  xmit_resp->frame_length=htons(ti->current_skb->len
-                                -sizeof(struct trh_hdr)+hdr_len);
-
-                  /*  now copy the actual packet data next to hdr */
-  memcpy(dhb,ti->current_skb->data+sizeof(struct trh_hdr),
-             ti->current_skb->len-sizeof(struct trh_hdr));
-
-  *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)
-             =RESP_IN_ASB;
-  dev->tbusy=0;
-  dev_kfree_skb(ti->current_skb,FREE_WRITE);
-  ti->current_skb=NULL;
-  mark_bh(NET_BH);
+	} 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. */
+	for (i=0; i<hdr_len; i++)
+		writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
+	
+	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 */
+	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);
+	
+	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	dev->tbusy=0;
+	dev_kfree_skb(ti->current_skb,FREE_WRITE);
+	ti->current_skb=NULL;
+	mark_bh(NET_BH);
 }
 
-static void tr_rx(struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-
-	struct arb_rec_req *rec_req=(struct arb_rec_req *)ti->arb;
-	struct asb_rec *rec_resp=(struct asb_rec *)ti->asb;
-	struct rec_buf *rbuffer;	
-	struct trllc *llc;
+static void tr_rx(struct device *dev) 
+{
+	int i;
+	struct tok_info *ti=(struct tok_info *) dev->priv;
+	__u32 rbuffer;	
+	__u32 llc;
 	unsigned char *data;
-	unsigned int rbuffer_len,lan_hdr_len;
+	unsigned int rbuffer_len, lan_hdr_len;
+	unsigned int arb_frame_len;
 	struct sk_buff *skb;
-
-	rbuffer=(struct rec_buf *)(ti->sram+ntohs(rec_req->rec_buf_addr));
-
-	if(rec_resp->ret_code!=0xff) DPRINTK("ASB not free !!!\n");
-
-	rec_resp->command=REC_DATA;
-	rec_resp->station_id=rec_req->station_id;
-	rec_resp->rec_buf_addr=rec_req->rec_buf_addr;
-
-	lan_hdr_len=rec_req->lan_hdr_len;
-
-	llc=(struct trllc *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data)+lan_hdr_len);
-
-#if 0
-DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",offsetof(struct rec_buf,data),lan_hdr_len);
-DPRINTK("llc: %p rec_buf_addr: %04X ti->sram: %p\n",llc,ntohs(rec_req->rec_buf_addr),ti->sram);
-DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, ethertype: %04X\n",
-			llc->dsap,llc->ssap,llc->llc,llc->protid[0],llc->protid[1],llc->protid[2],llc->ethertype);
+	
+	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, 
+	       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))), 
+		ti->sram);
+	DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
+		"ethertype: %04X\n",
+		(int)readb(llc + offsetof(struct trllc, dsap)),
+		(int)readb(llc + offsetof(struct trllc, ssap)),
+		(int)readb(llc + offsetof(struct trllc, protid)),
+		(int)readb(llc + offsetof(struct trllc, protid)+1),
+		(int)readb(llc + offsetof(struct trllc, protid)+2),
+		(int)readw(llc + offsetof(struct trllc, ethertype)));
 #endif
-
-	if(llc->llc!=UI_CMD) {
-#ifndef TR_FILTERNONUI		
-		DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",llc->llc);
-#endif
-		rec_resp->ret_code=DATA_LOST;
-		ti->tr_stats.rx_dropped++;
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
-		return;
-	}
-
-#if 0
-	if((llc->dsap!=0xaa) || (llc->ssap!=0xaa)) {
-
-	struct trh_hdr *trhdr=(struct trh_hdr *)((unsigned char *)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",
-			llc->ssap,llc->dsap,trhdr->saddr[0],trhdr->saddr[1],trhdr->saddr[2],trhdr->saddr[3],trhdr->saddr[4],trhdr->saddr[5],
-			trhdr->daddr[0],trhdr->daddr[1],trhdr->daddr[2],trhdr->daddr[3],trhdr->daddr[4],trhdr->daddr[5]);
-	}
+	
+	if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
+#if !TR_FILTERNONUI		
+		DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",
+			(int)readb(llc + offsetof(struct trllc, llc))
+#endif
+			writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+			ti->tr_stats.rx_dropped++;
+			writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+			return;
+			}
+		
+#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",
+				(int)readb(llc + offsetof(struct trllc, ssap)),
+				(int)readb(llc + offsetof(struct trllc, dsap)),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, saddr)),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+1),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+2),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+3),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+4),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+5),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, daddr)),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+1),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+2),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+3),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+4),
+				(int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
+		}
 #endif
-
-
-	if(!(skb=dev_alloc_skb(ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr)))) {
-		DPRINTK("out of memory. frame dropped.\n");	
-		ti->tr_stats.rx_dropped++;
-		rec_resp->ret_code=DATA_LOST;
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
-		return;
+		
+		arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
+		
+		if (!(skb=dev_alloc_skb(arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr)))) {
+			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, arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr));
+		skb->dev=dev;
+		
+		data=skb->data;
+		for (i=0; i<lan_hdr_len; i++) 
+			data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
+		
+		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;
+		
+#if TR_VERBOSE
+		DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
+#endif
+		
+		for (i=0; i<rbuffer_len; i++)
+			data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
+		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);
+			rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+			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", 
+				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);
+		
 	}
 
-	skb_put(skb,ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr));
-	skb->dev=dev;
-
-#if 0
-DPRINTK("Now copying data...\n");
-#endif
-
-
-	data=skb->data;
-	memcpy(data,&(rbuffer->data),lan_hdr_len);
-
-
-	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(rbuffer->buf_len)-lan_hdr_len;
-#if 0
-DPRINTK("rbuffer_len: %d, data: %p\n",rbuffer_len,data);
-#endif
-	memcpy(data,(unsigned char *)(&(rbuffer->data))+lan_hdr_len,rbuffer_len);
-	data+=rbuffer_len;
-
-
-	if(rbuffer->buf_ptr)
-		for(rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2);
-				memcpy(data,&(rbuffer->data),rbuffer_len=ntohs(rbuffer->buf_len)),rbuffer->buf_ptr;
-				data+=rbuffer_len,rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2))
-#if 0
-	DPRINTK("buf_ptr: %d,data =%p\n",ntohs(rbuffer->buf_ptr),data);
-#endif
-
-	rec_resp->ret_code=0;
-
-	*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
-
-	ti->tr_stats.rx_packets++;
-
-	skb->protocol=tr_type_trans(skb,dev);
-	netif_rx(skb);
-
-	return;
-}
-
-static int tok_send_packet(struct sk_buff *skb, struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-
-#if 0
-DPRINTK("tada: sending packet...\n");
-#endif
-
+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=jiffies - dev->trans_start;
-		if(ticks_waited<TX_TIMEOUT)
-			return 1;
-		DPRINTK("Arrg. Transmitter busy for more than 50 msec. Donald resets adapter, but resetting\n \
-the IBM tokenring adapter takes a long time. It might not even help when the\n \
-ring is very busy, so we just wait a little longer and hope for the best.\n");		
+		int ticks_waited;
+		
+		ticks_waited=jiffies - dev->trans_start;
+		if (ticks_waited<TR_BUSY_INTERVAL) return 1;
+		
+		DPRINTK("Arrg. Transmitter busy for more than 50 msec. "
+			"Donald resets adapter, but resetting\n"
+			"the IBM tokenring adapter takes a long time."
+			" It might not even help when the\n"
+			"ring is very busy, so we just wait a little longer "
+			"and hope for the best.\n");		
 		dev->trans_start+=5; /* we fake the transmission start time... */
 		return 1;
 	}
-
+	
 	/* Donald does this, so we do too. */
-
-	if(skb==NULL) {
+	if (skb==NULL) {
 		dev_tint(dev);
 		return 0;
 	}
-
-	if(set_bit(0,(void *)&dev->tbusy)!=0)
+	
+	if (set_bit(0,(void *)&dev->tbusy)!=0)
 		DPRINTK("Transmitter access conflict\n");
 	else {
-		struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
-
-		ti->current_skb=skb; /* save skb. We will need it when the adapter
-                                  asks for the data */
-		xmit->command=XMIT_UI_FRAME;
-		xmit->station_id=ti->exsap_station_id;
-		*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
+		/* Save skb; we'll need it when the adapter asks for the data */
+		ti->current_skb=skb; 
+		writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
+		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;
 }	
 
 /* tok_get_stats():  Basically a scaffold routine which will return
-         the address of the tr_statistics structure associated with
-         this device -- the tr.... structure is a ethnet look-alike
-         so at least for this iteration may suffice.   */
+   the address of the tr_statistics structure associated with
+   this device -- the tr.... structure is a ethnet look-alike
+   so at least for this iteration may suffice.   */
 
 static struct enet_statistics * tok_get_stats(struct device *dev) {
 
-  struct tok_info *toki;
-  toki=(struct tok_info *) dev->priv;
-  return (struct enet_statistics *) &toki->tr_stats;
+	struct tok_info *toki;
+	toki=(struct tok_info *) dev->priv;
+	return (struct enet_statistics *) &toki->tr_stats;
 }
 
 #ifdef MODULE
+
+
 static char devicename[9] = { 0, };
 static struct device dev_ibmtr = {
 	devicename, /* device name is inserted by linux/drivers/net/net_init.c */
@@ -1348,10 +1446,11 @@
 
 int init_module(void)
 {
-	if (io == 0)
+	if (io == 0) 
 		printk("ibmtr: You should not use auto-probing with insmod!\n");
 	dev_ibmtr.base_addr = io;
 	dev_ibmtr.irq       = 0;
+	
 	if (register_netdev(&dev_ibmtr) != 0) {
 		printk("ibmtr: register_netdev() returned non-zero.\n");
 		return -EIO;
@@ -1359,11 +1458,10 @@
 	return 0;
 }
 
-void
-cleanup_module(void)
+void cleanup_module(void)
 {
 	unregister_netdev(&dev_ibmtr);
-
+	
 	/* If we don't do this, we can't re-insmod it later. */
 	free_irq(dev_ibmtr.irq, NULL);
 	irq2dev_map[dev_ibmtr.irq] = NULL;
diff -u --recursive --new-file v1.3.77/linux/drivers/net/ibmtr.h linux/drivers/net/ibmtr.h
--- v1.3.77/linux/drivers/net/ibmtr.h	Sun Mar 10 09:49:50 1996
+++ linux/drivers/net/ibmtr.h	Sun Mar 24 12:09:36 1996
@@ -1,23 +1,18 @@
 /* Definitions for an IBM Token Ring card. */
 /* This file is distributed under the GNU GPL   */
 
-#define TR_RETRY_INTERVAL 500
+/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
+
+#define TR_RETRY_INTERVAL (5*HZ) /* 500 on PC = 5 s */
+#define TR_RESET_INTERVAL (HZ/20) /* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */
+
 #define TR_ISA 1
 #define TR_MCA 2
 #define TR_ISAPNP 3
 #define NOTOK 0
 #define TOKDEBUG 1
 
-/* Mike Eckhoff -- 96/02/08 */
-/* This defines the minimum timeout. If a transmission takes */
-/* longer then TX_TIMEOUT to send, we will wait and retry. */
-/* On large networks, this value may need to be increased. */
-/* We will start at .2s because that is what most drivers seem to be doing */
-/* now and the original value of .05s was not nearly enough for large nets. */
-
-#define TX_TIMEOUT (HZ/5)
-
-
 #ifndef IBMTR_SHARED_RAM_BASE
 #define IBMTR_SHARED_RAM_BASE 0xD0
 #define IBMTR_SHARED_RAM_SIZE 0x10
@@ -168,105 +163,68 @@
 #define ACA_RW 0x00
 
 #ifdef ENABLE_PAGING
-#define SET_PAGE(x) (*(unsigned char *) \
-                         (ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)\
-                                                = (x>>8)&ti.page_mask)
+#define SET_PAGE(x) (writeb(((x>>8)&ti.page_mask), \
+  ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN))
 #else
 #define SET_PAGE(x)
 #endif
 
 typedef enum { IN_PROGRESS, SUCCES, FAILURE, CLOSED } open_state;
 
-struct tok_info {
-        unsigned char irq;
-        unsigned char *mmio;
-        unsigned char hw_address[32];
-        unsigned char adapter_type;
-        unsigned char data_rate;
-        unsigned char token_release;
-        unsigned char avail_shared_ram;
-        unsigned char shared_ram_paging;
-        unsigned char dhb_size4mb;
-        unsigned char dhb_size16mb;
-/* Additions by David Morris       */
-        unsigned char do_tok_int;
+/* do_tok_int possible values */
 #define FIRST_INT 1
 #define NOT_FIRST 2
-        struct wait_queue *wait_for_tok_int;
-        struct wait_queue *wait_for_reset;
-        unsigned char sram_base;
-/* Additions by Peter De Schrijver */
-        unsigned char page_mask;     /* mask to select RAM page to Map*/
-        unsigned char mapped_ram_size;  /* size of RAM page */
-        unsigned char *sram; /* Shared memory base address */
-        unsigned char *init_srb;  /* Initial System Request Block address */
-        unsigned char *srb;  /* System Request Block address */
-        unsigned char *ssb;  /* System Status Block address */
-        unsigned char *arb;  /* Adapter Request Block address */
-        unsigned char *asb;  /* Adapter Status Block address */
-        unsigned short exsap_station_id;
-        unsigned short global_int_enable;
-        struct sk_buff *current_skb;
-        struct tr_statistics tr_stats;
-        unsigned char auto_ringspeedsave;
-	open_state open_status;
-	
-};
 
-struct srb_init_response {
-        unsigned char command;
-        unsigned char init_status;
-	unsigned char init_status_2;
-        unsigned char reserved[3];
-        unsigned short bring_up_code;
-        unsigned short encoded_address;
-        unsigned short level_address;
-        unsigned short adapter_address;
-        unsigned short parms_address;
-        unsigned short mac_address;
-};
-
-#define DIR_OPEN_ADAPTER 0x03
-
-struct dir_open_adapter {
-        unsigned char command;
-        char reserved[7];
-        unsigned short open_options;
-        unsigned char node_address[6];
-        unsigned char group_address[4];
-        unsigned char funct_address[4];
-        unsigned short num_rcv_buf;
-        unsigned short rcv_buf_len;
-        unsigned short dhb_length;
-        unsigned char num_dhb;
-        char reserved2;
-        unsigned char dlc_max_sap;
-        unsigned char dlc_max_sta;
-        unsigned char dlc_max_gsap;
-        unsigned char dlc_max_gmem;
-        unsigned char dlc_t1_tick_1;
-        unsigned char dlc_t2_tick_1;
-        unsigned char dlc_ti_tick_1;
-        unsigned char dlc_t1_tick_2;
-        unsigned char dlc_t2_tick_2;
-        unsigned char dlc_ti_tick_2;
-        unsigned char product_id[18];
+struct tok_info {
+	unsigned char irq;
+	__u32 mmio;
+	unsigned char hw_address[32];
+	unsigned char adapter_type;
+	unsigned char data_rate;
+	unsigned char token_release;
+	unsigned char avail_shared_ram;
+	unsigned char shared_ram_paging;
+	unsigned char dhb_size4mb;
+	unsigned char dhb_size16mb;
+	/* Additions by David Morris       */
+	unsigned char do_tok_int;
+	struct wait_queue *wait_for_tok_int;
+	struct wait_queue *wait_for_reset;
+	unsigned char sram_base;
+	/* Additions by Peter De Schrijver */
+	unsigned char page_mask;          /* mask to select RAM page to Map*/
+	unsigned char mapped_ram_size;    /* size of RAM page */
+	__u32 sram;                       /* Shared memory base address */
+	__u32 init_srb;                   /* Initial System Request Block address */
+	__u32 srb;                        /* System Request Block address */
+	__u32 ssb;                        /* System Status Block address */
+	__u32 arb;                        /* Adapter Request Block address */
+	__u32 asb;                        /* Adapter Status Block address */
+	unsigned short exsap_station_id;
+	unsigned short global_int_enable;
+	struct sk_buff *current_skb;
+	struct tr_statistics tr_stats;
+	unsigned char auto_ringspeedsave;
+	open_state open_status;
 };
 
-struct srb_open_response {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2[3];
-        unsigned short error_code;
-        unsigned short asb_addr;
-        unsigned short srb_addr;
-        unsigned short arb_addr;
-        unsigned short ssb_addr;
-};
+/* token ring adapter commands */
+#define DIR_INTERRUPT 		0x00 /* struct srb_interrupt */
+#define DIR_MOD_OPEN_PARAMS 	0x01
+#define DIR_OPEN_ADAPTER 	0x03 /* struct dir_open_adapter */
+#define DIR_CLOSE_ADAPTER   	0x04
+#define DIR_SET_GRP_ADDR    	0x06
+#define DIR_SET_FUNC_ADDR   	0x07
+#define DIR_READ_LOG 		0x08 /* struct srb_read_log */
+#define DLC_OPEN_SAP 		0x15 /* struct dlc_open_sap */
+#define DLC_CLOSE_SAP       	0x16
+#define DATA_LOST 		0x20 /* struct asb_rec */
+#define REC_DATA 		0x81 /* struct arb_rec_req */
+#define XMIT_DATA_REQ 		0x82 /* struct arb_xmit_req */
+#define DLC_STATUS 		0x83 /* struct arb_dlc_status */
+#define RING_STAT_CHANGE    	0x84 /* struct dlc_open_sap ??? */
 
 /* DIR_OPEN_ADAPTER options */
-
 #define OPEN_PASS_BCON_MAC 0x0100
 #define NUM_RCV_BUF 16
 #define RCV_BUF_LEN 136
@@ -275,164 +233,197 @@
 #define DLC_MAX_SAP 2
 #define DLC_MAX_STA 1
 
-#define DLC_OPEN_SAP 0x15
-
-struct dlc_open_sap {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2;
-        unsigned short station_id;
-        unsigned char timer_t1;
-        unsigned char timer_t2;
-        unsigned char timer_ti;
-        unsigned char maxout;
-        unsigned char maxin;
-        unsigned char maxout_incr;
-        unsigned char max_retry_count;
-        unsigned char gsap_max_mem;
-        unsigned short max_i_field;
-        unsigned char sap_value;
-        unsigned char sap_options;
-        unsigned char station_count;
-        unsigned char sap_gsap_mem;
-        unsigned char gsap[0];
-};
-
 /* DLC_OPEN_SAP options */
-
 #define MAX_I_FIELD 0x0088
 #define SAP_OPEN_IND_SAP 0x04
 #define SAP_OPEN_PRIORITY 0x20
 #define SAP_OPEN_STATION_CNT 0x1
-
-#define XMIT_DIR_FRAME 0x0a
+#define XMIT_DIR_FRAME 0x0A
 #define XMIT_UI_FRAME  0x0d
 #define XMIT_XID_CMD   0x0e
 #define XMIT_TEST_CMD  0x11
 
+/* srb close return code */
+#define SIGNAL_LOSS  0x8000
+#define HARD_ERROR   0x4000
+#define XMIT_BEACON  0x1000
+#define LOBE_FAULT   0x0800
+#define AUTO_REMOVAL 0x0400
+#define REMOVE_RECV  0x0100
+#define LOG_OVERFLOW 0x0080
+#define RING_RECOVER 0x0020
+
+struct srb_init_response {
+	unsigned char command;
+	unsigned char init_status;
+	unsigned char init_status_2;
+	unsigned char reserved[3];
+	__u16 bring_up_code;
+	__u16 encoded_address;
+	__u16 level_address;
+	__u16 adapter_address;
+	__u16 parms_address;
+	__u16 mac_address;
+};
+
+struct dir_open_adapter {
+	unsigned char command;
+	char reserved[7];
+	__u16 open_options;
+	unsigned char node_address[6];
+	unsigned char group_address[4];
+	unsigned char funct_address[4];
+	__u16 num_rcv_buf;
+	__u16 rcv_buf_len;
+	__u16 dhb_length;
+	unsigned char num_dhb;
+	char reserved2;
+	unsigned char dlc_max_sap;
+	unsigned char dlc_max_sta;
+	unsigned char dlc_max_gsap;
+	unsigned char dlc_max_gmem;
+	unsigned char dlc_t1_tick_1;
+	unsigned char dlc_t2_tick_1;
+	unsigned char dlc_ti_tick_1;
+	unsigned char dlc_t1_tick_2;
+	unsigned char dlc_t2_tick_2;
+	unsigned char dlc_ti_tick_2;
+	unsigned char product_id[18];
+};
+
+struct srb_open_response {
+	unsigned char command;
+	unsigned char reserved1;
+	unsigned char ret_code;
+	unsigned char reserved2[3];
+	__u16 error_code;
+	__u16 asb_addr;
+	__u16 srb_addr;
+	__u16 arb_addr;
+	__u16 ssb_addr;
+};
+
+struct dlc_open_sap {
+	unsigned char command;
+	unsigned char reserved1;
+	unsigned char ret_code;
+	unsigned char reserved2;
+	__u16 station_id;
+	unsigned char timer_t1;
+	unsigned char timer_t2;
+	unsigned char timer_ti;
+	unsigned char maxout;
+	unsigned char maxin;
+	unsigned char maxout_incr;
+	unsigned char max_retry_count;
+	unsigned char gsap_max_mem;
+	__u16 max_i_field;
+	unsigned char sap_value;
+	unsigned char sap_options;
+	unsigned char station_count;
+	unsigned char sap_gsap_mem;
+	unsigned char gsap[0];
+};
+
 struct srb_xmit {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char ret_code;
-        unsigned char reserved1;
-        unsigned short station_id;
+	unsigned char command;
+	unsigned char cmd_corr;
+	unsigned char ret_code;
+	unsigned char reserved1;
+	__u16 station_id;
 };
 
-#define DIR_INTERRUPT 0x00
 struct srb_interrupt {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char ret_code;
+	unsigned char command;
+	unsigned char cmd_corr;
+	unsigned char ret_code;
 };
 
-#define DIR_READ_LOG 0x08
 struct srb_read_log {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2;
-        unsigned char line_errors;
-        unsigned char internal_errors;
-        unsigned char burst_errors;
-        unsigned char A_C_errors;
-        unsigned char abort_delimiters;
-        unsigned char reserved3;
-        unsigned char lost_frames;
-        unsigned char recv_congest_count;
-        unsigned char frame_copied_errors;
-        unsigned char frequency_errors;
-        unsigned char token_errors;
+	unsigned char command;
+	unsigned char reserved1;
+	unsigned char ret_code;
+	unsigned char reserved2;
+	unsigned char line_errors;
+	unsigned char internal_errors;
+	unsigned char burst_errors;
+	unsigned char A_C_errors;
+	unsigned char abort_delimiters;
+	unsigned char reserved3;
+	unsigned char lost_frames;
+	unsigned char recv_congest_count;
+	unsigned char frame_copied_errors;
+	unsigned char frequency_errors;
+	unsigned char token_errors;
 };
 
 struct asb_xmit_resp {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char ret_code;
-        unsigned char reserved;
-        unsigned short station_id;
-        unsigned short frame_length;
-        unsigned char hdr_length;
-        unsigned        char rsap_value;
+	unsigned char command;
+	unsigned char cmd_corr;
+	unsigned char ret_code;
+	unsigned char reserved;
+	__u16 station_id;
+	__u16 frame_length;
+	unsigned char hdr_length;
+	unsigned char rsap_value;
 };
 
-#define XMIT_DATA_REQ 0x82
 struct arb_xmit_req {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char reserved1[2];
-        unsigned short station_id;
-        unsigned short dhb_address;
+	unsigned char command;
+	unsigned char cmd_corr;
+	unsigned char reserved1[2];
+	__u16 station_id;
+	__u16 dhb_address;
 };
 
-#define REC_DATA 0x81
 struct arb_rec_req {
-        unsigned char command;
-        unsigned char reserved1[3];
-        unsigned short station_id;
-        unsigned short rec_buf_addr;
-        unsigned char lan_hdr_len;
-        unsigned char dlc_hdr_len;
-        unsigned short frame_len;
-        unsigned char msg_type;
+	unsigned char command;
+	unsigned char reserved1[3];
+	__u16 station_id;
+	__u16 rec_buf_addr;
+	unsigned char lan_hdr_len;
+	unsigned char dlc_hdr_len;
+	__u16 frame_len;
+	unsigned char msg_type;
 };
 
-#define DATA_LOST 0x20
 struct asb_rec {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2;
-        unsigned short station_id;
-        unsigned short rec_buf_addr;
+	unsigned char command;
+	unsigned char reserved1;
+	unsigned char ret_code;
+	unsigned char reserved2;
+	__u16 station_id;
+	__u16 rec_buf_addr;
 };
 
 struct rec_buf {
-        unsigned char reserved1[2];
-        unsigned short buf_ptr;
-        unsigned char reserved2;
-        unsigned short buf_len;
-        unsigned char data[0];
+	unsigned char reserved1[2];
+	__u16 buf_ptr;
+	unsigned char reserved2;
+	__u16 buf_len;
+	unsigned char data[0];
 };
 
-#define DLC_STATUS          0x83
 struct arb_dlc_status {
-        unsigned char command;
-        unsigned char reserved1[3];
-        unsigned short station_id;
-        unsigned short status;
-        unsigned char frmr_data[5];
-        unsigned char access_prio;
-        unsigned char rem_addr[TR_ALEN];
-        unsigned        char rsap_value;
+	unsigned char command;
+	unsigned char reserved1[3];
+	__u16 station_id;
+	__u16 status;
+	unsigned char frmr_data[5];
+	unsigned char access_prio;
+	unsigned char rem_addr[TR_ALEN];
+	unsigned char rsap_value;
 };
 
-#define RING_STAT_CHANGE    0x84
 struct arb_ring_stat_change {
-        unsigned char command;
-        unsigned char reserved1[5];
-        unsigned short ring_status;
+	unsigned char command;
+	unsigned char reserved1[5];
+	__u16 ring_status;
 };
 
-#define DIR_CLOSE_ADAPTER   0x04
 struct srb_close_adapter {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
+	unsigned char command;
+	unsigned char reserved1;
+	unsigned char ret_code;
 };
-
-#define DIR_MOD_OPEN_PARAMS 0x01
-#define DIR_SET_GRP_ADDR    0x06
-#define DIR_SET_FUNC_ADDR   0x07
-#define DLC_CLOSE_SAP       0x16
-
-
-#define SIGNAL_LOSS  0x8000
-#define HARD_ERROR   0x4000
-#define XMIT_BEACON  0x1000
-#define LOBE_FAULT   0x0800
-#define AUTO_REMOVAL 0x0400
-#define REMOVE_RECV  0x0100
-#define LOG_OVERFLOW 0x0080
-#define RING_RECOVER 0x0020
 
diff -u --recursive --new-file v1.3.77/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- v1.3.77/linux/drivers/net/loopback.c	Wed Feb 14 14:37:10 1996
+++ linux/drivers/net/loopback.c	Mon Mar 25 08:58:21 1996
@@ -34,8 +34,6 @@
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/in.h>
-#include <linux/if_ether.h>	/* For the statistics structure. */
-#include <linux/if_arp.h>	/* For ARPHRD_ETHER */
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -46,6 +44,8 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
+#include <linux/if_ether.h>	/* For the statistics structure. */
+#include <linux/if_arp.h>	/* For ARPHRD_ETHER */
 
 #define LOOPBACK_MTU (PAGE_SIZE*7/8)
 
@@ -72,7 +72,7 @@
 	  	skb=skb_clone(skb, GFP_ATOMIC);		/* Clone the buffer */
 	  	if(skb==NULL)
 	  		return 1;
-	  	dev_kfree_skb(skb2, FREE_READ);
+	  	dev_kfree_skb(skb2, FREE_WRITE);
   		unlock=0;
 	}
 	else if(skb->sk)
@@ -81,7 +81,7 @@
 	  	 *	Packet sent but looped back around. Cease to charge
 	  	 *	the socket for the frame.
 	  	 */
-	  	skb->sk->wmem_alloc-=skb->truesize;
+		atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
 	  	skb->sk->write_space(skb->sk);
 	}
 
diff -u --recursive --new-file v1.3.77/linux/drivers/net/net_init.c linux/drivers/net/net_init.c
--- v1.3.77/linux/drivers/net/net_init.c	Wed Feb  7 15:11:25 1996
+++ linux/drivers/net/net_init.c	Mon Mar 25 08:58:21 1996
@@ -29,11 +29,11 @@
 #include <linux/fs.h>
 #include <linux/malloc.h>
 #include <linux/if_ether.h>
-#include <linux/if_arp.h>
 #include <linux/string.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/trdevice.h>
+#include <linux/if_arp.h>
 #ifdef CONFIG_NET_ALIAS
 #include <linux/net_alias.h>
 #endif
diff -u --recursive --new-file v1.3.77/linux/drivers/net/new_tunnel.c linux/drivers/net/new_tunnel.c
--- v1.3.77/linux/drivers/net/new_tunnel.c	Wed Mar 13 10:09:18 1996
+++ linux/drivers/net/new_tunnel.c	Mon Mar 25 08:58:21 1996
@@ -273,8 +273,9 @@
 	/*
 	 *	Push down and install the IPIP header.
 	 */
-	iph = skb->h.iph;
-	iph->version	= 	4;
+	 
+	iph 			=	skb->h.iph;
+	iph->version		= 	4;
 	iph->tos		=	skb->ip_hdr->tos;
 	iph->ttl		=	skb->ip_hdr->ttl;
 	iph->frag_off		=	0;
@@ -285,8 +286,8 @@
 	iph->tot_len		=	htons(skb->len);
 	iph->id			=	htons(ip_id_count++);	/* Race condition here? */
 	ip_send_check(iph);
-	skb->ip_hdr = skb->h.iph;
-
+	skb->ip_hdr 		= skb->h.iph;
+	skb->protocol		=	htons(ETH_P_IP);
 #ifdef TUNNEL_DEBUG
 	printk("New IP Header....\n");
 	print_ip(iph);
@@ -317,8 +318,7 @@
 	return 0;
 }
 
-static struct enet_statistics *
-tunnel_get_stats(struct device *dev)
+static struct enet_statistics *tunnel_get_stats(struct device *dev)
 {
 	return((struct enet_statistics*) dev->priv);
 }
@@ -336,7 +336,7 @@
 	static int tun_msg=0;
 	if(!tun_msg)
 	{
-		printk ( KERN_INFO "tunnel: version v0.2b\n" );
+		printk ( KERN_INFO "tunnel: version v0.2b2\n" );
 		tun_msg=1;
 	}
 
@@ -393,11 +393,13 @@
 	return 0;
 }
 
-static struct device dev_tunnel = {
+static struct device dev_tunnel = 
+{
 	"tunl0\0   ", 
 	0, 0, 0, 0,
  	0x0, 0,
- 	0, 0, 0, NULL, tunnel_probe };
+ 	0, 0, 0, NULL, tunnel_probe 
+ };
 
 int init_module(void)
 {
diff -u --recursive --new-file v1.3.77/linux/drivers/net/sdla.c linux/drivers/net/sdla.c
--- v1.3.77/linux/drivers/net/sdla.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/sdla.c	Mon Mar 25 10:06:28 1996
@@ -0,0 +1,1639 @@
+/*
+ * SDLA      An implementation of a driver for the Sangoma S502/S508 series
+ *           multi-protocol PC interface card.  Initial offering is with 
+ *           the DLCI driver, providing Frame Relay support for linux.
+ *
+ *           Global definitions for the Frame relay interface.
+ *
+ * Version:  @(#)sdla.c   0.10   23 Mar 1996
+ *
+ * Credits:  Sangoma Technologies, for the use of 2 cards for an extended
+ *                                 period of time.
+ *           David Mandelstam <dm@sangoma.com> for getting me started on 
+ *                            this project, and incentive to complete it.
+ *           Gene Kozen <74604.152@compuserve.com> for providing me with
+ *                      important information about the cards.
+ *
+ * Author:   Mike McLagan <mike.mclagan@linux.org>
+ *
+ *           This program is free software; you can redistribute it and/or
+ *           modify it under the terms of the GNU General Public License
+ *           as published by the Free Software Foundation; either version
+ *           2 of the License, or (at your option) any later version.
+ */
+
+#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/timer.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/if_frad.h>
+
+#include <linux/sdla.h>
+
+static const char* version = "SDLA driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
+
+static const char* devname = "sdla";
+
+static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
+
+static unsigned int valid_mem[]  = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 
+                                    0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
+                                    0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
+                                    0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
+                                    0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; 
+
+/*********************************************************
+ *
+ * these are the core routines that access the card itself 
+ *
+ *********************************************************/
+
+#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
+
+static void sdla_read(struct device *dev, int addr, void *buf, short len)
+{
+   unsigned long flags;
+   char          *temp, *base;
+   int           offset, bytes;
+
+   temp = buf;
+   while(len)
+   {
+      offset = addr & 0x1FFF;
+      if (offset + len > 0x2000)
+         bytes = 0x2000 - offset;
+      else
+         bytes = len;
+
+      base = (void *) dev->mem_start;
+      base += offset;
+
+      save_flags(flags);
+      cli();
+      SDLA_WINDOW(dev, addr);
+      memcpy(temp, base, bytes);
+      restore_flags(flags);
+
+      addr += bytes;
+      temp += bytes;
+      len  -= bytes;
+   }  
+}
+
+static void sdla_write(struct device *dev, int addr, void *buf, short len)
+{
+   unsigned long flags;
+   char          *temp, *base;
+   int           offset, bytes;
+
+   temp = buf;
+   while(len)
+   {
+      offset = addr & 0x1FFF;
+      if (offset + len > 0x2000)
+         bytes = 0x2000 - offset;
+      else
+         bytes = len;
+
+      base = (void *) dev->mem_start;
+      base += offset;
+
+      save_flags(flags);
+      cli();
+      SDLA_WINDOW(dev, addr);
+      memcpy(base, temp, bytes);
+      restore_flags(flags);
+
+      addr += bytes;
+      temp += bytes;
+      len  -= bytes;
+   }
+}
+
+static void sdla_clear(struct device *dev)
+{
+   unsigned long flags;
+   char          *base;
+   int           offset, len, addr, bytes;
+
+   len = 65536;
+   addr = 0;
+   while(len)
+   {
+      offset = addr & 0x1FFF;
+      if (offset + len > 0x2000)
+         bytes = offset + len - 0x2000;
+      else
+         bytes = len;
+
+      base = (void *) dev->mem_start;
+      base += offset;
+
+      save_flags(flags);
+      cli();
+      SDLA_WINDOW(dev, addr);
+      memset(base, 0, bytes);
+      restore_flags(flags);
+
+      addr += bytes;
+      len  -= bytes;
+   }
+}
+
+static char sdla_byte(struct device *dev, int addr)
+{
+   unsigned long flags;
+   char          byte, *temp;
+
+   temp = (void *) dev->mem_start;
+   temp += addr & 0x1FFF;
+
+   save_flags(flags);
+   cli();
+   SDLA_WINDOW(dev, addr);
+   byte = *temp;
+   restore_flags(flags);
+
+   return(byte);
+}
+
+void sdla_stop(struct device *dev)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = SDLA_HALT;
+         break;
+      case SDLA_S502E:
+         outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
+         outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = SDLA_S502E_ENABLE;
+         break;
+      case SDLA_S507:
+         flp->state &= ~SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+      case SDLA_S508:
+         flp->state &= ~SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+   }
+}
+
+void sdla_start(struct device *dev)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
+         outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = SDLA_S502A_START;
+         break;
+      case SDLA_S502E:
+         outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
+         outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = 0;
+         break;
+      case SDLA_S507:
+         flp->state |= SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+      case SDLA_S508:
+         flp->state |= SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+   }
+}
+
+/****************************************************
+ *
+ * this is used for the S502A/E cards to determine
+ * the speed of the onboard CPU.  Calibration is
+ * necessary for the Frame Relay code uploaded 
+ * later.  Incorrect results cause timing problems
+ * with link checks & status messages
+ *
+ ***************************************************/
+
+int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+{
+   unsigned long start, done, now;
+   char          resp, *temp;
+
+   start = now = jiffies;
+   done = jiffies + jiffs;
+
+   temp = (void *)dev->mem_start;
+   temp += z80_addr & 0x1FFF;
+
+   resp = ~resp1;
+   while ((jiffies < done) && (resp != resp1) && (!resp2 || (resp != resp2)))
+   {
+      if (jiffies != now)
+      {
+         SDLA_WINDOW(dev, z80_addr);
+         now = jiffies;
+         resp = *temp;
+      }
+   }
+   return(jiffies < done ? jiffies - start : -1);
+}
+
+/* constants for Z80 CPU speed */
+#define Z80_READY 		'1'	/* Z80 is ready to begin */
+#define LOADER_READY 		'2'	/* driver is ready to begin */
+#define Z80_SCC_OK 		'3'	/* SCC is on board */
+#define Z80_SCC_BAD	 	'4'	/* SCC was not found */
+
+static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr)
+{
+   int  jiffs;
+   char data;
+
+   sdla_start(dev);
+   if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
+      return(-EIO);
+
+   data = LOADER_READY;
+   sdla_write(dev, 0, &data, 1);
+
+   if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
+      return(-EIO);
+
+   sdla_stop(dev);
+   sdla_read(dev, 0, &data, 1);
+
+   if (data == Z80_SCC_BAD)
+      return(-EIO);
+
+   if (data != Z80_SCC_OK)
+      return(-EINVAL);
+
+   if (jiffs < 165)
+      ifr->ifr_mtu = SDLA_CPU_16M;
+   else
+      if (jiffs < 220)
+         ifr->ifr_mtu = SDLA_CPU_10M;
+      else
+         if (jiffs < 258)
+            ifr->ifr_mtu = SDLA_CPU_8M;
+         else
+            if (jiffs < 357)
+               ifr->ifr_mtu = SDLA_CPU_7M;
+            else
+               if (jiffs < 467)
+                  ifr->ifr_mtu = SDLA_CPU_5M;
+               else
+                  ifr->ifr_mtu = SDLA_CPU_3M;
+ 
+   return(0);
+}
+
+/************************************************
+ *
+ *  Direct interaction with the Frame Relay code 
+ *  starts here.
+ *
+ ************************************************/
+
+struct _dlci_stat {
+   short dlci		__attribute__((packed));
+   char  flags		__attribute__((packed));
+};
+
+struct _frad_stat {
+   char    flags;
+   struct _dlci_stat dlcis[SDLA_MAX_DLCI];
+};
+
+static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data) 
+{
+   struct _dlci_stat *pstatus;
+   short             *pdlci;
+   int               i;
+   char              *state;
+
+   switch (ret)
+   {
+      case SDLA_RET_MODEM:
+         state = data;
+         if (*state & SDLA_MODEM_DCD_LOW)
+            printk(KERN_NOTICE "%s: Modem DCD unexpectedly low!\n", dev->name);
+         if (*state & SDLA_MODEM_CTS_LOW)
+            printk(KERN_NOTICE "%s: Modem CTS unexpectedly low!\n", dev->name);
+/* I should probably do something about this! */
+         break;
+
+      case SDLA_RET_CHANNEL_OFF:
+         printk(KERN_NOTICE "%s: Channel became inoperative!\n", dev->name);
+/* same here */
+         break;
+
+      case SDLA_RET_CHANNEL_ON:
+         printk(KERN_NOTICE "%s: Channel became operative!\n", dev->name);
+/* same here */
+         break;
+
+      case SDLA_RET_DLCI_STATUS:
+         printk(KERN_NOTICE "%s: Status change reported by Access Node.\n", dev->name);
+         len /= sizeof(struct _dlci_stat);
+         for(pstatus = data, i=0;i < len;i++,pstatus++)
+         {
+            if (pstatus->flags & SDLA_DLCI_NEW)
+               state = "new";
+            else
+               if (pstatus->flags & SDLA_DLCI_DELETED)
+                  state = "deleted";
+               else
+                  if (pstatus->flags & SDLA_DLCI_ACTIVE)
+                     state = "active";
+                  else
+                     state = "unknown status";
+ 
+            printk(KERN_NOTICE "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state);
+/* same here */
+         }
+         break;
+
+      case SDLA_RET_DLCI_UNKNOWN:
+         printk(KERN_DEBUG "%s: Received unknown DLCIs:", dev->name);
+         len /= 2;
+         for(pdlci = data,i=0;i < len;i++,pdlci++)
+            printk(" %i", *pdlci);
+         printk("\n");
+         break;
+
+      case SDLA_RET_TIMEOUT:
+         printk(KERN_ERR "%s: Command timed out!\n", dev->name);
+         break;
+
+      default: 
+         /*
+          * Further processing could be done here 
+          * printk(KERN_DEBUG "%s: Unhandled return code 0x%2.2X\n", dev->name, ret);
+          *
+          */
+   }
+}
+
+static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, 
+                        void *inbuf, short inlen, void *outbuf, short *outlen)
+{
+   static struct _frad_stat status;
+   struct frad_local        *flp;
+   struct sdla_cmd          *cmd_buf;
+   unsigned long            pflags;
+   int                      jiffs, ret, waiting, len;
+   long                     temp, window;
+
+   flp = dev->priv;
+
+   window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
+   temp = (int) dev->mem_start;
+   temp += window & 0x1FFF;
+   cmd_buf = (struct sdla_cmd *)temp;
+   ret = 0;
+   jiffs = jiffies + HZ / 2;  /* 1/2 second timeout */
+   save_flags(pflags);
+   cli();
+   SDLA_WINDOW(dev, window);
+   cmd_buf->cmd = cmd;
+   cmd_buf->dlci = dlci;
+   cmd_buf->flags = flags;
+
+   if (inbuf)
+      memcpy(cmd_buf->data, inbuf, inlen);
+
+   cmd_buf->length = inlen;
+
+   cmd_buf->opp_flag = 1;
+   restore_flags(pflags);
+
+   waiting = 1;
+   len = 0;
+   while (waiting && (jiffies <= jiffs))
+   {
+      if (waiting++ % 4) 
+      {
+         save_flags(pflags);
+         cli();
+         SDLA_WINDOW(dev, window);
+         waiting = ((volatile)(cmd_buf->opp_flag));
+         restore_flags(pflags);
+      }
+   }
+   
+   if (!waiting)
+   {
+      save_flags(pflags);
+      cli();
+      SDLA_WINDOW(dev, window);
+      ret = cmd_buf->retval;
+      len = cmd_buf->length;
+      if (outbuf && len)
+      {
+         *outlen = *outlen >= len ? len : *outlen;
+         memcpy(outbuf, cmd_buf->data, *outlen);
+      }
+      if (ret)
+         memcpy(&status, cmd_buf->data, len);
+      restore_flags(pflags);
+   }
+   else
+      ret = SDLA_RET_TIMEOUT;
+
+   if (ret != SDLA_RET_OK)
+      sdla_errors(dev, cmd, dlci, ret, len, &status);
+
+   return(ret);
+}
+
+/***********************************************
+ *
+ * these functions are called by the DLCI driver 
+ *
+ ***********************************************/
+
+static int sdla_reconfig(struct device *dev);
+
+int sdla_activate(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-ENODEV);
+
+   flp->dlci[i] = abs(flp->dlci[i]);
+
+   if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+      sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_deactivate(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   flp->dlci[i] = -abs(flp->dlci[i]);
+
+   if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+      sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_assoc(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   if (master->type != ARPHRD_DLCI)
+      return(-EINVAL);
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+   {
+      if (!flp->master[i])
+         break;
+      if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
+         return(-EADDRINUSE);
+   } 
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-EMLINK);  /* #### Alan: Comments on this ?? */
+
+   MOD_INC_USE_COUNT;
+
+   flp->master[i] = master;
+   flp->dlci[i] = -*(short *)(master->dev_addr);
+   master->mtu = slave->mtu;
+
+   if (slave->start)
+      if (flp->config.station == FRAD_STATION_CPE)
+         sdla_reconfig(slave);
+      else
+         sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_deassoc(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-ENODEV);
+
+   flp->master[i] = NULL;
+   flp->dlci[i] = 0;
+
+   MOD_DEC_USE_COUNT;
+
+   if (slave->start)
+      if (flp->config.station == FRAD_STATION_CPE)
+         sdla_reconfig(slave);
+      else
+         sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_dlci_conf(struct device *slave, struct device *master, int get)
+{
+   struct frad_local *flp;
+   struct frad_local *dlp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-ENODEV);
+
+   dlp = master->priv;
+   if (slave->start)
+      sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, flp->dlci[i], 0,  
+                  &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+/**************************
+ *
+ * now for the Linux driver 
+ *
+ **************************/
+
+static int sdla_transmit(struct sk_buff *skb, struct device *dev)
+{
+   struct frad_local *flp;
+   int               ret, addr;
+   short             size;
+   unsigned long     flags;
+   struct buf_entry  *pbuf;
+
+   flp = dev->priv;
+   ret = 0;
+
+   if (dev->tbusy) 
+      return(1);
+
+   if (skb == NULL) 
+      return(0);
+
+   if (set_bit(0, (void*)&dev->tbusy) != 0)
+      printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
+   else
+   {
+      switch (flp->type)
+      {
+         case SDLA_S502A:
+         case SDLA_S502E:
+            ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
+            break;
+
+         case SDLA_S508:
+            size = sizeof(addr);
+            ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
+            if (ret == SDLA_RET_OK)
+            {
+               save_flags(flags); 
+               cli();
+               SDLA_WINDOW(dev, addr);
+               pbuf = (void *)(((int) dev->mem_start) + (addr & 0x1FFF));
+
+               sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
+
+               SDLA_WINDOW(dev, addr);
+               pbuf->opp_flag = 1;
+               restore_flags(flags);
+            }
+            break;
+      }
+ 
+      switch (ret)
+      {
+         case SDLA_RET_OK:
+            flp->stats.tx_packets++;
+            ret = 0;
+            break;
+ 
+         default:
+            flp->stats.tx_errors++;
+            ret = 1;
+      }
+
+      /* per Alan Cox, we can drop the packet on the floor if it doesn't go */
+      dev_kfree_skb(skb, FREE_WRITE);
+
+      dev->tbusy = 0;
+   }
+   return(ret);
+}
+
+static void sdla_receive(struct device *dev)
+{
+   struct device     *master;
+   struct frad_local *flp;
+   struct dlci_local *dlp;
+   struct sk_buff    *skb;
+
+   struct sdla_cmd   *cmd;
+   struct buf_info   *pbufi;
+   struct buf_entry  *pbuf;
+
+   unsigned long     flags;
+   int               i, received, success, addr;
+   short             dlci, len, split;
+   char              bogus;
+
+   flp = dev->priv;
+   bogus = 0;
+   success = 0;
+   received = 0;
+   addr = 0;
+   skb = NULL;
+   master = NULL;
+
+   save_flags(flags);
+   cli();
+
+   switch (flp->type)
+   {
+      case SDLA_S502A:
+      case SDLA_S502E:
+         cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & 0x1FFF));
+         SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
+         if (!cmd->opp_flag)
+            break;
+
+         dlci = cmd->dlci;
+         len = cmd->length;
+
+         for (i=0;i<CONFIG_DLCI_MAX;i++)
+            if (flp->dlci[i] == dlci)
+               break;
+
+         if (i == CONFIG_DLCI_MAX)
+         {
+            printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
+            flp->stats.rx_errors++;
+            cmd->opp_flag = 0;
+            break;
+         }
+
+         master = flp->master[i];
+         skb = dev_alloc_skb(len);
+         if (skb == NULL) 
+         {
+            printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+            flp->stats.rx_dropped++;
+            cmd->opp_flag = 0;
+            break;
+         }
+
+         /* pick up the data */
+         sdla_read(dev, dev->mem_start + ((SDLA_502_RCV_BUF + SDLA_502_DATA_OFS) & 0x1FFF), skb_put(skb,len), len);
+         cmd->opp_flag = 0;
+         success = 1;
+         break;
+
+      case SDLA_S508:
+         pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & 0x1FFF));
+         SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+         pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & 0x1FFF));
+         if (!pbuf->opp_flag)
+            break;
+
+         dlci = pbuf->dlci;
+         len = pbuf->length;
+         addr = pbuf->buf_addr;
+
+         for (i=0;i<CONFIG_DLCI_MAX;i++)
+            if (flp->dlci[i] == dlci)
+               break;
+
+         if (i == CONFIG_DLCI_MAX)
+         {
+            printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
+            flp->stats.rx_errors++;
+            pbuf->opp_flag = 0;
+            break;
+         }
+
+         master = flp->master[i];
+         skb = dev_alloc_skb(len);
+         if (skb == NULL) 
+         {
+            printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+            flp->stats.rx_dropped++;
+            pbuf->opp_flag = 0;
+            break;
+         }
+
+         /* is this buffer split off the end of the internal ring buffer */
+         split = addr + len > pbufi->buf_top + 1 ? pbufi->buf_top - addr + 1 : 0;
+         len -= split;
+
+         /* lets get the data */
+         sdla_read(dev, addr, skb_put(skb, len), len);
+         if (split)
+         {
+            SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+            sdla_read(dev, pbufi->buf_base, skb_put(skb, split), split);
+         }
+
+         SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+         pbuf->opp_flag = 0;
+         success = 1;
+
+         /* increment the buffer we're looking at */
+         flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
+         break;
+   }
+
+   if (success)
+   {
+      flp->stats.rx_packets++;
+      dlp = master->priv;
+      (*dlp->receive)(skb, master);
+   }
+
+   restore_flags(flags);
+}
+
+static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
+{
+   struct device     *dev;
+   struct frad_local *flp;
+   char              byte;
+
+   dev = irq2dev_map[irq];
+
+   if (dev == NULL)
+   {
+      printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq);
+      return;
+   }
+
+   flp = dev->priv;
+
+   if (!flp->initialized)
+   {
+      printk(KERN_WARNING "%s: irq %d for unintialiazed device.\n", dev->name, irq);
+      return;
+   }
+
+   dev->interrupt = 1;
+   byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
+   switch (byte)
+   {
+      case SDLA_INTR_RX:
+         sdla_receive(dev);
+         break;
+
+      /* the command will get an error return, which is processed above */
+      case SDLA_INTR_MODEM:
+      case SDLA_INTR_STATUS:
+         sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
+         break;
+
+      case SDLA_INTR_TX:
+      case SDLA_INTR_COMPLETE:
+      case SDLA_INTR_TIMER:
+         printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
+         break;
+   }
+
+   /* the S502E requires a manual acknowledgement of the interrupt */ 
+   if (flp->type == SDLA_S502E)
+   {
+      flp->state &= ~SDLA_S502E_INTACK;
+      outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+      flp->state |= SDLA_S502E_INTACK;
+      outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+   }
+
+   dev->interrupt = 0;
+   /* this clears the byte, informing the Z80 we're done */
+   byte = 0;
+   sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
+}
+
+static void sdla_poll(unsigned long device)
+{
+   struct device     *dev;
+   struct frad_local *flp;
+
+   dev = (struct device *) device;
+   flp = dev->priv;
+
+   if (sdla_byte(dev, SDLA_502_RCV_BUF))
+      sdla_receive(dev);
+
+   flp->timer.expires = 1;
+   add_timer(&flp->timer);
+}
+
+static int sdla_close(struct device *dev)
+{
+   struct frad_local *flp;
+   struct intr_info  intr;
+   int               len, i;
+   short             dlcis[CONFIG_DLCI_MAX];
+
+   flp = dev->priv;
+
+   len = 0;
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+         dlcis[len++] = abs(flp->dlci[i]);
+   len *= 2;
+
+   if (flp->config.station == FRAD_STATION_NODE)
+   {
+      for(i=0;i<CONFIG_DLCI_MAX;i++)
+         if (flp->dlci[i] > 0) 
+            sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
+      sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
+   }
+
+   memset(&intr, 0, sizeof(intr));
+   /* lets start up the reception */
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         del_timer(&flp->timer); 
+         break;
+
+      case SDLA_S502E:
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
+         flp->state &= ~SDLA_S502E_INTACK;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+
+      case SDLA_S507:
+         break;
+
+      case SDLA_S508:
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
+         flp->state &= ~SDLA_S508_INTEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+   }
+
+   sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+   sdla_stop(dev);
+
+   dev->tbusy = 1;
+   dev->start = 0;
+
+   MOD_DEC_USE_COUNT;
+
+   return(0);
+}
+
+struct conf_data {
+   struct frad_conf config;
+   short            dlci[CONFIG_DLCI_MAX];
+};
+
+static int sdla_open(struct device *dev)
+{
+   struct frad_local *flp;
+   struct dlci_local *dlp;
+   struct conf_data  data;
+   struct intr_info  intr;
+   int               len, i;
+   char              byte;
+
+   flp = dev->priv;
+
+   if (!flp->initialized)
+      return(-EPERM);
+
+   if (!flp->configured)
+      return(-EPERM);
+
+   /* off to the races! */
+   sdla_start(dev);
+
+   /* time to send in the configuration */
+   len = 0;
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+         data.dlci[len++] = abs(flp->dlci[i]);
+   len *= 2;
+
+   memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
+   len += sizeof(struct frad_conf);
+
+   sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+   sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
+
+   if (flp->type == SDLA_S508)
+      flp->buffer = 0;
+
+   sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+
+   /* lets start up the reception */
+   memset(&intr, 0, sizeof(intr));
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         flp->timer.expires = 1;
+         add_timer(&flp->timer);
+         break;
+
+      case SDLA_S502E:
+         flp->state |= SDLA_S502E_ENABLE;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state |= SDLA_S502E_INTACK;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         byte = 0;
+         sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
+         intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
+         break;
+
+      case SDLA_S507:
+         break;
+
+      case SDLA_S508:
+         flp->state |= SDLA_S508_INTEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         byte = 0;
+         sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
+         intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
+         intr.irq = dev->irq;
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
+         break;
+   }
+
+   if (flp->config.station == FRAD_STATION_CPE)
+   {
+      byte = SDLA_ICS_STATUS_ENQ;
+      sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
+   }
+   else
+   {
+      sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
+      for(i=0;i<CONFIG_DLCI_MAX;i++)
+         if (flp->dlci[i] > 0)
+            sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
+   }
+
+   /* configure any specific DLCI settings */
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+      {
+         dlp = flp->master[i]->priv;
+         if (dlp->configured)
+            sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
+      }
+
+   dev->tbusy = 0;
+   dev->interrupt = 0;
+   dev->start = 1;
+
+   MOD_INC_USE_COUNT;
+
+   return(0);
+}
+
+static int sdla_config(struct device *dev, struct frad_conf *conf, int get)
+{
+   struct frad_local *flp;
+   struct conf_data  data;
+   int               i, err;
+
+   if (dev->type == 0xFFFF)
+      return(-EUNATCH);
+
+   flp = dev->priv;
+
+   if (!get)
+   {
+      if (dev->start)
+         return(-EBUSY);
+
+      err = verify_area(VERIFY_READ, conf, sizeof(struct frad_conf));
+      if (err)
+         return(err);
+
+      memcpy_fromfs(&data.config, conf, sizeof(struct frad_conf));
+
+      if (data.config.station & ~FRAD_STATION_NODE)
+         return(-EINVAL);
+
+      if (data.config.flags & ~FRAD_VALID_FLAGS)
+         return(-EINVAL);
+
+      if ((data.config.kbaud < 0) || 
+          ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
+         return(-EINVAL);
+
+      if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
+         return(-EINVAL);
+
+      if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
+         return(-EINVAL);
+
+      if ((data.config.T391 < 5) || (data.config.T391 > 30))
+         return(-EINVAL);
+
+      if ((data.config.T392 < 5) || (data.config.T392 > 30))
+         return(-EINVAL);
+
+      if ((data.config.N391 < 1) || (data.config.N391 > 255))
+         return(-EINVAL);
+
+      if ((data.config.N392 < 1) || (data.config.N392 > 10))
+         return(-EINVAL);
+
+      if ((data.config.N393 < 1) || (data.config.N393 > 10))
+         return(-EINVAL);
+
+      memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
+      flp->config.flags |= SDLA_DIRECT_RECV;
+
+      if (dev->mtu != flp->config.mtu)
+      {
+         /* this is required to change the MTU */
+         dev->mtu = flp->config.mtu;
+         for(i=0;i<CONFIG_DLCI_MAX;i++)
+            if (flp->master[i])
+               flp->master[i]->mtu = flp->config.mtu;
+      }
+
+      flp->config.mtu += sizeof(struct fradhdr);
+      flp->configured = 1;
+   }
+   else
+   {
+      err = verify_area(VERIFY_WRITE, conf, sizeof(struct frad_conf));
+      if (err)
+         return(err);
+
+      sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, &data, sizeof(data), NULL, NULL);
+      memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
+
+      data.config.flags &= ~SDLA_DIRECT_RECV;
+      data.config.mtu -= sizeof(struct fradhdr);
+      memcpy_tofs(conf, &data.config, sizeof(struct frad_conf));
+   }
+
+   return(0);
+}
+
+static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read)
+{
+   struct sdla_mem mem;
+   int    err;
+   char   *temp;
+
+   err = verify_area(VERIFY_READ, info, sizeof(struct sdla_mem));
+   if (err)
+      return(err);
+
+   memcpy_fromfs(&mem, info, sizeof(mem));
+   if (read)
+   {
+      err = verify_area(VERIFY_WRITE, mem.data, mem.len);
+      if (err)
+         return(err);
+
+      temp = kmalloc(mem.len, GFP_KERNEL);
+      if (!temp)
+         return(-ENOMEM);
+      sdla_read(dev, mem.addr, temp, mem.len);
+      memcpy_tofs(mem.data, temp, mem.len);
+      kfree(temp);
+   }
+   else
+   {
+      err = verify_area(VERIFY_READ, mem.data, mem.len);
+      if (err)
+         return(err);
+
+      temp = kmalloc(mem.len, GFP_KERNEL);
+      if (!temp)
+         return(-ENOMEM);
+      memcpy_fromfs(temp, mem.data, mem.len);
+      sdla_write(dev, mem.addr, temp, mem.len);
+      kfree(temp);
+   }
+   return(0);
+}
+
+static int sdla_reconfig(struct device *dev)
+{
+   struct frad_local *flp;
+   struct conf_data  data;
+   int               i, len;
+
+   flp = dev->priv;
+
+   memcpy(&data, &flp->config, sizeof(struct frad_conf));
+
+   len = 0;
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+         data.dlci[len++] = flp->dlci[i];
+   len *= 2;
+   len += sizeof(struct frad_conf);
+
+   sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+   sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
+   sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+
+   return(0);
+}
+
+static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+
+   if (!flp->initialized)
+      return(-EPERM);
+
+   switch (cmd)
+   {
+      case FRAD_GET_CONF:
+      case FRAD_SET_CONF:
+         return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF));
+
+      case SDLA_IDENTIFY:
+         ifr->ifr_flags = flp->type;
+         break;
+
+      case SDLA_CPUSPEED:
+         return(sdla_cpuspeed(dev, ifr)); 
+
+/* ==========================================================
+NOTE:  This is rather a useless action right now, as the
+       driver does not support protocols other than FR right
+       now.  However, Sangoma has modules for a number of
+       other protocols.
+============================================================*/
+      case SDLA_PROTOCOL:
+         if (flp->configured)
+            return(-EALREADY);
+
+         switch (ifr->ifr_flags)
+         {
+            case ARPHRD_FRAD:
+               dev->type = ifr->ifr_flags;
+               dev->family = AF_UNSPEC;
+               break;
+
+            default:
+               return(-ENOPROTOOPT);
+         }
+         break;
+
+      case SDLA_CLEARMEM:
+         sdla_clear(dev);
+         break;
+
+      case SDLA_WRITEMEM:
+      case SDLA_READMEM:
+         return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM));
+
+      case SDLA_START:
+         sdla_start(dev);
+         break;
+
+      case SDLA_STOP:
+         sdla_stop(dev);
+         break;
+
+      default:
+         return(-EOPNOTSUPP);
+   }
+   return(0);
+}
+
+int sdla_change_mtu(struct device *dev, int new_mtu)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+
+   if (dev->start)
+      return(-EBUSY);
+
+   /* for now, you can't change the MTU! */
+   return(-EACCES);
+}
+
+int sdla_set_config(struct device *dev, struct ifmap *map)
+{
+   struct frad_local *flp;
+   int               i;
+   char              byte;
+
+   flp = dev->priv;
+
+   if (flp->initialized)
+      return(-EINVAL);
+
+   for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
+      if (valid_port[i] == map->base_addr)
+         break;   
+
+   if (i == sizeof(valid_port) / sizeof(int))
+      return(-EINVAL);
+
+   dev->base_addr = map->base_addr;
+   request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name);
+
+   /* test for card types, S502A, S502E, S507, S508                 */
+   /* these tests shut down the card completely, so clear the state */
+   flp->type = SDLA_UNKNOWN;
+   flp->state = 0;
+   
+   for(i=1;i<SDLA_IO_EXTENTS;i++)
+      if (inb(dev->base_addr + i) != 0xFF)
+        break;
+
+   if (i == SDLA_IO_EXTENTS)
+   {   
+      outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
+      if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x08)
+      {
+         outb(SDLA_S502E_INTACK, dev->base_addr + SDLA_REG_CONTROL);
+         if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x0C)
+         {
+            outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+            flp->type = SDLA_S502E;
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      for(byte=inb(dev->base_addr),i=0;i<SDLA_IO_EXTENTS;i++)
+         if (inb(dev->base_addr + i) != byte)
+            break;
+
+      if (i == SDLA_IO_EXTENTS)
+      {
+         outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+         if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x30)
+         {
+            outb(SDLA_S507_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
+            if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x32)
+            {
+               outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+               flp->type = SDLA_S507;
+            }
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+      if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x00)
+      {
+         outb(SDLA_S508_INTEN, dev->base_addr + SDLA_REG_CONTROL);
+         if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x10)
+         {
+            outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+            flp->type = SDLA_S508;
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
+      if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
+      {
+         outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+         if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
+         {
+            outb(SDLA_S502A_INTEN, dev->base_addr + SDLA_REG_CONTROL);
+            if (inb(dev->base_addr + SDLA_S502_STS) == 0x44)
+            {
+               outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+               flp->type = SDLA_S502A;
+            }
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
+      return(-ENODEV);
+   }
+
+   switch(dev->base_addr)
+   {
+      case 0x270:
+      case 0x280:
+      case 0x380: 
+      case 0x390:
+         if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
+            return(-EINVAL);
+   }
+
+   switch (map->irq)
+   {
+      case 2:
+         if (flp->type != SDLA_S502E)
+            return(-EINVAL);
+         break;
+
+      case 10:
+      case 11:
+      case 12:
+      case 15:
+      case 4:
+         if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
+            return(-EINVAL);
+
+      case 3:
+      case 5:
+      case 7:
+         if (flp->type == SDLA_S502A)
+            return(-EINVAL);
+         break;
+
+      default:
+         return(-EINVAL);
+   }
+   dev->irq = map->irq;
+
+   if (request_irq(dev->irq, &sdla_isr, 0, dev->name, NULL)) 
+      return(-EADDRINUSE);
+
+   irq2dev_map[dev->irq] = dev;
+
+   if (flp->type == SDLA_S507)
+   {
+      switch(dev->irq)
+      {
+         case 3:
+            flp->state = SDLA_S507_IRQ3;
+            break;
+         case 4:
+            flp->state = SDLA_S507_IRQ4;
+            break;
+         case 5:
+            flp->state = SDLA_S507_IRQ5;
+            break;
+         case 7:
+            flp->state = SDLA_S507_IRQ7;
+            break;
+         case 10:
+            flp->state = SDLA_S507_IRQ10;
+            break;
+         case 11:
+            flp->state = SDLA_S507_IRQ11;
+            break;
+         case 12:
+            flp->state = SDLA_S507_IRQ12;
+            break;
+         case 15:
+            flp->state = SDLA_S507_IRQ15;
+            break;
+      }
+   }
+
+   for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
+      if (valid_mem[i] == map->mem_start)
+         break;   
+
+   if (i == sizeof(valid_mem) / sizeof(int))
+      return(-EINVAL);
+
+   if ((flp->type == SDLA_S502A) && (((map->mem_start & 0xF000) >> 12) == 0x0E))
+      return(-EINVAL);
+
+   if ((flp->type != SDLA_S507) && ((map->mem_start >> 16) == 0x0B))
+      return(-EINVAL);
+
+   if ((flp->type == SDLA_S507) && ((map->mem_start >> 16) == 0x0D))
+      return(-EINVAL);
+
+   dev->mem_start = map->mem_start;
+   dev->mem_end = dev->mem_start + 0x2000;
+
+   byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
+   byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+      case SDLA_S502E:
+         switch (map->mem_start >> 16)
+         {
+            case 0x0A:
+               byte |= SDLA_S502_SEG_A;
+               break;
+            case 0x0C:
+               byte |= SDLA_S502_SEG_C;
+               break;
+            case 0x0D:
+               byte |= SDLA_S502_SEG_D;
+               break;
+            case 0x0E:
+               byte |= SDLA_S502_SEG_E;
+               break;
+         }
+         break;
+      case SDLA_S507:
+         switch (map->mem_start >> 16)
+         {
+            case 0x0A:
+               byte |= SDLA_S507_SEG_A;
+               break;
+            case 0x0B:
+               byte |= SDLA_S507_SEG_B;
+               break;
+            case 0x0C:
+               byte |= SDLA_S507_SEG_C;
+               break;
+            case 0x0E:
+               byte |= SDLA_S507_SEG_E;
+               break;
+         }
+         break;
+      case SDLA_S508:
+         switch (map->mem_start >> 16)
+         {
+            case 0x0A:
+               byte |= SDLA_S508_SEG_A;
+               break;
+            case 0x0C:
+               byte |= SDLA_S508_SEG_C;
+               break;
+            case 0x0D:
+               byte |= SDLA_S508_SEG_D;
+               break;
+            case 0x0E:
+               byte |= SDLA_S508_SEG_E;
+               break;
+         }
+         break;
+   }
+
+   /* set the memory bits, and enable access */
+   outb(byte, dev->base_addr + SDLA_REG_PC_WINDOW);
+   switch(flp->type)
+   {
+      case SDLA_S502E:
+         flp->state = SDLA_S502E_ENABLE;
+         break;
+      case SDLA_S507:
+         flp->state |= SDLA_MEMEN;
+         break;
+      case SDLA_S508:
+         flp->state = SDLA_MEMEN;
+         break;
+   }
+   outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+
+   flp->initialized = 1;
+   return(0);
+}
+ 
+static struct enet_statistics *sdla_stats(struct device *dev)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+
+   return(&flp->stats);
+}
+
+int sdla_init(struct device *dev)
+{
+   struct frad_local *flp;
+   int               i;
+
+   /* allocate the private data structure */
+   flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL);
+   if (!flp)
+      return(-ENOMEM);
+
+   memset(flp, 0, sizeof(struct frad_local));
+   dev->priv = flp;
+
+   dev->flags           = 0;
+   dev->open            = sdla_open;
+   dev->stop            = sdla_close;
+   dev->do_ioctl        = sdla_ioctl;
+   dev->set_config      = sdla_set_config;
+   dev->get_stats       = sdla_stats;
+   dev->hard_start_xmit = sdla_transmit;
+   dev->change_mtu	= sdla_change_mtu;
+
+   dev->type            = 0xFFFF;
+   dev->family          = AF_UNSPEC;
+   dev->pa_alen         = sizeof(unsigned long);
+   dev->hard_header_len = 0;
+   dev->mtu             = SDLA_MAX_MTU;
+
+   for (i = 0; i < DEV_NUMBUFFS; i++) 
+      skb_queue_head_init(&dev->buffs[i]);
+
+   flp->activate        = sdla_activate;
+   flp->deactivate      = sdla_deactivate;
+   flp->assoc           = sdla_assoc;
+   flp->deassoc         = sdla_deassoc;
+   flp->dlci_conf       = sdla_dlci_conf;
+
+   init_timer(&flp->timer);
+   flp->timer.expires   = 1;
+   flp->timer.data      = (unsigned long) dev;
+   flp->timer.function  = sdla_poll;
+
+   return(0);
+}
+
+void sdla_setup(void)
+{
+   printk("%s.\n", version);
+   register_frad(devname);
+}
+
+#ifdef MODULE
+static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init};
+
+int init_module(void)
+{
+   int result;
+
+   sdla_setup();
+   if ((result = register_netdev(&sdla0)) != 0)
+      return result;
+
+   return 0;
+}
+
+void cleanup_module(void)
+{
+   unregister_netdev(&sdla0);
+   if (sdla0.priv)
+      kfree(sdla0.priv);
+   if (sdla0.irq)
+      free_irq(sdla0.irq, NULL);
+}
+#endif /* MODULE */
diff -u --recursive --new-file v1.3.77/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v1.3.77/linux/drivers/pci/pci.c	Wed Mar 13 10:09:18 1996
+++ linux/drivers/pci/pci.c	Fri Mar 22 13:01:40 1996
@@ -73,7 +73,6 @@
 	DEVICE( CIRRUS,		CIRRUS_5434_4,	"GD 5434"),
 	DEVICE( CIRRUS,		CIRRUS_5434_8,	"GD 5434"),
 	DEVICE( CIRRUS,		CIRRUS_5436,	"GD 5436"),
-	DEVICE( CIRRUS,		CIRRUS_6205,	"GD 6205"),
 	DEVICE( CIRRUS,		CIRRUS_6729,	"CL 6729"),
 	DEVICE( CIRRUS,		CIRRUS_7542,	"CL 7542"),
 	DEVICE( CIRRUS,		CIRRUS_7543,	"CL 7543"),
@@ -90,9 +89,11 @@
 	DEVICE( MATROX,		MATROX_MGA_IMP,	"MGA Impression"),
 	DEVICE( CT,		CT_65545,	"65545"),
 	DEVICE( CT,		CT_65548,	"65548"),
+	DEVICE( MIRO,		MIRO_36050,	"ZR36050"),
 	DEVICE( FD,		FD_36C70,	"TMC-18C30"),
 	DEVICE( SI,		SI_6201,	"6201"),
 	DEVICE( SI,		SI_6202,	"6202"),
+	DEVICE( SI,		SI_6205,	"6205"),
 	DEVICE( SI,		SI_503,		"85C503"),
 	DEVICE( SI,		SI_501,		"85C501"),
 	DEVICE( SI,		SI_496,		"85C496"),
@@ -163,11 +164,25 @@
 	DEVICE( VIA,		VIA_82C561,	"VT 82C561"),
 	DEVICE( VIA,		VIA_82C576,	"VT 82C576 3V"),
 	DEVICE( VIA,		VIA_82C416,	"VT 82C416MV"),
-	DEVICE( VORTEX,		VORTEX_GDT,	"GDT 6000b"),
+	DEVICE( VORTEX,		VORTEX_GDT60x0,	"GDT 60x0"),
+	DEVICE( VORTEX,		VORTEX_GDT6000B,"GDT 6000b"),
+	DEVICE( VORTEX,		VORTEX_GDT6x10,	"GDT 6110/6510"),
+	DEVICE( VORTEX,		VORTEX_GDT6x20,	"GDT 6120/6520"),
+	DEVICE( VORTEX,		VORTEX_GDT6530,	"GDT 6530"),
+	DEVICE( VORTEX,		VORTEX_GDT6550,	"GDT 6550"),
+	DEVICE( VORTEX,		VORTEX_GDT6x17,	"GDT 6117/6517"),
+	DEVICE( VORTEX,		VORTEX_GDT6x27,	"GDT 6127/6527"),
+	DEVICE( VORTEX,		VORTEX_GDT6537,	"GDT 6537"),
+	DEVICE( VORTEX,		VORTEX_GDT6557,	"GDT 6557"),
+	DEVICE( VORTEX,		VORTEX_GDT6x15,	"GDT 6115/6515"),
+	DEVICE( VORTEX,		VORTEX_GDT6x25,	"GDT 6125/6525"),
+	DEVICE( VORTEX,		VORTEX_GDT6535,	"GDT 6535"),
+	DEVICE( VORTEX,		VORTEX_GDT6555,	"GDT 6555"),
 	DEVICE( EF,		EF_ATM_FPGA,		"155P-MF1 (FPGA)"),
 	DEVICE( EF,		EF_ATM_ASIC,	"155P-MF1 (ASIC)"),
 	DEVICE( IMAGINGTECH,	IMAGINGTECH_ICPCI, "MVC IC-PCI"),
 	DEVICE( FORE,		FORE_PCA200PC, "PCA-200PC"),
+	DEVICE( FORE,		FORE_PCA200E,	 "PCA-200E"),
 	DEVICE( PLX,		PLX_9060,	"PCI9060 i960 bridge"),
 	DEVICE( ALLIANCE,	ALLIANCE_PROMOTIO, "Promotion-6410"),
 	DEVICE( ALLIANCE,	ALLIANCE_PROVIDEO, "Provideo"),
diff -u --recursive --new-file v1.3.77/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c
--- v1.3.77/linux/drivers/scsi/NCR5380.c	Thu Mar 21 20:36:52 1996
+++ linux/drivers/scsi/NCR5380.c	Fri Mar 22 09:40:30 1996
@@ -2185,7 +2185,7 @@
 
     *data = d + c;
     *count = 0;
-    *phase = (NCR5380_read(STATUS_REG & PHASE_MASK));
+    *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 #if 0
     NCR5380_print_phase(instance);
 #endif
diff -u --recursive --new-file v1.3.77/linux/drivers/scsi/README.g_NCR5380 linux/drivers/scsi/README.g_NCR5380
--- v1.3.77/linux/drivers/scsi/README.g_NCR5380	Thu Mar 21 20:36:52 1996
+++ linux/drivers/scsi/README.g_NCR5380	Sun Mar 24 20:07:00 1996
@@ -1,4 +1,4 @@
-REAME file for the Linux g_NCR5380 driver.
+README file for the Linux g_NCR5380 driver.
 
 (c) 1993 Drew Eckhard
 NCR53c400 extensions (c) 1994,1995,1996 Kevin Lentin
diff -u --recursive --new-file v1.3.77/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v1.3.77/linux/drivers/scsi/fdomain.c	Sun Mar 10 09:49:55 1996
+++ linux/drivers/scsi/fdomain.c	Sat Mar 23 13:15:00 1996
@@ -982,6 +982,9 @@
 				   get resources.  */
 
    shpnt = scsi_register( tpnt, 0 );
+   shpnt->irq = interrupt_level;
+   shpnt->io_port = port_base;
+   shpnt->n_io_port = 0x10;
    print_banner( shpnt );
 
 				/* Log IRQ with kernel */   
diff -u --recursive --new-file v1.3.77/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.3.77/linux/drivers/scsi/scsi.c	Wed Mar 20 10:59:57 1996
+++ linux/drivers/scsi/scsi.c	Sat Mar 23 13:15:00 1996
@@ -2153,7 +2153,7 @@
     
     if(SCset){
 	oldto = SCset->timeout - used;
-	SCset->timeout = timeout + used;
+	SCset->timeout = timeout;
     }
 
     least = 0xffffffff;
@@ -2161,7 +2161,8 @@
     for(host = scsi_hostlist; host; host = host->next)
 	for(SCpnt = host->host_queue; SCpnt; SCpnt = SCpnt->next)
 	    if (SCpnt->timeout > 0) {
-		SCpnt->timeout -= used;
+	        if (SCpnt != SCset)
+		  SCpnt->timeout -= used;
 		if(SCpnt->timeout <= 0) SCpnt->timeout = -1;
 		if(SCpnt->timeout > 0 && SCpnt->timeout < least)
 		    least = SCpnt->timeout;
diff -u --recursive --new-file v1.3.77/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.3.77/linux/drivers/scsi/scsi.h	Wed Feb  7 15:11:29 1996
+++ linux/drivers/scsi/scsi.h	Sun Mar 24 18:57:04 1996
@@ -514,7 +514,7 @@
  * turned off 
  */
 #define INIT_SCSI_REQUEST       \
-    if (!CURRENT) {             \
+    if (!CURRENT || CURRENT_PLUGGED) {     \
 	CLEAR_INTR;             \
 	restore_flags(flags);	\
 	return;                 \
diff -u --recursive --new-file v1.3.77/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c
--- v1.3.77/linux/drivers/scsi/sd_ioctl.c	Sun Mar 10 09:49:55 1996
+++ linux/drivers/scsi/sd_ioctl.c	Sun Mar 24 20:07:00 1996
@@ -19,6 +19,7 @@
 #include "scsi_ioctl.h"
 #include "hosts.h"
 #include "sd.h"
+#include <linux/scsicam.h>     /* must follow "hosts.h" */
 
 int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
 {
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/.version linux/drivers/sound/.version
--- v1.3.77/linux/drivers/sound/.version	Fri Mar 15 16:03:16 1996
+++ linux/drivers/sound/.version	Sun Mar 24 22:56:00 1996
@@ -1,2 +1,2 @@
-3.5
+3.5.1
 0x030500
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/CHANGELOG linux/drivers/sound/CHANGELOG
--- v1.3.77/linux/drivers/sound/CHANGELOG	Fri Mar 15 16:03:16 1996
+++ linux/drivers/sound/CHANGELOG	Sun Mar 24 22:55:28 1996
@@ -1,5 +1,5 @@
-Changelog for version 3.5
--------------------------
+Changelog for version 3.5.1
+---------------------------
 
 Since 3.5
 - Improved handling of playback underrunt situations.
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v1.3.77/linux/drivers/sound/Makefile	Fri Mar 15 16:03:17 1996
+++ linux/drivers/sound/Makefile	Mon Mar 25 09:20:45 1996
@@ -30,6 +30,7 @@
 endif
 
 
+ifndef HOSTCC
 build:
 	@echo Compiling modularized sound driver
 	@make sound.o
@@ -37,6 +38,7 @@
 
 install:	sound.o
 	cp sound.o $(MODULEDIR)
+endif
 
 .c.o:
 	$(CC) $(CFLAGS) -c $<
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/Readme linux/drivers/sound/Readme
--- v1.3.77/linux/drivers/sound/Readme	Fri Mar 15 16:03:17 1996
+++ linux/drivers/sound/Readme	Sun Mar 24 22:55:43 1996
@@ -1,5 +1,5 @@
-Version 3.5-beta11 release notes
---------------------------------
+Version 3.5.1 release notes
+---------------------------
 
 Most up to date information about this driver is available from 
 http://personal.eunet.fi/pp/voxware.
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/Readme.cards linux/drivers/sound/Readme.cards
--- v1.3.77/linux/drivers/sound/Readme.cards	Fri Mar 15 16:03:17 1996
+++ linux/drivers/sound/Readme.cards	Mon Mar 25 09:25:26 1996
@@ -601,8 +601,7 @@
 partition containing the file with Linux. 
 
 It's possible to load your own DSP algorithms and run them with the card.
-Look at the directory pss_test of snd-util-3.0.tar.gz for more info.§
-package.
+Look at the directory pss_test of snd-util-3.0.tar.gz for more info.
 
 AudioTriX Pro
 -------------
@@ -688,9 +687,6 @@
 are terrible), just modify ssinit.c to use another microcode file and try
 again. It's possible to use an earlier version of sndscape.co[01] but it
 may sound wierd.
-
-Btw, The driver may complain something about "sscapeintr()" after
-running ssinit. You should just ignore these messages.
 
 MAD16 (Pro) and Mozart
 ----------------------
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v1.3.77/linux/drivers/sound/ad1848.c	Fri Mar 15 16:03:17 1996
+++ linux/drivers/sound/ad1848.c	Sun Mar 24 22:49:51 1996
@@ -1152,9 +1152,9 @@
 {
 
   unsigned char   tmp;
-  int             i;
   ad1848_info    *devc = &dev_info[nr_ad1848_devs];
   unsigned char   tmp1 = 0xff, tmp2 = 0xff;
+  int             i;
 
   DDB (printk ("ad1848_detect(%x)\n", io_base));
 
@@ -1201,6 +1201,11 @@
       return 0;
     }
 
+  DDB (printk ("ad1848: regs: "));
+  for (i = 0; i < 32; i++)
+    DDB (printk ("%02x ", ad_read (devc, i)));
+  DDB (printk ("\n"));
+
   /*
      * Test if it's possible to change contents of the indirect registers.
      * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
@@ -1254,15 +1259,6 @@
      * with CS4231.
    */
 
-  DDB (printk ("ad1848_detect() - step F\n"));
-  ad_write (devc, 12, 0);	/* Mode2=disabled */
-
-  for (i = 0; i < 16; i++)
-    if ((tmp1 = ad_read (devc, i)) != (tmp2 = ad_read (devc, i + 16)))
-      {
-	DDB (printk ("ad1848 detect error - step F(%d/%x/%x)\n", i, tmp1, tmp2));
-	return 0;
-      }
 
   /*
      * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40).
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
--- v1.3.77/linux/drivers/sound/audio.c	Tue Mar  5 10:11:03 1996
+++ linux/drivers/sound/audio.c	Mon Mar 25 09:25:26 1996
@@ -51,7 +51,7 @@
 static int      local_conversion[MAX_AUDIO_DEV];
 
 static int
-set_format (int dev, int fmt)
+set_format (int dev, long fmt)
 {
   if (fmt != AFMT_QUERY)
     {
@@ -80,7 +80,7 @@
 audio_open (int dev, struct fileinfo *file)
 {
   int             ret;
-  int             bits;
+  long            bits;
   int             dev_type = dev & 0x0f;
   int             mode = file->mode & O_ACCMODE;
 
@@ -128,13 +128,31 @@
 void
 sync_output (int dev)
 {
-  int             buf_no, buf_ptr, buf_size;
+  int             buf_no, buf_ptr, buf_size, p, i;
   char           *dma_buf;
+  struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 
   if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
     {
       DMAbuf_start_output (dev, buf_no, buf_ptr);
     }
+
+/*
+ * Clean all unused buffer fragments.
+ */
+
+  p = dmap->qtail;
+
+  for (i = dmap->qlen; i < dmap->nbufs; i++)
+    {
+      memset (dmap->raw_buf + p * dmap->fragment_size,
+	      dmap->neutral_byte,
+	      dmap->fragment_size);
+
+      p = (p + 1) % dmap->nbufs;
+    }
+
+  dmap->flags |= DMA_CLEAN;
 }
 
 void
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/configure.c linux/drivers/sound/configure.c
--- v1.3.77/linux/drivers/sound/configure.c	Thu Mar 21 20:36:52 1996
+++ linux/drivers/sound/configure.c	Sun Mar 24 22:49:55 1996
@@ -1,13 +1,36 @@
 /*
- *	 PnP soundcard support is not included in this version.
+ *     PnP soundcard support is not included in this version.
  *
- *	 AEDSP16 will not work without significant changes.
+ *       AEDSP16 will not work without significant changes.
  */
 #define DISABLED_OPTIONS 	(B(OPT_SPNP)|B(OPT_AEDSP16)|B(OPT_UNUSED1)|B(OPT_UNUSED2))
 /*
  * sound/configure.c  - Configuration program for the Linux Sound Driver
  */
-#define COPYING2
+/*
+ * Copyright by Hannu Savolainen 1993-1996
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
 
 #include <stdio.h>
 #include <unistd.h>
@@ -56,7 +79,7 @@
 #define ANY_DEVS (B(OPT_AUDIO)|B(OPT_MIDI)|B(OPT_GUS)| \
 		  B(OPT_MPU401)|B(OPT_PSS)|B(OPT_GUS16)|B(OPT_GUSMAX)| \
 		  B(OPT_MSS)|B(OPT_SSCAPE)|B(OPT_UART6850)|B(OPT_TRIX)| \
-		  B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI))
+		  B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI)|B(OPT_ADLIB))
 #define AUDIO_CARDS (B (OPT_PSS) | B (OPT_SB) | B (OPT_PAS) | B (OPT_GUS) | \
 		B (OPT_MSS) | B (OPT_GUS16) | B (OPT_GUSMAX) | B (OPT_TRIX) | \
 		B (OPT_SSCAPE)| B(OPT_MAD16) | B(OPT_CS4232))
@@ -221,7 +244,7 @@
   "them. In addition the MAD16 chip is used in some cards made by known\n"
   "manufacturers such as Turtle Beach (Tropez), Reveal (some models) and\n"
   "Diamond (latest ones).\n",
-  
+
   "Enable this if you have a card based on the Crystal CS4232 chip set.\n",
 
   "Enable this option if you have a Turtle Beach Wave Front, Maui,\n"
@@ -246,7 +269,7 @@
   "This enables the dev/midixx devices and access to any MIDI ports\n"
   "using /dev/sequencer and /dev/music. This option also affects any\n"
   "MPU401 and/or General MIDI compatible devices.\n",
-  
+
   "This should not be asked",
 
   "This enables the Yamaha FM synthesizer chip used on many sound\n"
@@ -297,21 +320,6 @@
 int
 can_select_option (int nr)
 {
-#if 0
-  switch (nr)
-    {
-    case OPT_LAST_MUTUAL + 1:
-      fprintf (stderr, "\nThe following cards should work with any other cards.\n"
-	       "CAUTION! Don't enable MPU-401 if you don't have it.\n");
-      break;
-
-    case OPT_HIGHLEVEL:
-      fprintf (stderr, "\nSelect one or more of the following options\n");
-      break;
-
-
-    }
-#endif
 
   if (hw_table[nr].conditions)
     if (!(hw_table[nr].conditions & selected_options))
@@ -333,12 +341,12 @@
   char            answ[512];
   int             len;
 
-  response:
-  fprintf(stderr, prompt);
+response:
+  fprintf (stderr, prompt);
   if (def_answ)
-    fprintf(stderr, " [Y/n/?] ");
+    fprintf (stderr, " [Y/n/?] ");
   else
-    fprintf(stderr, " [N/y/?] ");
+    fprintf (stderr, " [N/y/?] ");
 
   if ((len = read (0, answ, sizeof (answ))) < 1)
     {
@@ -354,12 +362,13 @@
 				 */
     return def_answ;
 
-  if (answ[0] == '?') {		/* display help message */
-    fprintf(stderr, "\n");
-    fprintf(stderr, help);
-    fprintf(stderr, "\n");
-    goto response;
-  }
+  if (answ[0] == '?')
+    {				/* display help message */
+      fprintf (stderr, "\n");
+      fprintf (stderr, help);
+      fprintf (stderr, "\n");
+      goto response;
+    }
 
   answ[len - 1] = 0;
 
@@ -420,7 +429,7 @@
       for (i = 0; i < OPT_LAST; i++)
 	if (mask == B (i))
 	  {
-	    unsigned int             j;
+	    unsigned int    j;
 
 	    for (j = 0; j < strlen (choices); j++)
 	      if (choices[j] == '\'')
@@ -441,7 +450,7 @@
 	return;
 
       fprintf (stderr, "\n%s\n", question);
-      if (strcmp(choices, ""))
+      if (strcmp (choices, ""))
 	fprintf (stderr, "Possible values are: %s\n", choices);
 
       if (format == FMT_INT)
@@ -579,18 +588,18 @@
 	    continue;
 
 	  if (strcmp (tmp, "JAZZ_DMA16") == 0)	/* Rename it (hack) */
-	  {
-		printf("#define SB_DMA2 %s\n",
-			&buf[18]);
-		continue;
-	  }
+	    {
+	      printf ("#define SB_DMA2 %s\n",
+		      &buf[18]);
+	      continue;
+	    }
 
 	  if (strcmp (tmp, "SB16_DMA") == 0)	/* Rename it (hack) */
-	  {
-		printf("#define SB_DMA2 %s\n",
-			&buf[16]);
-		continue;
-	  }
+	    {
+	      printf ("#define SB_DMA2 %s\n",
+		      &buf[16]);
+	      continue;
+	    }
 
 	  tmp[8] = 0;		/* Truncate the string */
 	  if (strcmp (tmp, "EXCLUDE_") == 0)
@@ -678,14 +687,11 @@
   printf ("#define SELECTED_SOUND_OPTIONS\t0x%08x\n", selected_options);
   fprintf (stderr, "Old configuration copied.\n");
 
-#ifdef linux
   build_defines ();
-#endif
   old_config_used = 1;
   return 1;
 }
 
-#ifdef linux
 void
 build_defines (void)
 {
@@ -703,10 +709,6 @@
     if (!hw_table[i].alias)
       if (selected_options & B (i))
 	fprintf (optf, "CONFIG_%s=y\n", hw_table[i].macro);
-#if 0
-      else
-	fprintf (optf, "CONFIG_%s=n\n", hw_table[i].macro);
-#endif
 
 
   fprintf (optf, "\n");
@@ -717,22 +719,16 @@
     {
       if (selected_options & extra_options[i].mask)
 	fprintf (optf, "CONFIG_%s=y\n", extra_options[i].name);
-#if 0
-      else
-	fprintf (optf, "CONFIG_%s=n\n", extra_options[i].name);
-#endif
       i++;
     }
 
   fprintf (optf, "\n");
   fclose (optf);
 }
-#endif
 
 void
 ask_parameters (void)
 {
-#ifdef linux
   int             num;
 
   build_defines ();
@@ -765,7 +761,7 @@
 		  "0, 1 or 3");
 
   ask_int_choice (B (OPT_SB), "SB_DMA2",
-		  "SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)",
+		"SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)",
 		  FMT_INT,
 		  5,
 		  "5, 6 or 7");
@@ -797,21 +793,21 @@
   if (selected_options & B (OPT_PAS))
     {
       if (think_positively ("Enable Joystick port on ProAudioSpectrum", 0,
-      "Enable this option if you want to use the joystick port provided\n"
-      "on the PAS sound card.\n"))
-         printf ("#define PAS_JOYSTICK_ENABLE\n");
+	"Enable this option if you want to use the joystick port provided\n"
+			    "on the PAS sound card.\n"))
+	printf ("#define PAS_JOYSTICK_ENABLE\n");
 
       if (think_positively ("Enable PAS16 bus clock option", 0,
-      "The PAS16 can be noisy with some motherboards. There is a command\n"
-      "line switch (:T?) in the DOS driver for PAS16 which solves this.\n"
+       "The PAS16 can be noisy with some motherboards. There is a command\n"
+	"line switch (:T?) in the DOS driver for PAS16 which solves this.\n"
       "Don't enable this feature unless you have problems and have to use\n"
-      "this switch with DOS\n"))
+			    "this switch with DOS\n"))
 	printf ("#define BROKEN_BUS_CLOCK\n");
 
       if (think_positively ("Disable SB mode of PAS16", 0,
-      "You should disable SB emulation of PAS16 if you want to use\n"
-      "Another SB compatible card in the same system\n"))
-         printf ("#define DISABLE_SB_EMULATION\n");
+	     "You should disable SB emulation of PAS16 if you want to use\n"
+			 "Another SB compatible card in the same system\n"))
+	printf ("#define DISABLE_SB_EMULATION\n");
     }
 
   ask_int_choice (B (OPT_GUS), "GUS_BASE",
@@ -989,10 +985,10 @@
       int             reveal_spea;
 
       reveal_spea = think_positively (
-        "Is your SoundScape card made/marketed by Reveal or Spea",
-	0,
-	"Enable if you have a SoundScape card with the Reveal or\n"
-	"Spea name on it.\n");
+		  "Is your SoundScape card made/marketed by Reveal or Spea",
+				       0,
+		 "Enable if you have a SoundScape card with the Reveal or\n"
+				       "Spea name on it.\n");
       if (reveal_spea)
 	printf ("#define REVEAL_SPEA\n");
 
@@ -1123,7 +1119,6 @@
 		  FMT_INT,
 		  9,
 		  "5, 7, 9 or 10");
-#endif
   ask_int_choice (B (OPT_AUDIO), "DSP_BUFFSIZE",
 		  "Audio DMA buffer size",
 		  FMT_INT,
@@ -1152,9 +1147,7 @@
   selected_options = 0;
   ask_parameters ();
 
-#if 1
   printf ("#\n$MAKE -C drivers/sound kernelconfig || exit 1\n");
-#endif
 }
 
 void
@@ -1258,11 +1251,12 @@
 
   if (access (oldconf, R_OK) == 0)
     {
-      char str[255];
-      sprintf(str, "Old configuration exists in `%s'. Use it", oldconf);
+      char            str[255];
+
+      sprintf (str, "Old configuration exists in `%s'. Use it", oldconf);
       if (think_positively (str, 1,
-"Enable this option to load the previously saved configuration file\n"
-"for all of the sound driver parameters.\n"))
+      "Enable this option to load the previously saved configuration file\n"
+			    "for all of the sound driver parameters.\n"))
 	if (use_old_config (oldconf))
 	  exit (0);
     }
@@ -1308,28 +1302,28 @@
   if (selected_options & B (OPT_SB))
     {
       if (think_positively (
-        "Support for the SG NX Pro mixer", 0,
-        "Enable this if you want to support the additional mixer functions\n"
-        "provided on Sound Galaxy NX Pro sound cards.\n"))
+			     "Support for the SG NX Pro mixer", 0,
+       "Enable this if you want to support the additional mixer functions\n"
+			  "provided on Sound Galaxy NX Pro sound cards.\n"))
 	printf ("#define __SGNXPRO__\n");
     }
 
   if (selected_options & B (OPT_SB))
     {
       if (think_positively ("Support for the MV Jazz16 (ProSonic etc.)", 0,
-      "Enable this if you have an MV Jazz16 or ProSonic sound card.\n"))
+	  "Enable this if you have an MV Jazz16 or ProSonic sound card.\n"))
 	{
 	  if (think_positively ("Do you have SoundMan Wave", 0,
- "Enable this option of you have the Logitech SoundMan Wave sound card.\n"))
+				"Enable this option of you have the Logitech SoundMan Wave sound card.\n"))
 	    {
 	      printf ("#define SM_WAVE\n");
 
 	    midi0001_again:
 	      if (think_positively (
-"Do you have access to the MIDI0001.BIN file", 1,
-"The Logitech SoundMan Wave has a microcontroller which must be\n"
-"initialized before MIDI emulation works. This is possible only if the\n"
-"microcode file is compiled into the driver.\n"))
+			   "Do you have access to the MIDI0001.BIN file", 1,
+				     "The Logitech SoundMan Wave has a microcontroller which must be\n"
+				     "initialized before MIDI emulation works. This is possible only if the\n"
+			   "microcode file is compiled into the driver.\n"))
 		{
 		  char            path[512];
 
@@ -1343,8 +1337,8 @@
 		      fprintf (stderr, "Couldn't open file %s\n",
 			       path);
 		      if (think_positively ("Try again with correct path", 1,
-"The specified file could not be opened. Enter the correct path to the\n"
-"file.\n"))
+					    "The specified file could not be opened. Enter the correct path to the\n"
+					    "file.\n"))
 			goto midi0001_again;
 		    }
 		  else
@@ -1360,13 +1354,13 @@
   if (selected_options & B (OPT_SB))
     {
       if (think_positively ("Do you have a Logitech SoundMan Games", 0,
-"The Logitech SoundMan Games supports 44 kHz in stereo while the\n"
-"standard SB Pro supports just 22 kHz stereo. You have the option of\n"
-"enabling SM Games mode.  However, enable it only if you are sure that\n"
-"your card is an SM Games. Enabling this feature with a plain old SB\n"
-"Pro will cause troubles with stereo mode.\n\n"
-"DANGER! Read the above once again before answering 'y'\n"
-"Answer 'n' if you are unsure what to do!\n"))
+	 "The Logitech SoundMan Games supports 44 kHz in stereo while the\n"
+      "standard SB Pro supports just 22 kHz stereo. You have the option of\n"
+			    "enabling SM Games mode.  However, enable it only if you are sure that\n"
+      "your card is an SM Games. Enabling this feature with a plain old SB\n"
+			    "Pro will cause troubles with stereo mode.\n\n"
+		  "DANGER! Read the above once again before answering 'y'\n"
+			    "Answer 'n' if you are unsure what to do!\n"))
 	printf ("#define SM_GAMES\n");
     }
 
@@ -1378,10 +1372,10 @@
 	{
 
 	  if (think_positively (
-"Do you want support for the Audio Excel SoundBlaster Pro mode",
-1,
-"Enable this option if you want the Audio Excel sound card to operate\n"
-"in SoundBlaster Pro mode.\n"))
+	    "Do you want support for the Audio Excel SoundBlaster Pro mode",
+				 1,
+				 "Enable this option if you want the Audio Excel sound card to operate\n"
+				 "in SoundBlaster Pro mode.\n"))
 	    {
 	      printf ("#define AEDSP16_SBPRO\n");
 	      sel1 = 1;
@@ -1390,12 +1384,12 @@
 
       if ((selected_options & B (OPT_MSS)) && (sel1 == 0))
 	{
-	  
+
 	  if (think_positively (
-"Do you want support for the Audio Excel Microsoft Sound System mode",
-1,
-"Enable this option if you want the Audio Excel sound card to operate\n"
-"in Microsoft Sound System mode.\n"))
+				 "Do you want support for the Audio Excel Microsoft Sound System mode",
+				 1,
+				 "Enable this option if you want the Audio Excel sound card to operate\n"
+				 "in Microsoft Sound System mode.\n"))
 	    {
 	      printf ("#define AEDSP16_MSS\n");
 	      sel1 = 1;
@@ -1416,8 +1410,8 @@
     {
     genld_again:
       if (think_positively ("Do you wish to include an LD file", 1,
-     "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n"
-     "file then you must include the LD in the kernel.\n"))
+			    "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n"
+		      "file then you must include the LD in the kernel.\n"))
 	{
 	  char            path[512];
 
@@ -1428,9 +1422,9 @@
 
 	  if (!bin2hex (path, "synth-ld.h", "pss_synth"))
 	    {
-              fprintf (stderr, "couldn't open `%s' as the LD file\n", path);
+	      fprintf (stderr, "couldn't open `%s' as the LD file\n", path);
 	      if (think_positively ("try again with correct path", 1,
-                "The given LD file could not opened.\n"))
+				    "The given LD file could not opened.\n"))
 		goto genld_again;
 	    }
 	  else
@@ -1455,12 +1449,12 @@
     hex2hex_again:
 
       if (think_positively ("Do you want to include TRXPRO.HEX in your kernel",
-      1,
-"The MediaTriX AudioTrix Pro has an onboard microcontroller which\n"
-"needs to be initialized by downloading the code from the file TRXPRO.HEX\n"
-"in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n"
-"you may skip this step. However, the SB and MPU-401 modes of AudioTriX\n"
-"Pro will not work without this file!\n"))
+			    1,
+	"The MediaTriX AudioTrix Pro has an onboard microcontroller which\n"
+			    "needs to be initialized by downloading the code from the file TRXPRO.HEX\n"
+			    "in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n"
+			    "you may skip this step. However, the SB and MPU-401 modes of AudioTriX\n"
+			    "Pro will not work without this file!\n"))
 	{
 	  char            path[512];
 
@@ -1479,7 +1473,7 @@
   if (!(selected_options & ANY_DEVS))
     {
       printf ("invalid_configuration__run_make_config_again\n");
-      fprintf (stderr,"\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device    ***\n\n");
+      fprintf (stderr, "\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device    ***\n\n");
       exit (0);
     }
 
@@ -1516,12 +1510,13 @@
 
   if (!old_config_used)
     {
-      char str[255];
-      sprintf(str, "Save copy of this configuration to `%s'", oldconf);
-      if (think_positively (str, 1, 
-"If you enable this option then the sound driver configuration is\n"
-"saved to a file. If you later need to recompile the kernel you have\n"
-"the option of using the saved configuration.\n"))
+      char            str[255];
+
+      sprintf (str, "Save copy of this configuration to `%s'", oldconf);
+      if (think_positively (str, 1,
+	"If you enable this option then the sound driver configuration is\n"
+      "saved to a file. If you later need to recompile the kernel you have\n"
+			  "the option of using the saved configuration.\n"))
 	{
 	  char            cmd[200];
 
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v1.3.77/linux/drivers/sound/dev_table.h	Sun Mar 17 09:04:07 1996
+++ linux/drivers/sound/dev_table.h	Sun Mar 24 22:49:41 1996
@@ -71,8 +71,8 @@
 #define MAX_SUB_BUFFERS		(32*MAX_REALTIME_FACTOR)
 
 #define DMODE_NONE		0
-#define DMODE_OUTPUT		1
-#define DMODE_INPUT		2
+#define DMODE_OUTPUT		PCM_ENABLE_OUTPUT
+#define DMODE_INPUT		PCM_ENABLE_INPUT
 
 struct dma_buffparms {
 	int      dma_mode;	/* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
@@ -96,6 +96,8 @@
 #define DMA_STARTED	0x00000008
 #define DMA_EMPTY	0x00000010	
 #define DMA_ALLOC_DONE	0x00000020
+#define DMA_SYNCING	0x00000040
+#define DMA_CLEAN	0x00000080
 
 	int      open_mode;
 
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c
--- v1.3.77/linux/drivers/sound/dmabuf.c	Fri Mar 15 16:03:17 1996
+++ linux/drivers/sound/dmabuf.c	Sun Mar 24 22:49:59 1996
@@ -360,6 +360,8 @@
       save_flags (flags);
       cli ();
 
+      audio_devs[dev]->flags |= DMA_SYNCING;
+
       audio_devs[dev]->dmap_out->underrun_count = 0;
       while (!current_got_fatal_signal ()
 	     && audio_devs[dev]->dmap_out->qlen
@@ -384,10 +386,12 @@
 	  };
 	  if ((out_sleep_flag[dev].mode & WK_TIMEOUT))
 	    {
+	      audio_devs[dev]->flags &= ~DMA_SYNCING;
 	      restore_flags (flags);
 	      return audio_devs[dev]->dmap_out->qlen;
 	    }
 	}
+      audio_devs[dev]->flags &= ~DMA_SYNCING;
       restore_flags (flags);
 
       /*
@@ -1023,6 +1027,8 @@
   int             abort, err = EIO;
   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 
+  dmap->flags &= ~DMA_CLEAN;
+
   if (audio_devs[dev]->dmap_out->mapping_flags & DMA_MAP_MAPPED)
     {
       printk ("Sound: Can't write to mmapped device (3)\n");
@@ -1165,6 +1171,7 @@
   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 
   dmap->cfrag = -1;
+
 /*
  * Bypass buffering if using mmaped access
  */
@@ -1401,7 +1408,8 @@
 	{
 	  dmap->underrun_count++;
 
-	  if (dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY)
+	  if (!(dmap->flags & DMA_CLEAN) &&
+	      (audio_devs[dev]->flags & DMA_SYNCING || dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY))
 	    {
 	      dmap->qlen = 0;
 	      force_restart (dev, dmap);
@@ -1624,6 +1632,7 @@
 
 	  save_flags (flags);
 	  cli ();
+
 	  in_sleep_flag[dev].mode = WK_SLEEP;
 	  module_select_wait (&in_sleeper[dev], wait);
 	  restore_flags (flags);
@@ -1650,6 +1659,7 @@
 	{
 	  save_flags (flags);
 	  cli ();
+
 	  in_sleep_flag[dev].mode = WK_SLEEP;
 	  module_select_wait (&in_sleeper[dev], wait);
 	  restore_flags (flags);
@@ -1668,6 +1678,7 @@
 
 	  save_flags (flags);
 	  cli ();
+
 	  out_sleep_flag[dev].mode = WK_SLEEP;
 	  module_select_wait (&out_sleeper[dev], wait);
 	  restore_flags (flags);
@@ -1688,6 +1699,7 @@
 	{
 	  save_flags (flags);
 	  cli ();
+
 	  out_sleep_flag[dev].mode = WK_SLEEP;
 	  module_select_wait (&out_sleeper[dev], wait);
 	  restore_flags (flags);
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
--- v1.3.77/linux/drivers/sound/gus_wave.c	Fri Mar 15 16:03:17 1996
+++ linux/drivers/sound/gus_wave.c	Sun Mar 24 22:50:04 1996
@@ -768,7 +768,7 @@
 
   irq_image = 0;
   tmp = gus_irq_map[gus_irq];
-  if (!tmp)
+  if (!gus_pnp_flag && !tmp)
     printk ("Warning! GUS IRQ not selected\n");
   irq_image |= tmp;
   irq_image |= 0x40;		/* Combine IRQ1 (GF1) and IRQ2 (Midi) */
@@ -1658,7 +1658,7 @@
 	  blk_sz = blk_end - target;
 	}
 
-      if (gus_no_dma)
+      if (gus_pnp_flag || gus_no_dma)
 	{
 	  /*
 	   * For some reason the DMA is not possible. We have to use PIO.
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c
--- v1.3.77/linux/drivers/sound/mad16.c	Wed Feb 28 11:50:08 1996
+++ linux/drivers/sound/mad16.c	Sun Mar 24 22:54:13 1996
@@ -23,7 +23,6 @@
  */
 #include <linux/config.h>
 
-
 /*
  * sound/mad16.c
  *
@@ -32,6 +31,7 @@
  *      OPTi 82C928     MAD16           (replaced by C929)
  *      OAK OTI-601D    Mozart
  *      OPTi 82C929     MAD16 Pro
+ *      OPTi 82C930     (Not supported yet)
  *
  * These audio interface chips don't prduce sound themselves. They just
  * connect some other components (OPL-[234] and a WSS compatible codec)
@@ -82,6 +82,7 @@
 #define C928	1
 #define MOZART	2
 #define C929	3
+#define C930	4
 
 /*
  *    Registers
@@ -92,6 +93,7 @@
  *      only until the next I/O read or write.
  */
 
+#define MC0_PORT	0xf8c	/* Dummy port */
 #define MC1_PORT	0xf8d	/* SB address, CDROM interface type, joystick */
 #define MC2_PORT	0xf8e	/* CDROM address, IRQ, DMA, plus OPL4 bit */
 #define MC3_PORT	0xf8f
@@ -100,6 +102,11 @@
 #define MC5_PORT	0xf91
 #define MC6_PORT	0xf92
 #define MC7_PORT	0xf93
+#define MC8_PORT	0xf94
+#define MC9_PORT	0xf95
+#define MC10_PORT	0xf96
+#define MC11_PORT	0xf97
+#define MC12_PORT	0xf98
 
 static int      board_type = C928;
 
@@ -128,6 +135,7 @@
     case C929:
       outb (0xE3, PASSWD_REG);
       break;
+
     }
 
   tmp = inb (port);
@@ -154,6 +162,7 @@
     case C929:
       outb (0xE3, PASSWD_REG);
       break;
+
     }
 
   outb ((unsigned char) (value & 0xff), port);
@@ -164,6 +173,7 @@
 detect_mad16 (void)
 {
   unsigned char   tmp, tmp2;
+  int             i;
 
 /*
  * Check that reading a register doesn't return bus float (0xff)
@@ -176,6 +186,10 @@
       DDB (printk ("MC1_PORT returned 0xff\n"));
       return 0;
     }
+
+  for (i = 0xf8d; i <= 0xf98; i++)
+    DDB (printk ("Port %0x (init value) = %0x\n", i, mad_read (i)));
+
 /*
  * Now check that the gate is closed on first I/O after writing
  * the password. (This is how a MAD16 compatible card works).
@@ -188,7 +202,6 @@
     }
 
   mad_write (MC1_PORT, tmp ^ 0x80);	/* Togge a bit */
-
   if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80))	/* Compare the bit */
     {
       mad_write (MC1_PORT, tmp);	/* Restore */
@@ -201,6 +214,67 @@
 
 }
 
+static int
+wss_init (struct address_info *hw_config)
+{
+  int             ad_flags = 0;
+
+/*
+ *    Verify the WSS parameters
+ */
+
+  if (check_region (hw_config->io_base, 8))
+    {
+      printk ("MSS: I/O port conflict\n");
+      return 0;
+    }
+
+  if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
+    return 0;
+  /*
+     * Check if the IO port returns valid signature. The original MS Sound
+     * system returns 0x04 while some cards (AudioTriX Pro for example)
+     * return 0x00.
+   */
+
+  if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
+      (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
+    {
+      DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
+		   hw_config->io_base, inb (hw_config->io_base + 3)));
+      return 0;
+    }
+
+  if (hw_config->irq > 11)
+    {
+      printk ("MSS: Bad IRQ %d\n", hw_config->irq);
+      return 0;
+    }
+
+  if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
+    {
+      printk ("MSS: Bad DMA %d\n", hw_config->dma);
+      return 0;
+    }
+
+  /*
+     * Check that DMA0 is not in use with a 8 bit board.
+   */
+
+  if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
+    {
+      printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
+      return 0;
+    }
+
+  if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
+    {
+      printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
+    }
+
+  return 1;
+}
+
 int
 probe_mad16 (struct address_info *hw_config)
 {
@@ -238,9 +312,13 @@
       DDB (printk ("Detect using password = 0xE3\n"));
 
       if (!detect_mad16 ())
-	return 0;
-
-      DDB (printk ("mad16.c: 82C929 detected\n"));
+	{
+	  return 0;
+	}
+      else
+	{
+	  DDB (printk ("mad16.c: 82C929 detected\n"));
+	}
     }
   else
     {
@@ -259,7 +337,7 @@
     }
 
   for (i = 0xf8d; i <= 0xf93; i++)
-    DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
+    DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
 
 /*
  * Set the WSS address
@@ -323,59 +401,9 @@
     }
 
   for (i = 0xf8d; i <= 0xf93; i++)
-    DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
-
-/*
- *    Verify the WSS parameters
- */
-
-  if (check_region (hw_config->io_base, 8))
-    {
-      printk ("MSS: I/O port conflict\n");
-      return 0;
-    }
-
-  /*
-     * Check if the IO port returns valid signature. The original MS Sound
-     * system returns 0x04 while some cards (AudioTriX Pro for example)
-     * return 0x00.
-   */
-
-  if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
-      (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
-    {
-      DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
-		   hw_config->io_base, inb (hw_config->io_base + 3)));
-      return 0;
-    }
-
-  if (hw_config->irq > 11)
-    {
-      printk ("MSS: Bad IRQ %d\n", hw_config->irq);
-      return 0;
-    }
-
-  if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
-    {
-      printk ("MSS: Bad DMA %d\n", hw_config->dma);
-      return 0;
-    }
+    DDB (printk ("port %03x after init = %02x\n", i, mad_read (i)));
 
-  /*
-     * Check that DMA0 is not in use with a 8 bit board.
-   */
-
-  if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
-    {
-      printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
-      return 0;
-    }
-
-  if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
-    {
-      printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
-      return 0;
-    }
+  wss_init (hw_config);
 
   return 1;
 }
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/midibuf.c linux/drivers/sound/midibuf.c
--- v1.3.77/linux/drivers/sound/midibuf.c	Wed Feb 14 14:37:14 1996
+++ linux/drivers/sound/midibuf.c	Sun Mar 24 22:50:08 1996
@@ -513,6 +513,7 @@
     case SEL_IN:
       if (!DATA_AVAIL (midi_in_buf[dev]))
 	{
+
 	  input_sleep_flag[dev].mode = WK_SLEEP;
 	  module_select_wait (&input_sleeper[dev], wait);
 	  return 0;
@@ -523,6 +524,7 @@
     case SEL_OUT:
       if (SPACE_AVAIL (midi_out_buf[dev]))
 	{
+
 	  midi_sleep_flag[dev].mode = WK_SLEEP;
 	  module_select_wait (&midi_sleeper[dev], wait);
 	  return 0;
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/sb16_dsp.c linux/drivers/sound/sb16_dsp.c
--- v1.3.77/linux/drivers/sound/sb16_dsp.c	Fri Mar 15 16:03:18 1996
+++ linux/drivers/sound/sb16_dsp.c	Mon Mar 25 09:25:26 1996
@@ -157,7 +157,7 @@
     {
     case SOUND_PCM_WRITE_RATE:
       if (local)
-	return dsp_set_speed ((int) arg);
+	return dsp_set_speed ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_speed (get_fs_long ((long *) arg)));
 
     case SOUND_PCM_READ_RATE:
@@ -167,12 +167,12 @@
 
     case SNDCTL_DSP_STEREO:
       if (local)
-	return dsp_set_stereo ((int) arg);
+	return dsp_set_stereo ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg)));
 
     case SOUND_PCM_WRITE_CHANNELS:
       if (local)
-	return dsp_set_stereo ((int) arg - 1) + 1;
+	return dsp_set_stereo ((long) arg - 1) + 1;
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1);
 
     case SOUND_PCM_READ_CHANNELS:
@@ -182,7 +182,7 @@
 
     case SNDCTL_DSP_SETFMT:
       if (local)
-	return dsp_set_bits ((int) arg);
+	return dsp_set_bits ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg)));
 
     case SOUND_PCM_READ_BITS:
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/sb_dsp.c linux/drivers/sound/sb_dsp.c
--- v1.3.77/linux/drivers/sound/sb_dsp.c	Sun Mar 17 09:04:07 1996
+++ linux/drivers/sound/sb_dsp.c	Mon Mar 25 09:25:27 1996
@@ -834,7 +834,7 @@
 
   if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
     {
-      printk ("SB: Audio device or MIDI already in use\n");
+      printk ("SB: Audio device or MIDI already in use.\n");
       return -EBUSY;
     }
 
@@ -938,7 +938,7 @@
     {
     case SOUND_PCM_WRITE_RATE:
       if (local)
-	return dsp_speed ((int) arg);
+	return dsp_speed ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_speed (get_fs_long ((long *) arg)));
       break;
 
@@ -950,7 +950,7 @@
 
     case SOUND_PCM_WRITE_CHANNELS:
       if (local)
-	return dsp_set_stereo ((int) arg - 1) + 1;
+	return dsp_set_stereo ((long) arg - 1) + 1;
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1);
       break;
 
@@ -962,7 +962,7 @@
 
     case SNDCTL_DSP_STEREO:
       if (local)
-	return dsp_set_stereo ((int) arg);
+	return dsp_set_stereo ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg)));
       break;
 
@@ -971,7 +971,7 @@
        */
     case SNDCTL_DSP_SETFMT:
       if (local)
-	return dsp_set_bits ((int) arg);
+	return dsp_set_bits ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg)));
       break;
 
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c
--- v1.3.77/linux/drivers/sound/sequencer.c	Wed Feb 28 11:50:08 1996
+++ linux/drivers/sound/sequencer.c	Sun Mar 24 22:50:23 1996
@@ -1908,12 +1908,12 @@
       cli ();
       if (!iqlen)
 	{
+
 	  midi_sleep_flag.mode = WK_SLEEP;
 	  module_select_wait (&midi_sleeper, wait);
 	  restore_flags (flags);
 	  return 0;
 	}
-      midi_sleep_flag.mode &= ~WK_SLEEP;
       restore_flags (flags);
       return 1;
       break;
@@ -1923,12 +1923,12 @@
       cli ();
       if ((SEQ_MAX_QUEUE - qlen) < output_treshold)
 	{
+
 	  seq_sleep_flag.mode = WK_SLEEP;
 	  module_select_wait (&seq_sleeper, wait);
 	  restore_flags (flags);
 	  return 0;
 	}
-      seq_sleep_flag.mode &= ~WK_SLEEP;
       restore_flags (flags);
       return 1;
       break;
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/sound_config.h linux/drivers/sound/sound_config.h
--- v1.3.77/linux/drivers/sound/sound_config.h	Fri Mar 15 16:03:18 1996
+++ linux/drivers/sound/sound_config.h	Sun Mar 24 22:49:43 1996
@@ -172,6 +172,7 @@
 #define WK_TIMEOUT	0x02
 #define WK_SIGNAL	0x04
 #define WK_SLEEP	0x08
+#define WK_SELECT	0x10
 
 #define OPEN_READ	PCM_ENABLE_INPUT
 #define OPEN_WRITE	PCM_ENABLE_OUTPUT
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/sound_switch.c linux/drivers/sound/sound_switch.c
--- v1.3.77/linux/drivers/sound/sound_switch.c	Tue Mar  5 10:11:06 1996
+++ linux/drivers/sound/sound_switch.c	Mon Mar 25 09:25:27 1996
@@ -523,12 +523,12 @@
   if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0)	/* Mixer ioctl */
     if ((dev & 0x0f) != SND_DEV_CTL)
       {
+#ifdef CONFIG_AUDIO
 	int             dtype = dev & 0x0f;
 	int             mixdev;
 
 	switch (dtype)
 	  {
-#ifdef CONFIG_AUDIO
 	  case SND_DEV_DSP:
 	  case SND_DEV_DSP16:
 	  case SND_DEV_AUDIO:
@@ -536,12 +536,9 @@
 	    if (mixdev < 0 || mixdev >= num_mixers)
 	      return -ENXIO;
 	    return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
-	    break;
-#endif
-
-	  default:
-	    return mixer_devs[0]->ioctl (0, cmd, arg);
 	  }
+#endif
+	  return mixer_devs[0]->ioctl (0, cmd, arg);
       }
 
   switch (dev & 0x0f)
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v1.3.77/linux/drivers/sound/soundcard.c	Fri Mar 15 16:03:18 1996
+++ linux/drivers/sound/soundcard.c	Mon Mar 25 09:25:27 1996
@@ -389,8 +389,6 @@
 
 #endif
 
-static int      debugmem = 0;	/* switched off by default */
-
 static int      sound[20] =
 {0};
 
@@ -442,6 +440,11 @@
 {
   int             i;
 
+  if (MOD_IN_USE)
+    {
+      return;
+    }
+
   if (chrdev_registered)
     module_unregister_chrdev (sound_major, "sound");
 
@@ -461,6 +464,7 @@
 	printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i);
 	sound_free_dma (i);
       }
+
 }
 #endif
 
@@ -599,6 +603,8 @@
 fatal_error__This_version_is_not_compatible_with_this_kernel;
 #endif
 
+static int      debugmem = 0;	/* switched off by default */
+
 static int      dma_buffsize = DSP_BUFFSIZE;
 
 int
@@ -647,7 +653,7 @@
 
       audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
 
-      if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, 1)) == NULL)
+      if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
 	audio_devs[dev]->buffsize /= 2;
     }
 
@@ -726,6 +732,7 @@
   printk ("Exited sound_map_buffer()\n");
   return -EINVAL;
 }
+#endif
 
 void
 conf_printf (char *name, struct address_info *hw_config)
@@ -768,4 +775,3 @@
 
   printk ("\n");
 }
-#endif
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/soundvers.h linux/drivers/sound/soundvers.h
--- v1.3.77/linux/drivers/sound/soundvers.h	Fri Mar 15 16:03:18 1996
+++ linux/drivers/sound/soundvers.h	Sun Mar 24 22:56:08 1996
@@ -1,2 +1,2 @@
-#define SOUND_VERSION_STRING "3.5-960313"
+#define SOUND_VERSION_STRING "3.5.1-960324"
 #define SOUND_INTERNAL_VERSION 0x030500
diff -u --recursive --new-file v1.3.77/linux/drivers/sound/sscape.c linux/drivers/sound/sscape.c
--- v1.3.77/linux/drivers/sound/sscape.c	Tue Mar  5 10:11:06 1996
+++ linux/drivers/sound/sscape.c	Sun Mar 24 22:50:27 1996
@@ -306,7 +306,7 @@
   unsigned char   bits, tmp;
   static int      debug = 0;
 
-  printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG)));
+  bits = sscape_read (devc, GA_INTSTAT_REG);
   if ((sscape_sleep_flag.mode & WK_SLEEP))
     {
       {
diff -u --recursive --new-file v1.3.77/linux/fs/binfmt_script.c linux/fs/binfmt_script.c
--- v1.3.77/linux/fs/binfmt_script.c	Tue Mar  5 10:11:06 1996
+++ linux/fs/binfmt_script.c	Sat Mar 23 14:46:40 1996
@@ -13,8 +13,8 @@
 
 static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-	char *cp, *interp, *i_name, *i_arg, *page;
-	int retval, offset;
+	char *cp, *interp, *i_name, *i_arg;
+	int retval;
 	if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
 		return -ENOEXEC;
 	/*
@@ -60,16 +60,7 @@
 	 * This is done in reverse order, because of how the
 	 * user environment and arguments are stored.
 	 */
-	if (bprm->argc) {
-		offset = bprm->p % PAGE_SIZE;
-		page = (char*)bprm->page[bprm->p/PAGE_SIZE];
-		while(bprm->p++,*(page+offset++))
-			if(offset==PAGE_SIZE){
-				offset=0;
-				page = (char*)bprm->page[bprm->p/PAGE_SIZE];
-			}
-		bprm->argc--;
-	}
+	remove_arg_zero(bprm);
 	bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
 	bprm->argc++;
 	if (i_arg) {
diff -u --recursive --new-file v1.3.77/linux/fs/dcache.c linux/fs/dcache.c
--- v1.3.77/linux/fs/dcache.c	Fri Nov 17 08:42:27 1995
+++ linux/fs/dcache.c	Sun Mar 24 12:09:36 1996
@@ -18,8 +18,6 @@
  * string-hash computed over the name. 
  */
 
-#include <stddef.h>
-
 #include <linux/fs.h>
 #include <linux/string.h>
 
@@ -51,9 +49,11 @@
 	struct dir_cache_entry * next_lru,  * prev_lru;
 };
 
+#define dcache_offset(x) ((unsigned long)&((struct dir_cache_entry*)0)->x)
+#define dcache_datalen (dcache_offset(lru_head) - dcache_offset(dc_dev))
+
 #define COPYDATA(de, newde) \
-memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, \
-sizeof(kdev_t) + 3*sizeof(unsigned long) + 1 + DCACHE_NAME_LEN)
+memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, dcache_datalen)
 
 static struct dir_cache_entry level1_cache[DCACHE_SIZE];
 static struct dir_cache_entry level2_cache[DCACHE_SIZE];
@@ -69,22 +69,27 @@
  * The hash-queues are also doubly-linked circular lists, but the head is
  * itself on the doubly-linked list, not just a pointer to the first entry.
  */
-#define DCACHE_HASH_QUEUES 19
+#define DCACHE_HASH_QUEUES 32
 #define hash_fn(dev,dir,namehash) ((HASHDEV(dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES)
 
 static struct hash_list hash_table[DCACHE_HASH_QUEUES];
 
 static inline void remove_lru(struct dir_cache_entry * de)
 {
-	de->next_lru->prev_lru = de->prev_lru;
-	de->prev_lru->next_lru = de->next_lru;
+	struct dir_cache_entry * next = de->next_lru;
+	struct dir_cache_entry * prev = de->prev_lru;
+
+	next->prev_lru = prev;
+	prev->next_lru = next;
 }
 
 static inline void add_lru(struct dir_cache_entry * de, struct dir_cache_entry *head)
 {
+	struct dir_cache_entry * prev = head->prev_lru;
+
 	de->next_lru = head;
-	de->prev_lru = head->prev_lru;
-	de->prev_lru->next_lru = de;
+	de->prev_lru = prev;
+	prev->next_lru = de;
 	head->prev_lru = de;
 }
 
@@ -104,7 +109,9 @@
  */
 static inline unsigned long namehash(const char * name, int len)
 {
-	return len * *(const unsigned char *) name;
+	return len +
+		((const unsigned char *) name)[0]+
+		((const unsigned char *) name)[len-1];
 }
 
 /*
@@ -112,18 +119,22 @@
  */
 static inline void remove_hash(struct dir_cache_entry * de)
 {
-	if (de->h.next) {
-		de->h.next->h.prev = de->h.prev;
-		de->h.prev->h.next = de->h.next;
+	struct dir_cache_entry * next = de->h.next;
+
+	if (next) {
+		struct dir_cache_entry * prev = de->h.prev;
+		next->h.prev = prev;
+		prev->h.next = next;
 		de->h.next = NULL;
 	}
 }
 
 static inline void add_hash(struct dir_cache_entry * de, struct hash_list * hash)
 {
-	de->h.next = hash->next;
+	struct dir_cache_entry * next = hash->next;
+	de->h.next = next;
 	de->h.prev = (struct dir_cache_entry *) hash;
-	hash->next->h.prev = de;
+	next->h.prev = de;
 	hash->next = de;
 }
 
diff -u --recursive --new-file v1.3.77/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
--- v1.3.77/linux/fs/isofs/inode.c	Wed Feb  7 15:11:31 1996
+++ linux/fs/isofs/inode.c	Sun Mar 24 14:07:42 1996
@@ -137,7 +137,9 @@
 		  if (*vpnt) return 0;
 		  switch(*this_char) {
 		  case 'b':
-		    if (ivalue != 1024 && ivalue != 2048) return 0;
+		    if (   ivalue != 512 
+			&& ivalue != 1024 
+			&& ivalue != 2048) return 0;
 		    popt->blocksize = ivalue;
 		    break;
 		  case 'u':
@@ -200,6 +202,7 @@
 	int high_sierra;
 	kdev_t dev = s->s_dev;
 	unsigned int vol_desc_start;
+	int orig_zonesize;
 
 	struct iso_volume_descriptor *vdp;
 	struct hs_volume_descriptor *hdp;
@@ -324,6 +327,7 @@
 	
 	/* RDE: convert log zone size to bit shift */
 
+	orig_zonesize = s -> u.isofs_sb.s_log_zone_size;
 	switch (s -> u.isofs_sb.s_log_zone_size)
 	  { case  512: s -> u.isofs_sb.s_log_zone_size =  9; break;
 	    case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break;
@@ -336,7 +340,8 @@
 
 	/* RDE: data zone now byte offset! */
 
-	s->u.isofs_sb.s_firstdatazone = (isonum_733( rootp->extent) 
+	s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) + 
+					   isonum_711 (rootp->ext_attr_length))
 					 << s -> u.isofs_sb.s_log_zone_size);
 	s->s_magic = ISOFS_SUPER_MAGIC;
 	
@@ -354,11 +359,32 @@
 	       1UL << s->u.isofs_sb.s_log_zone_size);
 	printk(KERN_DEBUG "First datazone:%ld   Root inode number %d\n",
 	       s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size,
-	       isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size);
+	       (isonum_733(rootp->extent) + isonum_711(rootp->ext_attr_length))
+			<< s -> u.isofs_sb.s_log_zone_size);
 	if(high_sierra) printk(KERN_DEBUG "Disc in High Sierra format.\n");
 	unlock_super(s);
 	/* set up enough so that it can read an inode */
 	
+	/*
+	 * Force the blocksize to 512 for 512 byte sectors.  The file
+	 * read primitives really get it wrong in a bad way if we don't
+	 * do this.
+	 */
+	if( orig_zonesize < opt.blocksize )
+	  {
+	    opt.blocksize = orig_zonesize;
+	    blocksize_bits = 0;
+	    {
+	      int i = opt.blocksize;
+	      while (i != 1){
+		blocksize_bits++;
+		i >>=1;
+	      }
+	    }
+	    set_blocksize(dev, opt.blocksize);
+	    printk(KERN_DEBUG "Forcing new log zone size:%d\n", opt.blocksize);
+	  }
+
 	s->s_dev = dev;
 	s->s_op = &isofs_sops;
 	s->u.isofs_sb.s_mapping = opt.map;
@@ -376,7 +402,9 @@
 	s->u.isofs_sb.s_mode = opt.mode & 0777;
 	s->s_blocksize = opt.blocksize;
 	s->s_blocksize_bits = blocksize_bits;
-	s->s_mounted = iget(s, isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size);
+	s->s_mounted = iget(s, (isonum_733(rootp->extent) + 
+			    isonum_711(rootp->ext_attr_length))
+				<< s -> u.isofs_sb.s_log_zone_size);
 	unlock_super(s);
 
 	if (!(s->s_mounted)) {
diff -u --recursive --new-file v1.3.77/linux/fs/ncpfs/ioctl.c linux/fs/ncpfs/ioctl.c
--- v1.3.77/linux/fs/ncpfs/ioctl.c	Tue Mar  5 10:11:07 1996
+++ linux/fs/ncpfs/ioctl.c	Fri Mar 22 12:58:41 1996
@@ -23,6 +23,26 @@
 	struct ncp_fs_info info;
 	struct ncp_server *server = NCP_SERVER(inode);
 
+	/*
+	 * Binary compatible with 1.3.XX releases.
+	 * Take this out in 2.1.0 development series.
+	 * <mec@duracef.shout.net> 12 Mar 1996
+	 */
+	switch(cmd) {
+	case _IOR('n', 1, unsigned char *):
+	    cmd = NCP_IOC_NCPREQUEST;
+	    break;
+	case _IOR('u', 1, uid_t):
+	    cmd = NCP_IOC_GETMOUNTUID;
+	    break;
+	case _IO('l', 1):
+	    cmd = NCP_IOC_CONN_LOGGED_IN;
+	    break;
+	case _IOWR('i', 1, unsigned char *):
+	    cmd = NCP_IOC_GET_FS_INFO;
+	    break;
+	}
+
 	switch(cmd) {
 	case NCP_IOC_NCPREQUEST:
 
@@ -106,10 +126,12 @@
 			return -EINVAL;
 		}
 
-		info.addr        = server->m.serv_addr;
-		info.mounted_uid = server->m.mounted_uid;
-		info.connection  = server->connection;
-		info.buffer_size = server->buffer_size;
+		info.addr          = server->m.serv_addr;
+		info.mounted_uid   = server->m.mounted_uid;
+		info.connection    = server->connection;
+		info.buffer_size   = server->buffer_size;
+		info.volume_number = NCP_ISTRUCT(inode)->volNumber;
+		info.directory_id  = NCP_ISTRUCT(inode)->DosDirNum;
 
 		memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
 		return 0;		
diff -u --recursive --new-file v1.3.77/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
--- v1.3.77/linux/fs/ncpfs/ncplib_kernel.c	Tue Mar  5 10:11:07 1996
+++ linux/fs/ncpfs/ncplib_kernel.c	Fri Mar 22 12:58:41 1996
@@ -217,14 +217,9 @@
 	ncp_add_byte(server, 0);
 	ncp_add_mem(server, file_id, 6);
 
-	if ((result = ncp_request(server, 66)) != 0)
-	{
-		ncp_unlock_server(server);
-		return result;
-	}
-
+	result = ncp_request(server, 66);
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
 static void
@@ -366,14 +361,9 @@
 	ncp_add_handle_path(server, file->volNumber,
 			    file->DosDirNum, 1, NULL);
 
-	if ((result = ncp_request(server, 87)) != 0)
-	{
-		ncp_unlock_server(server);
-		return result;
-	}
-
+	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
 int
@@ -390,14 +380,9 @@
 	ncp_add_handle_path(server, dir->volNumber,
 			    dir->DosDirNum, 1, name);
 	
-	if ((result = ncp_request(server, 87)) != 0)
-	{
-		ncp_unlock_server(server);
-		return result;
-	}
-
+	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
 static inline void
diff -u --recursive --new-file v1.3.77/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v1.3.77/linux/fs/nfs/inode.c	Wed Mar 13 10:09:20 1996
+++ linux/fs/nfs/inode.c	Sun Mar 24 20:07:00 1996
@@ -80,7 +80,7 @@
  * The way this works is that the mount process passes a structure
  * in the data argument which contains an open socket to the NFS
  * server and the root file handle obtained from the server's mount
- * daemon.  We stash theses away in the private superblock fields.
+ * daemon.  We stash these away in the private superblock fields.
  * Later we can add other mount parameters like caching values.
  */
 
@@ -169,7 +169,7 @@
 	    sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ;
 	  }
 	} else {
-	/*  printk("NFS: coppying passed addr to server->toaddr\n") ;*/
+	/*  printk("NFS: copying passed addr to server->toaddr\n") ;*/
 	  memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr));
 	}
 	/* End of JSP NFS patch */
diff -u --recursive --new-file v1.3.77/linux/fs/super.c linux/fs/super.c
--- v1.3.77/linux/fs/super.c	Wed Mar 13 10:09:21 1996
+++ linux/fs/super.c	Sun Mar 24 20:07:00 1996
@@ -612,6 +612,9 @@
 	struct vfsmount *vfsmnt;
 	int error;
 
+	if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
+		return -EACCES;
+		/*flags |= MS_RDONLY;*/
 	error = namei(dir_name, &dir_i);
 	if (error)
 		return error;
@@ -656,6 +659,7 @@
 static int do_remount_sb(struct super_block *sb, int flags, char *data)
 {
 	int retval;
+	struct vfsmount *vfsmnt;
 	
 	if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
 		return -EACCES;
@@ -671,6 +675,9 @@
 	}
 	sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
 		(flags & MS_RMT_MASK);
+	vfsmnt = lookup_vfsmnt(sb->s_dev);
+	if (vfsmnt)
+		vfsmnt->mnt_flags = sb->s_flags;
 	return 0;
 }
 
diff -u --recursive --new-file v1.3.77/linux/fs/umsdos/ioctl.c linux/fs/umsdos/ioctl.c
--- v1.3.77/linux/fs/umsdos/ioctl.c	Wed Mar 13 10:09:21 1996
+++ linux/fs/umsdos/ioctl.c	Sun Mar 24 20:07:00 1996
@@ -65,8 +65,9 @@
 		in UMSDOS. EPERM is returned for other user.
 	*/
 	/*
-		Well, not all case require write access, but it simplify the code
-		and let's face it, there is only one client (umssync) for all this
+		Well, not all cases require write access, but it simplifies
+		the code, and let's face it, there is only one client (umssync)
+		for all this.
 	*/
 	if ((err = verify_area(VERIFY_WRITE,(void*)data,sizeof(struct umsdos_ioctl))) < 0) {
 		ret = err;
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/apecs.h linux/include/asm-alpha/apecs.h
--- v1.3.77/linux/include/asm-alpha/apecs.h	Sat Feb 17 16:02:53 1996
+++ linux/include/asm-alpha/apecs.h	Sun Mar 24 12:09:36 1996
@@ -334,47 +334,47 @@
  * Data structure for handling APECS machine checks:
  */
 struct el_apecs_sysdata_mcheck {
-    u_long      coma_gcr;                       
-    u_long      coma_edsr;                      
-    u_long      coma_ter;                       
-    u_long      coma_elar;                      
-    u_long      coma_ehar;                      
-    u_long      coma_ldlr;                      
-    u_long      coma_ldhr;                      
-    u_long      coma_base0;                     
-    u_long      coma_base1;                     
-    u_long      coma_base2;                     
-    u_long      coma_cnfg0;                     
-    u_long      coma_cnfg1;                     
-    u_long      coma_cnfg2;                     
-    u_long      epic_dcsr;                      
-    u_long      epic_pear;                      
-    u_long      epic_sear;                      
-    u_long      epic_tbr1;                      
-    u_long      epic_tbr2;                      
-    u_long      epic_pbr1;                      
-    u_long      epic_pbr2;                      
-    u_long      epic_pmr1;                      
-    u_long      epic_pmr2;                      
-    u_long      epic_harx1;                     
-    u_long      epic_harx2;                     
-    u_long      epic_pmlt;                      
-    u_long      epic_tag0;                      
-    u_long      epic_tag1;                      
-    u_long      epic_tag2;                      
-    u_long      epic_tag3;                      
-    u_long      epic_tag4;                      
-    u_long      epic_tag5;                      
-    u_long      epic_tag6;                      
-    u_long      epic_tag7;                      
-    u_long      epic_data0;                     
-    u_long      epic_data1;                     
-    u_long      epic_data2;                     
-    u_long      epic_data3;                     
-    u_long      epic_data4;                     
-    u_long      epic_data5;                     
-    u_long      epic_data6;                     
-    u_long      epic_data7;                     
+    unsigned long coma_gcr;
+    unsigned long coma_edsr;
+    unsigned long coma_ter;
+    unsigned long coma_elar;
+    unsigned long coma_ehar;
+    unsigned long coma_ldlr;
+    unsigned long coma_ldhr;
+    unsigned long coma_base0;
+    unsigned long coma_base1;
+    unsigned long coma_base2;
+    unsigned long coma_cnfg0;
+    unsigned long coma_cnfg1;
+    unsigned long coma_cnfg2;
+    unsigned long epic_dcsr;
+    unsigned long epic_pear;
+    unsigned long epic_sear;
+    unsigned long epic_tbr1;
+    unsigned long epic_tbr2;
+    unsigned long epic_pbr1;
+    unsigned long epic_pbr2;
+    unsigned long epic_pmr1;
+    unsigned long epic_pmr2;
+    unsigned long epic_harx1;
+    unsigned long epic_harx2;
+    unsigned long epic_pmlt;
+    unsigned long epic_tag0;
+    unsigned long epic_tag1;
+    unsigned long epic_tag2;
+    unsigned long epic_tag3;
+    unsigned long epic_tag4;
+    unsigned long epic_tag5;
+    unsigned long epic_tag6;
+    unsigned long epic_tag7;
+    unsigned long epic_data0;
+    unsigned long epic_data1;
+    unsigned long epic_data2;
+    unsigned long epic_data3;
+    unsigned long epic_data4;
+    unsigned long epic_data5;
+    unsigned long epic_data6;
+    unsigned long epic_data7;
 };
 
 #define RTC_PORT(x)	(0x70 + (x))
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h
--- v1.3.77/linux/include/asm-alpha/atomic.h	Thu Mar 21 20:36:53 1996
+++ linux/include/asm-alpha/atomic.h	Sun Mar 24 12:09:36 1996
@@ -1,9 +1,12 @@
-#ifndef __ARCH_I386_ATOMIC__
-#define __ARCH_I386_ATOMIC__
+#ifndef __ARCH_ALPHA_ATOMIC__
+#define __ARCH_ALPHA_ATOMIC__
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
- * resource counting etc..
+ * resource counting etc...
+ *
+ * But use these as seldom as possible since they are much more slower
+ * than regular operations.
  */
 
 /*
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/ioctl.h linux/include/asm-alpha/ioctl.h
--- v1.3.77/linux/include/asm-alpha/ioctl.h	Sat Feb 17 16:02:53 1996
+++ linux/include/asm-alpha/ioctl.h	Sun Mar 24 12:09:36 1996
@@ -37,7 +37,7 @@
 #define _IOC_WRITE	4U
 
 #define _IOC(dir,type,nr,size)			\
-	((__u32)				\
+	((unsigned int)				\
 	 (((dir)  << _IOC_DIRSHIFT) |		\
 	  ((type) << _IOC_TYPESHIFT) |		\
 	  ((nr)   << _IOC_NRSHIFT) |		\
@@ -63,4 +63,4 @@
 #define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
 #define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
 
-#endif
+#endif /* _ALPHA_IOCTL_H */
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/ioctls.h linux/include/asm-alpha/ioctls.h
--- v1.3.77/linux/include/asm-alpha/ioctls.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/ioctls.h	Sun Mar 24 12:09:36 1996
@@ -0,0 +1,102 @@
+#ifndef _ASM_ALPHA_IOCTLS_H
+#define _ASM_ALPHA_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+
+#define TIOCGETP	_IOR('t', 8, struct sgttyb)
+#define TIOCSETP	_IOW('t', 9, struct sgttyb)
+#define TIOCSETN	_IOW('t', 10, struct sgttyb)	/* TIOCSETP wo flush */
+
+#define TIOCSETC	_IOW('t', 17, struct tchars)
+#define TIOCGETC	_IOR('t', 18, struct tchars)
+#define TCGETS		_IOR('t', 19, struct termios)
+#define TCSETS		_IOW('t', 20, struct termios)
+#define TCSETSW		_IOW('t', 21, struct termios)
+#define TCSETSF		_IOW('t', 22, struct termios)
+
+#define TCGETA		_IOR('t', 23, struct termio)
+#define TCSETA		_IOW('t', 24, struct termio)
+#define TCSETAW		_IOW('t', 25, struct termio)
+#define TCSETAF		_IOW('t', 28, struct termio)
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCGLTC	_IOR('t', 116, struct ltchars)
+#define TIOCSLTC	_IOW('t', 117, struct ltchars)
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+
+#define TIOCSTI		0x5412
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+# 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
+
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+# 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
+
+
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+#endif /* _ASM_ALPHA_IOCTLS_H */
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/param.h linux/include/asm-alpha/param.h
--- v1.3.77/linux/include/asm-alpha/param.h	Tue Jan 23 21:15:52 1996
+++ linux/include/asm-alpha/param.h	Sun Mar 24 12:09:37 1996
@@ -1,14 +1,8 @@
-#ifndef _ASMAXP_PARAM_H
-#define _ASMAXP_PARAM_H
-
-#include <linux/config.h>
+#ifndef _ASM_ALPHA_PARAM_H
+#define _ASM_ALPHA_PARAM_H
 
 #ifndef HZ
-# if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB66P)
-#  define HZ	 977	/* Evaluation Boards seem to be a little odd */
-# else
-#  define HZ	1024	/* normal value for Alpha systems */
-# endif
+# define HZ	1024
 #endif
 
 #define EXEC_PAGESIZE	8192
@@ -23,4 +17,4 @@
 
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
 
-#endif
+#endif /* _ASM_ALPHA_PARAM_H */
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/posix_types.h linux/include/asm-alpha/posix_types.h
--- v1.3.77/linux/include/asm-alpha/posix_types.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/posix_types.h	Sun Mar 24 13:16:29 1996
@@ -0,0 +1,94 @@
+#ifndef _ALPHA_POSIX_TYPES_H
+#define _ALPHA_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 int	__dev_t;
+typedef unsigned int	__ino_t;
+typedef unsigned int	__mode_t;
+typedef unsigned short	__nlink_t;
+typedef long		__off_t;
+typedef int		__pid_t;
+typedef unsigned int	__uid_t;
+typedef unsigned int	__gid_t;
+typedef unsigned long	__size_t;
+typedef long		__ssize_t;
+typedef long		__ptrdiff_t;
+typedef long		__time_t;
+typedef long		__clock_t;
+typedef int		__daddr_t;
+typedef char *		__caddr_t;
+
+typedef struct {
+	int	val[2];
+} __fsid_t;
+
+#ifndef __GNUC__
+
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define	__FD_ZERO(set)	\
+  ((void) memset ((__ptr_t) (set), 0, sizeof (__fd_set)))
+
+#else /* __GNUC__ */
+
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __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, __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, __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 case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__fd_set *p)
+{
+	unsigned int *tmp = p->fds_bits;
+	int i;
+
+	if (__builtin_constant_p(__FDSET_INTS)) {
+		switch (__FDSET_INTS) {
+			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;
+		}
+	}
+	i = __FDSET_INTS;
+	while (i) {
+		i--;
+		*tmp = 0;
+		tmp++;
+	}
+}
+
+#endif /* __GNUC__ */
+
+#endif /* _ALPHA_POSIX_TYPES_H */
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/socket.h linux/include/asm-alpha/socket.h
--- v1.3.77/linux/include/asm-alpha/socket.h	Mon Dec 11 15:42:05 1995
+++ linux/include/asm-alpha/socket.h	Sun Mar 24 12:09:37 1996
@@ -3,16 +3,7 @@
 
 #include <linux/types.h>
 #include <asm/ioctl.h>
-
-/* Socket-level I/O control calls. */
-#define FIOGETOWN	_IOR('f', 123, int)
-#define FIOSETOWN 	_IOW('f', 124, int)
-
-#define SIOCATMARK	_IOR('s', 7, int)
-#define SIOCSPGRP	_IOW('s', 8, pid_t)
-#define SIOCGPGRP	_IOR('s', 9, pid_t)
-
-#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
+#include <asm/sockios.h>
 
 /* For setsockoptions(2) */
 /*
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/sockios.h linux/include/asm-alpha/sockios.h
--- v1.3.77/linux/include/asm-alpha/sockios.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/sockios.h	Sun Mar 24 12:09:37 1996
@@ -0,0 +1,15 @@
+#ifndef _ASM_ALPHA_SOCKIOS_H
+#define _ASM_ALPHA_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+
+#define FIOGETOWN	_IOR('f', 123, int)
+#define FIOSETOWN 	_IOW('f', 124, int)
+
+#define SIOCATMARK	_IOR('s', 7, int)
+#define SIOCSPGRP	_IOW('s', 8, pid_t)
+#define SIOCGPGRP	_IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+
+#endif /* _ASM_ALPHA_SOCKIOS_H */
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/statfs.h linux/include/asm-alpha/statfs.h
--- v1.3.77/linux/include/asm-alpha/statfs.h	Fri Jun  2 13:51:17 1995
+++ linux/include/asm-alpha/statfs.h	Sun Mar 24 12:09:37 1996
@@ -1,9 +1,13 @@
 #ifndef _ALPHA_STATFS_H
 #define _ALPHA_STATFS_H
 
-typedef struct {
-	int	val[2];
-} fsid_t;
+#ifndef _LINUX_TYPES_DONT_EXPORT
+
+#include <linux/posix_types.h>
+
+typedef __fsid_t	fsid_t;
+
+#endif
 
 /*
  * The OSF/1 statfs structure is much larger, but this should
@@ -19,7 +23,7 @@
 	int	f_bavail;
 	int	f_files;
 	int	f_ffree;
-	fsid_t	f_fsid;
+	__fsid_t f_fsid;
 	/* linux-specific entries start here.. */
 	int	f_namelen;
 };
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/termbits.h linux/include/asm-alpha/termbits.h
--- v1.3.77/linux/include/asm-alpha/termbits.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/termbits.h	Sun Mar 24 13:18:47 1996
@@ -0,0 +1,176 @@
+#ifndef _ALPHA_TERMBITS_H
+#define _ALPHA_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+/*
+ * termios type and macro definitions.  Be careful about adding stuff
+ * to this file since it's used in GNU libc and there are strict rules
+ * concerning namespace pollution.
+ */
+
+#define NCCS 19
+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_cc[NCCS];		/* control characters */
+	cc_t c_line;			/* line discipline (== c_cc[19]) */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
+/* c_cc characters */
+#define VEOF 0
+#define VEOL 1
+#define VEOL2 2
+#define VERASE 3
+#define VWERASE 4
+#define VKILL 5
+#define VREPRINT 6
+#define VSWTC 7
+#define VINTR 8
+#define VQUIT 9
+#define VSUSP 10
+#define VSTART 12
+#define VSTOP 13
+#define VLNEXT 14
+#define VDISCARD 15
+#define VMIN 16
+#define VTIME 17
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IXON	0001000
+#define IXOFF	0002000
+#if !defined(KERNEL) || defined(__USE_BSD)
+  /* POSIX.1 doesn't want these... */
+# define IXANY		0004000
+# define IUCLC		0010000
+# define IMAXBEL	0020000
+#endif
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define ONLCR	0000002
+#define OLCUC	0000004
+
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+
+#define OFILL	00000100
+#define OFDEL	00000200
+#define NLDLY	00001400
+#define   NL0	00000000
+#define   NL1	00000400
+#define   NL2	00001000
+#define   NL3	00001400
+#define TABDLY	00006000
+#define   TAB0	00000000
+#define   TAB1	00002000
+#define   TAB2	00004000
+#define   TAB3	00006000
+#define CRDLY	00030000
+#define   CR0	00000000
+#define   CR1	00010000
+#define   CR2	00020000
+#define   CR3	00030000
+#define FFDLY	00040000
+#define   FF0	00000000
+#define   FF1	00040000
+#define BSDLY	00100000
+#define   BS0	00000000
+#define   BS1	00100000
+#define VTDLY	00200000
+#define   VT0	00000000
+#define   VT1	00200000
+#define XTABS	01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
+
+/* c_cflag bit meaning */
+#define CBAUD	0000017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CBAUDEX 0000020
+#define  B57600   00020
+#define  B115200  00021
+#define  B230400  00022
+
+#define CSIZE	00001400
+#define   CS5	00000000
+#define   CS6	00000400
+#define   CS7	00001000
+#define   CS8	00001400
+
+#define CSTOPB	00002000
+#define CREAD	00004000
+#define PARENB	00010000
+#define PARODD	00020000
+#define HUPCL	00040000
+
+#define CLOCAL	00100000
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0x00000080
+#define ICANON	0x00000100
+#define XCASE	0x00004000
+#define ECHO	0x00000008
+#define ECHOE	0x00000002
+#define ECHOK	0x00000004
+#define ECHONL	0x00000010
+#define NOFLSH	0x80000000
+#define TOSTOP	0x00400000
+#define ECHOCTL	0x00000040
+#define ECHOPRT	0x00000020
+#define ECHOKE	0x00000001
+#define FLUSHO	0x00800000
+#define PENDIN	0x20000000
+#define IEXTEN	0x00000400
+
+/* Values for the ACTION argument to `tcflow'.  */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* Values for the QUEUE_SELECTOR argument to `tcflush'.  */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'.  */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _ALPHA_TERMBITS_H */
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/termios.h linux/include/asm-alpha/termios.h
--- v1.3.77/linux/include/asm-alpha/termios.h	Sat Feb 17 16:02:53 1996
+++ linux/include/asm-alpha/termios.h	Sun Mar 24 12:09:37 1996
@@ -1,9 +1,8 @@
 #ifndef _ALPHA_TERMIOS_H
 #define _ALPHA_TERMIOS_H
 
-#include <linux/types.h>
-
-#include <asm/ioctl.h>
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
 
 struct sgttyb {
 	char	sg_ispeed;
@@ -31,89 +30,6 @@
 	char	t_lnextc;
 };
 
-#define FIOCLEX		_IO('f', 1)
-#define FIONCLEX	_IO('f', 2)
-#define FIOASYNC	_IOW('f', 125, int)
-#define FIONBIO		_IOW('f', 126, int)
-#define FIONREAD	_IOR('f', 127, int)
-#define TIOCINQ		FIONREAD
-
-#define TIOCGETP	_IOR('t', 8, struct sgttyb)
-#define TIOCSETP	_IOW('t', 9, struct sgttyb)
-#define TIOCSETN	_IOW('t', 10, struct sgttyb)	/* TIOCSETP wo flush */
-
-#define TIOCSETC	_IOW('t', 17, struct tchars)
-#define TIOCGETC	_IOR('t', 18, struct tchars)
-#define TCGETS		_IOR('t', 19, struct termios)
-#define TCSETS		_IOW('t', 20, struct termios)
-#define TCSETSW		_IOW('t', 21, struct termios)
-#define TCSETSF		_IOW('t', 22, struct termios)
-
-#define TCGETA		_IOR('t', 23, struct termio)
-#define TCSETA		_IOW('t', 24, struct termio)
-#define TCSETAW		_IOW('t', 25, struct termio)
-#define TCSETAF		_IOW('t', 28, struct termio)
-
-#define TCSBRK		_IO('t', 29)
-#define TCXONC		_IO('t', 30)
-#define TCFLSH		_IO('t', 31)
-
-#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
-#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
-#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
-#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
-#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
-
-#define TIOCGLTC	_IOR('t', 116, struct ltchars)
-#define TIOCSLTC	_IOW('t', 117, struct ltchars)
-#define TIOCSPGRP	_IOW('t', 118, int)
-#define TIOCGPGRP	_IOR('t', 119, int)
-
-#define TIOCEXCL	0x540C
-#define TIOCNXCL	0x540D
-#define TIOCSCTTY	0x540E
-
-#define TIOCSTI		0x5412
-#define TIOCMGET	0x5415
-#define TIOCMBIS	0x5416
-#define TIOCMBIC	0x5417
-#define TIOCMSET	0x5418
-#define TIOCGSOFTCAR	0x5419
-#define TIOCSSOFTCAR	0x541A
-#define TIOCLINUX	0x541C
-#define TIOCCONS	0x541D
-#define TIOCGSERIAL	0x541E
-#define TIOCSSERIAL	0x541F
-#define TIOCPKT		0x5420
-
-#define TIOCNOTTY	0x5422
-#define TIOCSETD	0x5423
-#define TIOCGETD	0x5424
-#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
-
-#define TIOCSERCONFIG	0x5453
-#define TIOCSERGWILD	0x5454
-#define TIOCSERSWILD	0x5455
-#define TIOCGLCKTRMIOS	0x5456
-#define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
-#define TIOCSERGETLSR   0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
-#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
-
-/* 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;
@@ -131,40 +47,13 @@
 	unsigned char c_cc[NCC];	/* control characters */
 };
 
-#define NCCS 19
-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_cc[NCCS];		/* control characters */
-	cc_t c_line;			/* line discipline (== c_cc[19]) */
-	int c_ispeed;			/* input speed */
-	int c_ospeed;			/* output speed */
-};
-
-/* c_cc characters */
-#define VEOF 0
-#define VEOL 1
-#define VEOL2 2
-#define VERASE 3
-#define VWERASE 4
-#define VKILL 5
-#define VREPRINT 6
-#define VSWTC 7
-#define VINTR 8
-#define VQUIT 9
-#define VSUSP 10
-#define VSTART 12
-#define VSTOP 13
-#define VLNEXT 14
-#define VDISCARD 15
-#define VMIN 16
-#define VTIME 17
-
 /*
- * ..and the same for c_cc in the termio structure.. 
- * Oh, how I love being backwardly compatible.
+ * 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 _VINTR	0
 #define _VQUIT	1
@@ -177,6 +66,12 @@
 #define _VEOL2	6
 #define _VSWTC	7
 
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+
 #ifdef __KERNEL__
 /*	eof=^D		eol=\0		eol2=\0		erase=del
 	werase=^W	kill=^U		reprint=^R	sxtc=\0
@@ -185,158 +80,6 @@
 	vmin=\1		vtime=\0
 */
 #define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"
-#endif
-
-/* c_iflag bits */
-#define IGNBRK	0000001
-#define BRKINT	0000002
-#define IGNPAR	0000004
-#define PARMRK	0000010
-#define INPCK	0000020
-#define ISTRIP	0000040
-#define INLCR	0000100
-#define IGNCR	0000200
-#define ICRNL	0000400
-#define IXON	0001000
-#define IXOFF	0002000
-#define IXANY	0004000
-#define IUCLC	0010000
-#define IMAXBEL	0020000
-
-/* c_oflag bits */
-#define OPOST	0000001
-#define ONLCR	0000002
-#define OLCUC	0000004
-
-#define OCRNL	0000010
-#define ONOCR	0000020
-#define ONLRET	0000040
-
-#define OFILL	00000100
-#define OFDEL	00000200
-#define NLDLY	00001400
-#define   NL0	00000000
-#define   NL1	00000400
-#define   NL2	00001000
-#define   NL3	00001400
-#define TABDLY	00006000
-#define   TAB0	00000000
-#define   TAB1	00002000
-#define   TAB2	00004000
-#define   TAB3	00006000
-#define CRDLY	00030000
-#define   CR0	00000000
-#define   CR1	00010000
-#define   CR2	00020000
-#define   CR3	00030000
-#define FFDLY	00040000
-#define   FF0	00000000
-#define   FF1	00040000
-#define BSDLY	00100000
-#define   BS0	00000000
-#define   BS1	00100000
-#define VTDLY	00200000
-#define   VT0	00000000
-#define   VT1	00200000
-#define XTABS	01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
-
-/* c_cflag bit meaning */
-#define CBAUD	0000017
-#define  B0	0000000		/* hang up */
-#define  B50	0000001
-#define  B75	0000002
-#define  B110	0000003
-#define  B134	0000004
-#define  B150	0000005
-#define  B200	0000006
-#define  B300	0000007
-#define  B600	0000010
-#define  B1200	0000011
-#define  B1800	0000012
-#define  B2400	0000013
-#define  B4800	0000014
-#define  B9600	0000015
-#define  B19200	0000016
-#define  B38400	0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CBAUDEX 0000020
-#define  B57600   00020
-#define  B115200  00021
-#define  B230400  00022
-
-#define CSIZE	00001400
-#define   CS5	00000000
-#define   CS6	00000400
-#define   CS7	00001000
-#define   CS8	00001400
-
-#define CSTOPB	00002000
-#define CREAD	00004000
-#define PARENB	00010000
-#define PARODD	00020000
-#define HUPCL	00040000
-
-#define CLOCAL	00100000
-#define CRTSCTS	  020000000000		/* flow control */
-
-/* c_lflag bits */
-#define ISIG	0x00000080
-#define ICANON	0x00000100
-#define XCASE	0x00004000
-#define ECHO	0x00000008
-#define ECHOE	0x00000002
-#define ECHOK	0x00000004
-#define ECHONL	0x00000010
-#define NOFLSH	0x80000000
-#define TOSTOP	0x00400000
-#define ECHOCTL	0x00000040
-#define ECHOPRT	0x00000020
-#define ECHOKE	0x00000001
-#define FLUSHO	0x00800000
-#define PENDIN	0x20000000
-#define IEXTEN	0x00000400
-
-/* 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
-
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-
-#ifdef __KERNEL__
 
 /*
  * Translate a "termio" structure into a "termios". Ugh.
diff -u --recursive --new-file v1.3.77/linux/include/asm-alpha/types.h linux/include/asm-alpha/types.h
--- v1.3.77/linux/include/asm-alpha/types.h	Sun Sep  3 12:27:01 1995
+++ linux/include/asm-alpha/types.h	Sun Mar 24 12:09:37 1996
@@ -1,41 +1,15 @@
 #ifndef _ALPHA_TYPES_H
 #define _ALPHA_TYPES_H
 
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned long size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef long ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef long ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
 
-typedef int pid_t;
-typedef unsigned int uid_t;
-typedef unsigned int gid_t;
-typedef unsigned int dev_t;
-typedef unsigned int ino_t;
-typedef unsigned int mode_t;
 typedef unsigned int umode_t;
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
 
 /*
  * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -98,55 +72,4 @@
 #endif
 
 #endif /* __KERNEL__ */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, 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, 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, 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 case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(fd_set *p)
-{
-	unsigned int *tmp = p->fds_bits;
-	int i;
-
-	if (__builtin_constant_p(__FDSET_INTS)) {
-		switch (__FDSET_INTS) {
-			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;
-		}
-	}
-	i = __FDSET_INTS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
-
-#endif
+#endif /* _ALPHA_TYPES_H */
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/ioctls.h linux/include/asm-i386/ioctls.h
--- v1.3.77/linux/include/asm-i386/ioctls.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/ioctls.h	Sun Mar 24 13:12:47 1996
@@ -0,0 +1,74 @@
+#ifndef __ARCH_I386_IOCTLS_H__
+#define __ARCH_I386_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+/* 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
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/posix_types.h linux/include/asm-i386/posix_types.h
--- v1.3.77/linux/include/asm-i386/posix_types.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/posix_types.h	Sun Mar 24 13:15:27 1996
@@ -0,0 +1,51 @@
+#ifndef __ARCH_I386_POSIX_TYPES_H
+#define __ARCH_I386_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 short	__dev_t;
+typedef unsigned long	__ino_t;
+typedef unsigned short	__mode_t;
+typedef unsigned short	__nlink_t;
+typedef long		__off_t;
+typedef int		__pid_t;
+typedef unsigned short	__uid_t;
+typedef unsigned short	__gid_t;
+typedef unsigned int	__size_t;
+typedef int		__ssize_t;
+typedef int		__ptrdiff_t;
+typedef long		__time_t;
+typedef long		__clock_t;
+typedef int		__daddr_t;
+typedef char *		__caddr_t;
+
+#undef	__FD_SET
+#define __FD_SET(fd,fdsetp) \
+		__asm__ __volatile__("btsl %1,%0": \
+			"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
+
+#undef	__FD_CLR
+#define __FD_CLR(fd,fdsetp) \
+		__asm__ __volatile__("btrl %1,%0": \
+			"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
+
+#undef	__FD_ISSET
+#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
+		unsigned char __result; \
+		__asm__ __volatile__("btl %1,%2 ; setb %0" \
+			:"=q" (__result) :"r" ((int) (fd)), \
+			"m" (*(fd_set *) (fdsetp))); \
+		__result; }))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) \
+		__asm__ __volatile__("cld ; rep ; stosl" \
+			:"=m" (*(fd_set *) (fdsetp)) \
+			:"a" (0), "c" (__FDSET_INTS), \
+			"D" ((fd_set *) (fdsetp)) :"cx","di")
+
+#endif
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v1.3.77/linux/include/asm-i386/smp.h	Wed Mar 20 10:59:59 1996
+++ linux/include/asm-i386/smp.h	Mon Mar 25 08:58:21 1996
@@ -175,13 +175,14 @@
  */
  
 extern int smp_found_config;
-extern void smp_scan_config(unsigned long, unsigned long);
+extern int smp_scan_config(unsigned long, unsigned long);
 extern unsigned long smp_alloc_memory(unsigned long mem_base);
 extern unsigned char *apic_reg;
 extern unsigned char *kernel_stacks[NR_CPUS];
 extern unsigned char boot_cpu_id;
 extern unsigned long cpu_present_map;
 extern volatile int cpu_number_map[NR_CPUS];
+extern volatile int cpu_logical_map[NR_CPUS];
 extern volatile unsigned long smp_invalidate_needed;
 extern void smp_invalidate(void);
 extern volatile unsigned long kernel_flag, kernel_counter;
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/socket.h linux/include/asm-i386/socket.h
--- v1.3.77/linux/include/asm-i386/socket.h	Sat Nov 25 19:04:48 1995
+++ linux/include/asm-i386/socket.h	Sun Mar 24 12:47:39 1996
@@ -1,13 +1,7 @@
 #ifndef _ASM_SOCKET_H
 #define _ASM_SOCKET_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 */
+#include <asm/sockios.h>
 
 /* For setsockoptions(2) */
 #define SOL_SOCKET	1
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/sockios.h linux/include/asm-i386/sockios.h
--- v1.3.77/linux/include/asm-i386/sockios.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/sockios.h	Sun Mar 24 12:47:39 1996
@@ -0,0 +1,12 @@
+#ifndef __ARCH_I386_SOCKIOS__
+#define __ARCH_I386_SOCKIOS__
+
+/* 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
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/string.h linux/include/asm-i386/string.h
--- v1.3.77/linux/include/asm-i386/string.h	Wed Mar 20 11:00:00 1996
+++ linux/include/asm-i386/string.h	Sat Mar 23 19:45:51 1996
@@ -402,6 +402,10 @@
 		case 4:
 			*(unsigned long *)to = *(const unsigned long *)from;
 			return to;
+		case 8:
+			*(unsigned long *)to = *(const unsigned long *)from;
+			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+			return to;
 	}
 #define COMMON(x) \
 __asm__("cld\n\t" \
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/termbits.h linux/include/asm-i386/termbits.h
--- v1.3.77/linux/include/asm-i386/termbits.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/termbits.h	Sun Mar 24 13:13:43 1996
@@ -0,0 +1,159 @@
+#ifndef __ARCH_I386_TERMBITS_H__
+#define __ARCH_I386_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+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 */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define  B57600  0010001
+#define  B115200 0010002
+#define  B230400 0010003
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+/* 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
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/termios.h linux/include/asm-i386/termios.h
--- v1.3.77/linux/include/asm-i386/termios.h	Wed Mar 13 10:09:22 1996
+++ linux/include/asm-i386/termios.h	Sun Mar 24 13:12:47 1996
@@ -1,71 +1,8 @@
 #ifndef _I386_TERMIOS_H
 #define _I386_TERMIOS_H
 
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS		0x5401
-#define TCSETS		0x5402
-#define TCSETSW		0x5403
-#define TCSETSF		0x5404
-#define TCGETA		0x5405
-#define TCSETA		0x5406
-#define TCSETAW		0x5407
-#define TCSETAF		0x5408
-#define TCSBRK		0x5409
-#define TCXONC		0x540A
-#define TCFLSH		0x540B
-#define TIOCEXCL	0x540C
-#define TIOCNXCL	0x540D
-#define TIOCSCTTY	0x540E
-#define TIOCGPGRP	0x540F
-#define TIOCSPGRP	0x5410
-#define TIOCOUTQ	0x5411
-#define TIOCSTI		0x5412
-#define TIOCGWINSZ	0x5413
-#define TIOCSWINSZ	0x5414
-#define TIOCMGET	0x5415
-#define TIOCMBIS	0x5416
-#define TIOCMBIC	0x5417
-#define TIOCMSET	0x5418
-#define TIOCGSOFTCAR	0x5419
-#define TIOCSSOFTCAR	0x541A
-#define FIONREAD	0x541B
-#define TIOCINQ		FIONREAD
-#define TIOCLINUX	0x541C
-#define TIOCCONS	0x541D
-#define TIOCGSERIAL	0x541E
-#define TIOCSSERIAL	0x541F
-#define TIOCPKT		0x5420
-#define FIONBIO		0x5421
-#define TIOCNOTTY	0x5422
-#define TIOCSETD	0x5423
-#define TIOCGETD	0x5424
-#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
-#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
-#define FIOCLEX		0x5451
-#define FIOASYNC	0x5452
-#define TIOCSERCONFIG	0x5453
-#define TIOCSERGWILD	0x5454
-#define TIOCSERSWILD	0x5455
-#define TIOCGLCKTRMIOS	0x5456
-#define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
-#define TIOCSERGETLSR   0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
-#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
-
-/* 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
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
 
 struct winsize {
 	unsigned short ws_row;
@@ -84,35 +21,6 @@
 	unsigned char c_cc[NCC];	/* control characters */
 };
 
-#define NCCS 19
-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 */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
 #ifdef __KERNEL__
 /*	intr=^C		quit=^\		erase=del	kill=^U
 	eof=^D		vtime=\0	vmin=\1		sxtc=\0
@@ -123,110 +31,6 @@
 #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
 #endif
 
-/* c_iflag bits */
-#define IGNBRK	0000001
-#define BRKINT	0000002
-#define IGNPAR	0000004
-#define PARMRK	0000010
-#define INPCK	0000020
-#define ISTRIP	0000040
-#define INLCR	0000100
-#define IGNCR	0000200
-#define ICRNL	0000400
-#define IUCLC	0001000
-#define IXON	0002000
-#define IXANY	0004000
-#define IXOFF	0010000
-#define IMAXBEL	0020000
-
-/* c_oflag bits */
-#define OPOST	0000001
-#define OLCUC	0000002
-#define ONLCR	0000004
-#define OCRNL	0000010
-#define ONOCR	0000020
-#define ONLRET	0000040
-#define OFILL	0000100
-#define OFDEL	0000200
-#define NLDLY	0000400
-#define   NL0	0000000
-#define   NL1	0000400
-#define CRDLY	0003000
-#define   CR0	0000000
-#define   CR1	0001000
-#define   CR2	0002000
-#define   CR3	0003000
-#define TABDLY	0014000
-#define   TAB0	0000000
-#define   TAB1	0004000
-#define   TAB2	0010000
-#define   TAB3	0014000
-#define   XTABS	0014000
-#define BSDLY	0020000
-#define   BS0	0000000
-#define   BS1	0020000
-#define VTDLY	0040000
-#define   VT0	0000000
-#define   VT1	0040000
-#define FFDLY	0100000
-#define   FF0	0000000
-#define   FF1	0100000
-
-/* c_cflag bit meaning */
-#define CBAUD	0010017
-#define  B0	0000000		/* hang up */
-#define  B50	0000001
-#define  B75	0000002
-#define  B110	0000003
-#define  B134	0000004
-#define  B150	0000005
-#define  B200	0000006
-#define  B300	0000007
-#define  B600	0000010
-#define  B1200	0000011
-#define  B1800	0000012
-#define  B2400	0000013
-#define  B4800	0000014
-#define  B9600	0000015
-#define  B19200	0000016
-#define  B38400	0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE	0000060
-#define   CS5	0000000
-#define   CS6	0000020
-#define   CS7	0000040
-#define   CS8	0000060
-#define CSTOPB	0000100
-#define CREAD	0000200
-#define PARENB	0000400
-#define PARODD	0001000
-#define HUPCL	0002000
-#define CLOCAL	0004000
-#define CBAUDEX 0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define CIBAUD	  002003600000	/* input baud rate (not used) */
-#define CRTSCTS	  020000000000		/* flow control */
-
-/* c_lflag bits */
-#define ISIG	0000001
-#define ICANON	0000002
-#define XCASE	0000004
-#define ECHO	0000010
-#define ECHOE	0000020
-#define ECHOK	0000040
-#define ECHONL	0000100
-#define NOFLSH	0000200
-#define TOSTOP	0000400
-#define ECHOCTL	0001000
-#define ECHOPRT	0002000
-#define ECHOKE	0004000
-#define FLUSHO	0010000
-#define PENDIN	0040000
-#define IEXTEN	0100000
-
 /* modem lines */
 #define TIOCM_LE	0x001
 #define TIOCM_DTR	0x002
@@ -241,24 +45,6 @@
 #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
 
 /* line disciplines */
 #define N_TTY		0
@@ -276,7 +62,7 @@
 extern inline void trans_from_termio(struct termio * termio,
 	struct termios * termios)
 {
-#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))
+#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);
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/types.h linux/include/asm-i386/types.h
--- v1.3.77/linux/include/asm-i386/types.h	Sun Sep  3 12:27:02 1995
+++ linux/include/asm-i386/types.h	Sun Mar 24 12:57:36 1996
@@ -1,41 +1,7 @@
 #ifndef _I386_TYPES_H
 #define _I386_TYPES_H
 
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-typedef int pid_t;
-typedef unsigned short uid_t;
-typedef unsigned short gid_t;
-typedef unsigned short dev_t;
-typedef unsigned long ino_t;
-typedef unsigned short mode_t;
 typedef unsigned short umode_t;
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
 
 /*
  * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -74,30 +40,5 @@
 typedef unsigned long long u64;
 
 #endif /* __KERNEL__ */
-
-#undef	__FD_SET
-#define __FD_SET(fd,fdsetp) \
-		__asm__ __volatile__("btsl %1,%0": \
-			"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd,fdsetp) \
-		__asm__ __volatile__("btrl %1,%0": \
-			"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
-		unsigned char __result; \
-		__asm__ __volatile__("btl %1,%2 ; setb %0" \
-			:"=q" (__result) :"r" ((int) (fd)), \
-			"m" (*(fd_set *) (fdsetp))); \
-		__result; }))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
-		__asm__ __volatile__("cld ; rep ; stosl" \
-			:"=m" (*(fd_set *) (fdsetp)) \
-			:"a" (0), "c" (__FDSET_INTS), \
-			"D" ((fd_set *) (fdsetp)) :"cx","di")
 
 #endif
diff -u --recursive --new-file v1.3.77/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v1.3.77/linux/include/asm-i386/unistd.h	Tue Feb 20 14:37:28 1996
+++ linux/include/asm-i386/unistd.h	Fri Mar 22 08:34:02 1996
@@ -168,6 +168,7 @@
 #define __NR_sched_get_priority_min	160
 #define __NR_sched_rr_get_interval	161
 #define __NR_nanosleep		162
+#define __NR_mremap		163
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
diff -u --recursive --new-file v1.3.77/linux/include/linux/atalk.h linux/include/linux/atalk.h
--- v1.3.77/linux/include/linux/atalk.h	Sat Mar  2 10:43:44 1996
+++ linux/include/linux/atalk.h	Mon Mar 25 08:58:21 1996
@@ -140,5 +140,9 @@
 extern struct at_addr *atalk_find_dev_addr(struct device *dev);
 extern int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr);
 extern void aarp_send_probe(struct device *dev, struct at_addr *addr);
+#ifdef MODULE
+extern void aarp_cleanup_module(void);
+#endif
+
 #endif
 #endif
diff -u --recursive --new-file v1.3.77/linux/include/linux/binfmts.h linux/include/linux/binfmts.h
--- v1.3.77/linux/include/linux/binfmts.h	Sun Mar 17 09:04:07 1996
+++ linux/include/linux/binfmts.h	Sat Mar 23 14:46:40 1996
@@ -51,6 +51,7 @@
 extern int init_script_binfmt(void);
 
 extern int prepare_binprm(struct linux_binprm *);
+extern void remove_arg_zero(struct linux_binprm *);
 extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
 extern void flush_old_exec(struct linux_binprm * bprm);
 extern unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm);
diff -u --recursive --new-file v1.3.77/linux/include/linux/blk.h linux/include/linux/blk.h
--- v1.3.77/linux/include/linux/blk.h	Wed Mar 13 10:09:22 1996
+++ linux/include/linux/blk.h	Mon Mar 25 10:22:43 1996
@@ -319,6 +319,8 @@
 #define CURRENT (blk_dev[MAJOR_NR].current_request)
 #endif
 
+#define CURRENT_PLUGGED IS_PLUGGED(blk_dev+MAJOR_NR)
+
 #define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev)
 
 #ifdef DEVICE_INTR
@@ -356,7 +358,7 @@
 #endif
 
 #define INIT_REQUEST \
-	if (!CURRENT) {\
+	if (!CURRENT || CURRENT_PLUGGED) {\
 		CLEAR_INTR; \
 		return; \
 	} \
diff -u --recursive --new-file v1.3.77/linux/include/linux/blkdev.h linux/include/linux/blkdev.h
--- v1.3.77/linux/include/linux/blkdev.h	Wed Feb 28 11:50:11 1996
+++ linux/include/linux/blkdev.h	Mon Mar 25 10:22:43 1996
@@ -4,6 +4,7 @@
 #include <linux/major.h>
 #include <linux/sched.h>
 #include <linux/genhd.h>
+#include <linux/tqueue.h>
 
 /*
  * Ok, this is an expanded form so that we can use the same
@@ -35,7 +36,10 @@
 struct blk_dev_struct {
 	void (*request_fn)(void);
 	struct request * current_request;
+	struct tq_struct plug_tq;
 };
+
+#define IS_PLUGGED(dev) ((dev)->plug_tq.sync)
 
 struct sec_size {
 	unsigned block_size;
diff -u --recursive --new-file v1.3.77/linux/include/linux/fs.h linux/include/linux/fs.h
--- v1.3.77/linux/include/linux/fs.h	Wed Mar 20 11:00:00 1996
+++ linux/include/linux/fs.h	Mon Mar 25 10:22:43 1996
@@ -480,6 +480,7 @@
 extern int register_blkdev(unsigned int, const char *, struct file_operations *);
 extern int unregister_blkdev(unsigned int major, const char * name);
 extern int blkdev_open(struct inode * inode, struct file * filp);
+extern void blkdev_release (struct inode * inode);
 extern struct file_operations def_blk_fops;
 extern struct inode_operations blkdev_inode_operations;
 
diff -u --recursive --new-file v1.3.77/linux/include/linux/if_arp.h linux/include/linux/if_arp.h
--- v1.3.77/linux/include/linux/if_arp.h	Sat Mar  2 10:43:44 1996
+++ linux/include/linux/if_arp.h	Mon Mar 25 08:58:22 1996
@@ -11,7 +11,8 @@
  *		Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
  *		Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Florian La Roche.
+ *		Florian La Roche,
+ *		Jonathan Layes <layes@loran.com>
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -31,6 +32,8 @@
 #define	ARPHRD_IEEE802	6		/* IEEE 802.2 Ethernet/TR/TB	*/
 #define	ARPHRD_ARCNET	7		/* ARCnet			*/
 #define	ARPHRD_APPLETLK	8		/* APPLEtalk			*/
+#define ARPHRD_DLCI	15		/* Frame Relay DLCI		*/
+
 /* Dummy types for non ARP hardware */
 #define ARPHRD_SLIP	256
 #define ARPHRD_CSLIP	257
@@ -39,9 +42,10 @@
 #define ARPHRD_RSRVD	260		/* Notional KISS type 		*/
 #define ARPHRD_ADAPT	264
 #define ARPHRD_PPP	512
+
 #define ARPHRD_TUNNEL	768		/* IPIP tunnel			*/
 #define ARPHRD_TUNNEL6	769		/* IPIP6 tunnel			*/
-#define ARPHRD_FRAD	770		/* Frame Relay			*/
+#define ARPHRD_FRAD	770		/* Frame Relay Access Device	*/
 #define ARPHRD_SKIP	771		/* SKIP vif			*/
 #define ARPHRD_LOOPBACK	772		/* Loopback device		*/
 #define ARPHRD_LOCALTLK 773		/* Localtalk device		*/
@@ -99,6 +103,24 @@
 	unsigned char		ar_tip[4];		/* target IP address		*/
 #endif
 
+};
+
+/* Support for the user space arp daemon, arpd */
+
+#define ARPD_UPDATE	0x01
+#define ARPD_LOOKUP	0x02
+
+struct arpd_request
+{
+	unsigned short	req;			/* request type */
+	__u32		ip;			/* ip address of entry */
+	__u32		mask;			/* netmask - used for proxy */
+	unsigned char	ha[MAX_ADDR_LEN];	/* Hardware address */
+	unsigned long	last_used;		/* For expiry */
+	unsigned long	last_updated;		/* For expiry */
+	unsigned int	flags;			/* Control status */
+	struct device	*dev;			/* Device entry is tied to */
+	int		loc;			/* Debugging call location */
 };
 
 #endif	/* _LINUX_IF_ARP_H */
diff -u --recursive --new-file v1.3.77/linux/include/linux/if_ether.h linux/include/linux/if_ether.h
--- v1.3.77/linux/include/linux/if_ether.h	Sat Mar  2 10:43:45 1996
+++ linux/include/linux/if_ether.h	Mon Mar 25 08:58:22 1996
@@ -17,19 +17,25 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  */
+ 
 #ifndef _LINUX_IF_ETHER_H
 #define _LINUX_IF_ETHER_H
 
-/* IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
-   and FCS/CRC (frame check sequence). */
+/*
+ *	IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
+ *	and FCS/CRC (frame check sequence). 
+ */
+
 #define ETH_ALEN	6		/* Octets in one ethernet addr	 */
 #define ETH_HLEN	14		/* Total octets in header.	 */
 #define ETH_ZLEN	60		/* Min. octets in frame sans FCS */
 #define ETH_DATA_LEN	1500		/* Max. octets in payload	 */
 #define ETH_FRAME_LEN	1514		/* Max. octets in frame sans FCS */
 
+/*
+ *	These are the defined Ethernet Protocol ID's.
+ */
 
-/* These are the defined Ethernet Protocol ID's. */
 #define ETH_P_LOOP	0x0060		/* Ethernet Loopback packet	*/
 #define ETH_P_ECHO	0x0200		/* Ethernet Echo packet		*/
 #define ETH_P_PUP	0x0400		/* Xerox PUP packet		*/
@@ -64,39 +70,49 @@
 #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
 #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
 #define ETH_P_LOCALTALK 0x0009		/* Localtalk pseudeo type 	*/
+#define ETH_P_PPPTALK	0x0010		/* Dummy type for Atalk over PPP*/
 
-/* This is an Ethernet frame header. */
-struct ethhdr {
-  unsigned char		h_dest[ETH_ALEN];	/* destination eth addr	*/
-  unsigned char		h_source[ETH_ALEN];	/* source ether addr	*/
-  unsigned short	h_proto;		/* packet type ID field	*/
+/*
+ *	This is an Ethernet frame header.
+ */
+ 
+struct ethhdr 
+{
+	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
+	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
+	unsigned short	h_proto;		/* packet type ID field	*/
 };
 
-/* Ethernet statistics collection data. */
-struct enet_statistics{
-  int	rx_packets;			/* total packets received	*/
-  int	tx_packets;			/* total packets transmitted	*/
-  int	rx_errors;			/* bad packets received		*/
-  int	tx_errors;			/* packet transmit problems	*/
-  int	rx_dropped;			/* no space in linux buffers	*/
-  int	tx_dropped;			/* no space available in linux	*/
-  int	multicast;			/* multicast packets received	*/
-  int	collisions;
-
-  /* detailed rx_errors: */
-  int	rx_length_errors;
-  int	rx_over_errors;			/* receiver ring buff overflow	*/
-  int	rx_crc_errors;			/* recved pkt with crc error	*/
-  int	rx_frame_errors;		/* recv'd frame alignment error */
-  int	rx_fifo_errors;			/* recv'r fifo overrun		*/
-  int	rx_missed_errors;		/* receiver missed packet	*/
-
-  /* detailed tx_errors */
-  int	tx_aborted_errors;
-  int	tx_carrier_errors;
-  int	tx_fifo_errors;
-  int	tx_heartbeat_errors;
-  int	tx_window_errors;
+/*
+ *	Ethernet statistics collection data. 
+ */
+ 
+struct enet_statistics
+{
+	int	rx_packets;		/* total packets received	*/
+	int	tx_packets;		/* total packets transmitted	*/
+	int	rx_errors;		/* bad packets received		*/
+	int	tx_errors;		/* packet transmit problems	*/
+	int	rx_dropped;		/* no space in linux buffers	*/
+	int	tx_dropped;		/* no space available in linux	*/
+	int	multicast;		/* multicast packets received	*/
+	int	collisions;
+
+	/* detailed rx_errors: */
+	int	rx_length_errors;
+	int	rx_over_errors;		/* receiver ring buff overflow	*/
+	int	rx_crc_errors;		/* recved pkt with crc error	*/
+	int	rx_frame_errors;	/* recv'd frame alignment error */
+	int	rx_fifo_errors;		/* recv'r fifo overrun		*/
+	int	rx_missed_errors;	/* receiver missed packet	*/
+
+	/* detailed tx_errors */
+	int	tx_aborted_errors;
+	int	tx_carrier_errors;
+	int	tx_fifo_errors;
+	int	tx_heartbeat_errors;
+	int	tx_window_errors;
 };
+
 
 #endif	/* _LINUX_IF_ETHER_H */
diff -u --recursive --new-file v1.3.77/linux/include/linux/if_frad.h linux/include/linux/if_frad.h
--- v1.3.77/linux/include/linux/if_frad.h	Thu Jan  1 02:00:00 1970
+++ linux/include/linux/if_frad.h	Mon Mar 25 08:58:22 1996
@@ -0,0 +1,168 @@
+/*
+ * DLCI/FRAD	Definitions for Frame Relay Access Devices.  DLCI devices are
+ *		created for each DLCI associated with a FRAD.  The FRAD driver
+ *		is not truely a network device, but the lower level device
+ *		handler.  This allows other FRAD manufacturers to use the DLCI
+ *		code, including it's RFC1490 encapsulation along side the current
+ *		implementation for the Sangoma cards.
+ *
+ * Version:	@(#)if_ifrad.h	0.10	23 Mar 96
+ *
+ * Author:	Mike McLagan <mike.mclagan@linux.org>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _FRAD_H_
+#define _FRAD_H_
+
+/* Stuctures and constants associated with the DLCI device driver */
+
+#define DLCI_DEVADD	(SIOCDEVPRIVATE)
+#define DLCI_DEVDEL	(SIOCDEVPRIVATE + 1)
+
+struct dlci_add
+{
+   char  devname[IFNAMSIZ];
+   short dlci;
+};
+
+#define DLCI_GET_CONF	(SIOCDEVPRIVATE + 2)
+#define DLCI_SET_CONF	(SIOCDEVPRIVATE + 3)
+
+/* These are related to the Sangoma FRAD */
+struct dlci_conf {
+   short flags;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd; 
+
+/* these are part of the status read */
+   short Tc_fwd;
+   short Tc_bwd;
+   short Tf_max;
+   short Tb_max;
+};
+
+#define DLCI_GET_SLAVE	(SIOCDEVPRIVATE + 4)
+
+/* configuration flags for DLCI */
+#define DLCI_IGNORE_CIR_OUT	0x0001
+#define DLCI_ACCOUNT_CIR_IN	0x0002
+#define DLCI_BUFFER_IF		0x0008
+
+#define DLCI_VALID_FLAGS	0x000B
+
+
+/* defines for the actual Frame Relay hardware */
+#define FRAD_GET_CONF	(SIOCDEVPRIVATE)
+#define FRAD_SET_CONF	(SIOCDEVPRIVATE + 1)
+
+#define FRAD_LAST_IOCTL	FRAD_SET_CONF
+
+struct frad_conf 
+{
+   short station;
+   short flags;
+   short kbaud;
+   short clocking;
+   short mtu;
+   short T391;
+   short T392;
+   short N391;
+   short N392;
+   short N393;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd;
+
+/* Add new fields here, above is a mirror of the sangoma_conf */
+
+};
+
+#define FRAD_STATION_CPE	0x0000
+#define FRAD_STATION_NODE	0x0001
+
+#define FRAD_TX_IGNORE_CIR	0x0001
+#define FRAD_RX_ACCOUNT_CIR	0x0002
+#define FRAD_DROP_ABORTED	0x0004
+#define FRAD_BUFFERIF		0x0008
+#define FRAD_STATS		0x0010
+#define FRAD_MCI		0x0100
+#define FRAD_AUTODLCI		0x8000
+#define FRAD_VALID_FLAGS	0x811F
+
+#define FRAD_CLOCK_INT		0x0001
+#define FRAD_CLOCK_EXT		0x0000
+
+#ifdef __KERNEL__
+
+struct fradhdr
+{
+   /* these are the fields of an RFC 1490 header               */
+   unsigned char  control;
+   unsigned char  pad;		/* for IP packets, this can be the NLPID */
+   unsigned char  NLPID;
+   unsigned char  OUI[3];
+   unsigned short PID;
+};
+
+/* see RFC 1490 for the definition of the following */
+#define FRAD_I_UI		0x03
+
+#define FRAD_P_PADDING		0x00
+#define FRAD_P_Q933		0x08
+#define FRAD_P_SNAP		0x80
+#define FRAD_P_CLNP		0x81
+#define FRAD_P_IP		0xCC
+
+struct dlci_local
+{
+   struct enet_statistics stats;
+   struct device          *slave;
+   struct dlci_conf       config;
+   int                    configured;
+
+   /* callback function */
+   void              (*receive)(struct sk_buff *skb, struct device *);
+};
+
+struct frad_local
+{
+   struct enet_statistics stats;
+   struct timer_list timer;
+
+   /* devices which this FRAD is slaved to */
+   struct device     *master[CONFIG_DLCI_MAX];
+   short             dlci[CONFIG_DLCI_MAX];
+
+   /* callback functions */
+   int               (*activate)(struct device *, struct device *);
+   int               (*deactivate)(struct device *, struct device *);
+   int               (*assoc)(struct device *, struct device *);
+   int               (*deassoc)(struct device *, struct device *);
+   int               (*dlci_conf)(struct device *, struct device *, int get);
+
+   int               initialized;	/* mem_start, port, irq set ? */
+   int               configured;	/* has this device been configured */
+   int               type;		/* adapter type */
+   int               state;		/* state of the S502/8 control latch */
+   int               buffer;		/* current buffer for S508 firmware */
+   struct frad_conf  config;
+};
+
+int register_frad(const char *name);
+int unregister_frad(const char *name);
+
+#endif __KERNEL__
+
+#endif
diff -u --recursive --new-file v1.3.77/linux/include/linux/if_tr.h linux/include/linux/if_tr.h
--- v1.3.77/linux/include/linux/if_tr.h	Tue Jun  6 11:22:11 1995
+++ linux/include/linux/if_tr.h	Sun Mar 24 12:09:37 1996
@@ -45,37 +45,36 @@
 
 /* This is an Token-Ring frame header. */
 struct trh_hdr {
-	unsigned char   ac;	/* access control field */
-	unsigned char   fc;	/* frame control field */
-	unsigned char   daddr[TR_ALEN];	/* destination address */
-	unsigned char   saddr[TR_ALEN];	/* source address */
-	unsigned short  rcf;	/* route control field */
-	unsigned short  rseg[8];/* routing registers */
+	__u8  ac;			/* access control field */
+	__u8  fc;			/* frame control field */
+	__u8  daddr[TR_ALEN];		/* destination address */
+	__u8  saddr[TR_ALEN];		/* source address */
+	__u16 rcf;			/* route control field */
+	__u16 rseg[8];			/* routing registers */
 };
 
 /* This is an Token-Ring LLC structure */
 struct trllc {
-	unsigned char   dsap;	/* destination SAP */
-	unsigned char   ssap;	/* source SAP */
-	unsigned char   llc;	/* LLC control field */
-	unsigned char   protid[3];	/* protocol id */
-	unsigned short  ethertype;	/* ether type field */
+	__u8  dsap;			/* destination SAP */
+	__u8  ssap;			/* source SAP */
+	__u8  llc;			/* LLC control field */
+	__u8  protid[3];		/* protocol id */
+	__u16 ethertype;		/* ether type field */
 };
 
-
 /* Token-Ring statistics collection data. */
-struct tr_statistics{
-  int	rx_packets;			/* total packets received	*/
-  int	tx_packets;			/* total packets transmitted	*/
-  int	rx_errors;			/* bad packets received		*/
-  int	tx_errors;			/* packet transmit problems	*/
-  int	rx_dropped;			/* no space in linux buffers	*/
-  int	tx_dropped;			/* no space available in linux	*/
-  int	multicast;			/* multicast packets received	*/
-  int   transmit_collision;
+struct tr_statistics {
+	int rx_packets;			/* total packets received	*/
+	int tx_packets;			/* total packets transmitted	*/
+	int rx_errors;			/* bad packets received		*/
+	int tx_errors;			/* packet transmit problems	*/
+	int rx_dropped;			/* no space in linux buffers	*/
+	int tx_dropped;			/* no space available in linux	*/
+	int multicast;			/* multicast packets received	*/
+	int transmit_collision;
 
-	/* detailed Token-Ring errors. See IBM Token-Ring Network Architecture
-      for more info */
+	/* detailed Token-Ring errors. See IBM Token-Ring Network
+	   Architecture for more info */
 
 	int line_errors;
 	int internal_errors;
@@ -88,7 +87,6 @@
 	int frequency_errors;
 	int token_errors;
 	int dummy1;
-	
 };
 
 /* source routing stuff */
diff -u --recursive --new-file v1.3.77/linux/include/linux/kd.h linux/include/linux/kd.h
--- v1.3.77/linux/include/linux/kd.h	Mon Sep 18 14:54:09 1995
+++ linux/include/linux/kd.h	Mon Mar 25 10:23:53 1996
@@ -10,8 +10,8 @@
 #define GIO_FONTX	0x4B6B	/* get font using struct consolefontdesc */
 #define PIO_FONTX	0x4B6C	/* set font using struct consolefontdesc */
 struct consolefontdesc {
-	u_short charcount;	/* characters in font (256 or 512) */
-	u_short charheight;	/* scan lines per character (1-32) */
+	unsigned short charcount;	/* characters in font (256 or 512) */
+	unsigned short charheight;	/* scan lines per character (1-32) */
 	char *chardata;		/* font data in expanded form */
 };
 
@@ -58,19 +58,19 @@
 
 #define GIO_UNIMAP	0x4B66	/* get unicode-to-font mapping from kernel */
 struct unipair {
-	u_short unicode;
-	u_short fontpos;
+	unsigned short unicode;
+	unsigned short fontpos;
 };
 struct unimapdesc {
-	u_short entry_ct;
+	unsigned short entry_ct;
 	struct unipair *entries;
 };
 #define PIO_UNIMAP	0x4B67	/* put unicode-to-font mapping in kernel */
 #define PIO_UNIMAPCLR	0x4B68	/* clear table, possibly advise hash algorithm */
 struct unimapinit {
-	u_short advised_hashsize;  /* 0 if no opinion */
-	u_short advised_hashstep;  /* 0 if no opinion */
-	u_short advised_hashlevel; /* 0 if no opinion */
+	unsigned short advised_hashsize;  /* 0 if no opinion */
+	unsigned short advised_hashstep;  /* 0 if no opinion */
+	unsigned short advised_hashlevel; /* 0 if no opinion */
 };
 
 #define UNI_DIRECT_BASE 0xF000	/* start of Direct Font Region */
@@ -95,9 +95,9 @@
 #define KDSKBLED	0x4B65	/* set led flags (not lights) */
 
 struct kbentry {
-	u_char kb_table;
-	u_char kb_index;
-	u_short kb_value;
+	unsigned char kb_table;
+	unsigned char kb_index;
+	unsigned short kb_value;
 };
 #define		K_NORMTAB	0x00
 #define		K_SHIFTTAB	0x01
@@ -108,14 +108,14 @@
 #define KDSKBENT	0x4B47	/* sets one entry in translation table */
 
 struct kbsentry {
-	u_char kb_func;
-	u_char kb_string[512];
+	unsigned char kb_func;
+	unsigned char kb_string[512];
 };
 #define KDGKBSENT	0x4B48	/* gets one function key string entry */
 #define KDSKBSENT	0x4B49	/* sets one function key string entry */
 
 struct kbdiacr {
-        u_char diacr, base, result;
+        unsigned char diacr, base, result;
 };
 struct kbdiacrs {
         unsigned int kb_cnt;    /* number of entries in following array */
diff -u --recursive --new-file v1.3.77/linux/include/linux/kerneld.h linux/include/linux/kerneld.h
--- v1.3.77/linux/include/linux/kerneld.h	Sun Jan 14 16:30:14 1996
+++ linux/include/linux/kerneld.h	Mon Mar 25 08:58:22 1996
@@ -8,6 +8,7 @@
 #define KERNELD_CANCEL_RELEASE_MODULE 5 /* "rmmod" */
 #define KERNELD_REQUEST_ROUTE 6 /* from net/ipv4/route.c */
 #define KERNELD_BLANKER 7 /* from drivers/char/console.c */
+#define KERNELD_ARP 256 /* from net/ipv4/arp.c */
 
 #define IPC_KERNELD 00040000   /* use the kerneld message channel */
 #define KERNELD_MAXCMD 0x7ffeffff
diff -u --recursive --new-file v1.3.77/linux/include/linux/loop.h linux/include/linux/loop.h
--- v1.3.77/linux/include/linux/loop.h	Tue Mar  5 10:11:12 1996
+++ linux/include/linux/loop.h	Sun Mar 24 20:07:01 1996
@@ -12,6 +12,8 @@
 
 #define LO_NAME_SIZE	64
 #define LO_KEY_SIZE	32
+
+#ifdef __KERNEL__
        
 struct loop_device {
 	int		lo_number;
@@ -39,6 +41,9 @@
  * Loop flags
  */
 #define LO_FLAGS_DO_BMAP	0x00000001
+#define LO_FLAGS_READ_ONLY	0x00000002
+
+#endif /* __KERNEL__ */
 
 struct loop_info {
 	int		lo_number;	/* ioctl r/o */
diff -u --recursive --new-file v1.3.77/linux/include/linux/mcdx.h linux/include/linux/mcdx.h
--- v1.3.77/linux/include/linux/mcdx.h	Sun Mar 17 09:04:07 1996
+++ linux/include/linux/mcdx.h	Fri Mar 22 09:42:18 1996
@@ -1,7 +1,7 @@
 /*
  * Definitions for the Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.8
+ * VERSION: 1.9
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff -u --recursive --new-file v1.3.77/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h
--- v1.3.77/linux/include/linux/ncp_fs.h	Tue Mar  5 10:11:12 1996
+++ linux/include/linux/ncp_fs.h	Mon Mar 25 10:26:16 1996
@@ -34,18 +34,16 @@
 	int    buffer_size;	/* The negotiated buffer size, to be
 				   used for read/write requests! */
 
-	/* Not used yet, but here some day the namespace numbers will be
-	   stored. */
 	int    volume_number;
 	__u32  directory_id;
 };	
 
-#define	NCP_IOC_NCPREQUEST		_IOR('n', 1, unsigned char *)
-#define	NCP_IOC_GETMOUNTUID		_IOR('u', 1, uid_t)
-#define NCP_IOC_CONN_LOGGED_IN          _IO('l', 1)
+#define	NCP_IOC_NCPREQUEST		_IOR('n', 1, struct ncp_ioctl_request)
+#define	NCP_IOC_GETMOUNTUID		_IOW('n', 2, uid_t)
+#define NCP_IOC_CONN_LOGGED_IN          _IO('n', 3)
 
 #define NCP_GET_FS_INFO_VERSION (1)
-#define NCP_IOC_GET_FS_INFO             _IOWR('i', 1, unsigned char *)
+#define NCP_IOC_GET_FS_INFO             _IOWR('n', 4, struct ncp_fs_info)
 
 /*
  * The packet size to allocate. One page should be enough.
diff -u --recursive --new-file v1.3.77/linux/include/linux/net.h linux/include/linux/net.h
--- v1.3.77/linux/include/linux/net.h	Wed Nov  8 07:11:42 1995
+++ linux/include/linux/net.h	Mon Mar 25 08:58:22 1996
@@ -83,6 +83,7 @@
   struct wait_queue	**wait;		/* ptr to place to wait on	*/
   struct inode		*inode;
   struct fasync_struct  *fasync_list;	/* Asynchronous wake up list	*/
+  struct file		*file;		/* File back pointer for gc	*/
 };
 
 #define SOCK_INODE(S)	((S)->inode)
diff -u --recursive --new-file v1.3.77/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v1.3.77/linux/include/linux/netdevice.h	Thu Mar 21 20:36:53 1996
+++ linux/include/linux/netdevice.h	Mon Mar 25 10:24:33 1996
@@ -187,6 +187,8 @@
 #define HAVE_HEADER_CACHE
   void			  (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, unsigned short htype, __u32 daddr);
   void			  (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char *  haddr);
+#define HAVE_CHANGE_MTU
+  int			  (*change_mtu)(struct device *dev, int new_mtu);            
 };
 
 
diff -u --recursive --new-file v1.3.77/linux/include/linux/optcd.h linux/include/linux/optcd.h
--- v1.3.77/linux/include/linux/optcd.h	Wed Feb 28 11:50:13 1996
+++ linux/include/linux/optcd.h	Fri Mar 22 15:45:05 1996
@@ -43,7 +43,7 @@
 #define STOP_TIMEOUT		1000		/* for poll wait */
 #define RESET_WAIT		1000		/* busy wait at drive reset */
 
-/* # of buffer for block size conversion. 6 is optimal for my setup (P75),
+/* # of buffers for block size conversion. 6 is optimal for my setup (P75),
    giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal
    setting */
 #define N_BUFS		6
diff -u --recursive --new-file v1.3.77/linux/include/linux/pci.h linux/include/linux/pci.h
--- v1.3.77/linux/include/linux/pci.h	Sun Mar 10 09:49:57 1996
+++ linux/include/linux/pci.h	Fri Mar 22 13:01:47 1996
@@ -31,10 +31,14 @@
  *	  PCI-CPU bridge or PCI-ISA bridge.
  *	- If you can't find the actual information in your hardware
  *	  booklet, try to read the references of the chip on the board.
- *	- Send all that, with the word PCIPROBE in the subject,
- *	  to frederic@cao-vlsi.ibp.fr, and I'll add your device to 
- *	  the list as soon as possible
- *		fred.
+ *	- Send all that to linux-pcisupport@cao-vlsi.ibp.fr,
+ *	  and I'll add your device to the list as soon as possible
+ *
+ * BEFORE you send a mail, please check the latest linux releases
+ * to be sure it has not been recently added.
+ *
+ *        Thanks
+ *		Frederic Potter.
  */
 
 
@@ -266,7 +270,6 @@
 #define PCI_DEVICE_ID_CIRRUS_5434_4	0x00a4
 #define PCI_DEVICE_ID_CIRRUS_5434_8	0x00a8
 #define PCI_DEVICE_ID_CIRRUS_5436	0x00ac
-#define PCI_DEVICE_ID_CIRRUS_6205	0x0205
 #define PCI_DEVICE_ID_CIRRUS_6729	0x1100
 #define PCI_DEVICE_ID_CIRRUS_7542	0x1200
 #define PCI_DEVICE_ID_CIRRUS_7543	0x1202
@@ -299,6 +302,7 @@
 #define PCI_DEVICE_ID_CT_65548		0x00dc
 
 #define PCI_VENDOR_ID_MIRO		0x1031
+#define PCI_DEVICE_ID_MIRO_36050	0x5601
 
 #define PCI_VENDOR_ID_FD		0x1036
 #define PCI_DEVICE_ID_FD_36C70		0x0000
@@ -306,6 +310,7 @@
 #define PCI_VENDOR_ID_SI		0x1039
 #define PCI_DEVICE_ID_SI_6201		0x0001
 #define PCI_DEVICE_ID_SI_6202		0x0002
+#define PCI_DEVICE_ID_SI_6205		0x0205
 #define PCI_DEVICE_ID_SI_503		0x0008
 #define PCI_DEVICE_ID_SI_501		0x0406
 #define PCI_DEVICE_ID_SI_496		0x0496
@@ -442,7 +447,20 @@
 #define PCI_DEVICE_ID_VIA_82C416	0x1571
 
 #define PCI_VENDOR_ID_VORTEX		0x1119
-#define PCI_DEVICE_ID_VORTEX_GDT	0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT60x0	0x0000
+#define PCI_DEVICE_ID_VORTEX_GDT6000B	0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT6x10	0x0002
+#define PCI_DEVICE_ID_VORTEX_GDT6x20	0x0003
+#define PCI_DEVICE_ID_VORTEX_GDT6530	0x0004
+#define PCI_DEVICE_ID_VORTEX_GDT6550	0x0005
+#define PCI_DEVICE_ID_VORTEX_GDT6x17	0x0006
+#define PCI_DEVICE_ID_VORTEX_GDT6x27	0x0007
+#define PCI_DEVICE_ID_VORTEX_GDT6537	0x0008
+#define PCI_DEVICE_ID_VORTEX_GDT6557	0x0009
+#define PCI_DEVICE_ID_VORTEX_GDT6x15	0x000a
+#define PCI_DEVICE_ID_VORTEX_GDT6x25	0x000b
+#define PCI_DEVICE_ID_VORTEX_GDT6535	0x000c
+#define PCI_DEVICE_ID_VORTEX_GDT6555	0x000d
 
 #define PCI_VENDOR_ID_EF		0x111a
 #define PCI_DEVICE_ID_EF_ATM_FPGA	0x0000
@@ -450,6 +468,7 @@
 
 #define PCI_VENDOR_ID_FORE		0x1127
 #define PCI_DEVICE_ID_FORE_PCA200PC	0x0210
+#define PCI_DEVICE_ID_FORE_PCA200E	0x0300
 
 #define PCI_VENDOR_ID_IMAGINGTECH	0x112f
 #define PCI_DEVICE_ID_IMAGINGTECH_ICPCI	0x0000
diff -u --recursive --new-file v1.3.77/linux/include/linux/posix_types.h linux/include/linux/posix_types.h
--- v1.3.77/linux/include/linux/posix_types.h	Thu Jan  1 02:00:00 1970
+++ linux/include/linux/posix_types.h	Sun Mar 24 14:39:10 1996
@@ -0,0 +1,59 @@
+#ifndef _LINUX_POSIX_TYPES_H
+#define _LINUX_POSIX_TYPES_H
+
+#define _GNU_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.
+ */
+
+#ifndef NULL
+# define NULL		((void *) 0)
+#endif
+
+/*
+ * This allows for 256 file descriptors: if NR_OPEN is ever grown
+ * beyond that you'll have to change this too. But 256 fd's seem to be
+ * enough even for such "real" unices like SunOS, so hopefully this is
+ * one limit that doesn't have to be changed.
+ *
+ * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in
+ * <sys/time.h> (and thus <linux/time.h>) - but this is a more logical
+ * place for them. Solved by having dummy defines in <sys/time.h>.
+ */
+
+/*
+ * Those macros may have been defined in <gnu/types.h>. But we always
+ * use the ones here. 
+ */
+#undef __NFDBITS
+#define __NFDBITS	(8 * sizeof(unsigned int))
+
+#undef __FD_SETSIZE
+#define __FD_SETSIZE	256
+
+#undef __FDSET_INTS
+#define __FDSET_INTS	(__FD_SETSIZE/__NFDBITS)
+
+#undef __FDELT
+#define	__FDELT(d)	((d) / __NFDBITS)
+
+#undef __FDMASK
+#define	__FDMASK(d)	(1 << ((d) % __NFDBITS))
+
+typedef struct fd_set {
+	unsigned int fds_bits [__FDSET_INTS];
+} __fd_set;
+
+#include <asm/posix_types.h>
+
+/* bsd */
+
+typedef unsigned char	__u_char;
+typedef unsigned short	__u_short;
+typedef unsigned int	__u_int;
+typedef unsigned long	__u_long;
+
+#endif /* _LINUX_POSIX_TYPES_H */
diff -u --recursive --new-file v1.3.77/linux/include/linux/sched.h linux/include/linux/sched.h
--- v1.3.77/linux/include/linux/sched.h	Wed Mar 13 10:09:23 1996
+++ linux/include/linux/sched.h	Mon Mar 25 10:22:43 1996
@@ -260,7 +260,7 @@
 #define PF_PTRACED	0x00000010	/* set if ptrace (0) has been called. */
 #define PF_TRACESYS	0x00000020	/* tracing system calls */
 #define PF_FORKNOEXEC	0x00000040	/* forked but didn't exec */
-#define PF_SUPERPREV	0x00000100	/* used super-user privileges */
+#define PF_SUPERPRIV	0x00000100	/* used super-user privileges */
 #define PF_DUMPCORE	0x00000200	/* dumped core */
 #define PF_SIGNALED	0x00000400	/* killed by a signal */
 
@@ -362,7 +362,7 @@
 extern inline int suser(void)
 {
 	if (current->euid == 0)
-		current->flags |= PF_SUPERPREV;
+		current->flags |= PF_SUPERPRIV;
 	return (current->euid == 0);
 }
 
diff -u --recursive --new-file v1.3.77/linux/include/linux/sdla.h linux/include/linux/sdla.h
--- v1.3.77/linux/include/linux/sdla.h	Thu Jan  1 02:00:00 1970
+++ linux/include/linux/sdla.h	Mon Mar 25 08:58:22 1996
@@ -0,0 +1,327 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		Global definitions for the Frame relay interface.
+ *
+ * Version:	@(#)if_ifrad.h	0.10	23 Mar 96
+ *
+ * Author:	Mike McLagan <mike.mclagan@linux.org>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#ifndef SDLA_H
+#define SDLA_H
+
+/* adapter type */
+#define SDLA_TYPES
+#define SDLA_S502A			5020
+#define SDLA_S502E			5021
+#define SDLA_S503			5030
+#define SDLA_S507			5070
+#define SDLA_S508			5080
+#define SDLA_S509			5090
+#define SDLA_UNKNOWN			-1
+
+/* port selection flags for the S508 */
+#define SDLA_S508_PORT_V35		0x00
+#define SDLA_S508_PORT_RS232		0x02
+
+/* Z80 CPU speeds */
+#define SDLA_CPU_3M			0x00
+#define SDLA_CPU_5M			0x01
+#define SDLA_CPU_7M			0x02
+#define SDLA_CPU_8M			0x03
+#define SDLA_CPU_10M			0x04
+#define SDLA_CPU_16M			0x05
+#define SDLA_CPU_12M			0x06
+
+/* some private IOCTLs */
+#define SDLA_IDENTIFY			(FRAD_LAST_IOCTL + 1)
+#define SDLA_CPUSPEED			(FRAD_LAST_IOCTL + 2)
+#define SDLA_PROTOCOL			(FRAD_LAST_IOCTL + 3)
+
+#define SDLA_CLEARMEM			(FRAD_LAST_IOCTL + 4)
+#define SDLA_WRITEMEM			(FRAD_LAST_IOCTL + 5)
+#define SDLA_READMEM			(FRAD_LAST_IOCTL + 6)
+
+struct sdla_mem {
+   int  addr;
+   int  len;
+   void *data;
+};
+
+#define SDLA_START			(FRAD_LAST_IOCTL + 7)
+#define SDLA_STOP			(FRAD_LAST_IOCTL + 8)
+
+/* some offsets in the Z80's memory space */
+#define SDLA_NMIADDR			0x0000
+#define SDLA_CONF_ADDR			0x0010
+#define SDLA_S502A_NMIADDR		0x0066
+#define SDLA_CODE_BASEADDR		0x0100
+
+/* largest handlable block of data */
+#define SDLA_MAX_DATA			4080
+#define SDLA_MAX_MTU			4072	/* MAX_DATA - sizeof(fradhdr) */
+#define SDLA_MAX_DLCI			24
+
+struct sdla_conf {
+   short station;
+   short config;
+   short kbaud;
+   short clocking;
+   short max_frm;
+   short T391;
+   short T392;
+   short N391;
+   short N392;
+   short N393;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd;
+};
+
+struct sdla_dlci {
+   short config;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd; 
+
+/* these are part of the status READ */
+   short Tc_fwd;
+   short Tc_bwd;
+   short Tf_max;
+   short Tb_max;
+};
+
+#ifndef __KERNEL__
+
+void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet);
+
+#else
+
+/* important Z80 window addresses */
+#define SDLA_CONTROL_WND		0xE000
+
+#define SDLA_502_CMD_BUF		0xEF60
+#define SDLA_502_RCV_BUF		0xA900
+#define	SDLA_502_TXN_AVAIL		0xFFF1
+#define SDLA_502_RCV_AVAIL		0xFFF2
+#define SDLA_502_EVENT_FLAGS		0xFFF3
+#define SDLA_502_MDM_STATUS		0xFFF4
+#define SDLA_502_IRQ_INTERFACE		0xFFFD
+#define SDLA_502_IRQ_PERMISSION		0xFFFE
+#define SDLA_502_DATA_OFS		0x0010
+
+#define SDLA_508_CMD_BUF		0xE000
+#define SDLA_508_TXBUF_INFO		0xF100
+#define SDLA_508_RXBUF_INFO		0xF120
+#define SDLA_508_EVENT_FLAGS		0xF003
+#define SDLA_508_MDM_STATUS		0xF004
+#define SDLA_508_IRQ_INTERFACE		0xF010
+#define SDLA_508_IRQ_PERMISSION		0xF011
+#define SDLA_508_TSE_OFFSET		0xF012
+
+/* Event flags */
+#define SDLA_EVENT_STATUS		0x01
+#define SDLA_EVENT_DLCI_STATUS		0x02
+#define SDLA_EVENT_BAD_DLCI		0x04
+#define SDLA_EVENT_LINK_DOWN		0x40
+
+/* IRQ Trigger flags */
+#define SDLA_INTR_RX			0x01
+#define SDLA_INTR_TX			0x02
+#define SDLA_INTR_MODEM			0x04
+#define SDLA_INTR_COMPLETE		0x08
+#define SDLA_INTR_STATUS		0x10
+#define SDLA_INTR_TIMER			0x20
+
+/* DLCI status bits */
+#define SDLA_DLCI_DELETED		0x01
+#define SDLA_DLCI_ACTIVE		0x02
+#define SDLA_DLCI_WAITING		0x04
+#define SDLA_DLCI_NEW			0x08
+#define SDLA_DLCI_INCLUDED		0x40
+
+/* valid command codes */
+#define	SDLA_INFORMATION_WRITE		0x01
+#define	SDLA_INFORMATION_READ		0x02
+#define SDLA_ISSUE_IN_CHANNEL_SIGNAL	0x03
+#define	SDLA_SET_DLCI_CONFIGURATION	0x10
+#define	SDLA_READ_DLCI_CONFIGURATION	0x11
+#define	SDLA_DISABLE_COMMUNICATIONS	0x12
+#define	SDLA_ENABLE_COMMUNICATIONS	0x13
+#define	SDLA_READ_DLC_STATUS		0x14
+#define	SDLA_READ_DLC_STATISTICS	0x15
+#define	SDLA_FLUSH_DLC_STATISTICS	0x16
+#define	SDLA_LIST_ACTIVE_DLCI		0x17
+#define	SDLA_FLUSH_INFORMATION_BUFFERS	0x18
+#define	SDLA_ADD_DLCI			0x20
+#define	SDLA_DELETE_DLCI		0x21
+#define	SDLA_ACTIVATE_DLCI		0x22
+#define	SDLA_DEACTIVATE_DLCI		0x23
+#define	SDLA_READ_MODEM_STATUS		0x30
+#define	SDLA_SET_MODEM_STATUS		0x31
+#define	SDLA_READ_COMMS_ERR_STATS	0x32
+#define SDLA_FLUSH_COMMS_ERR_STATS	0x33
+#define	SDLA_READ_CODE_VERSION		0x40
+#define SDLA_SET_IRQ_TRIGGER		0x50
+#define SDLA_GET_IRQ_TRIGGER		0x51
+
+/* In channel signal types */
+#define SDLA_ICS_LINK_VERIFY		0x02
+#define SDLA_ICS_STATUS_ENQ		0x03
+
+/* modem status flags */
+#define SDLA_MODEM_DTR_HIGH		0x01
+#define SDLA_MODEM_RTS_HIGH		0x02
+#define SDLA_MODEM_DCD_HIGH		0x08
+#define SDLA_MODEM_CTS_HIGH		0x20
+
+/* used for RET_MODEM interpretation */
+#define SDLA_MODEM_DCD_LOW		0x01
+#define SDLA_MODEM_CTS_LOW		0x02
+
+/* return codes */
+#define SDLA_RET_OK			0x00
+#define SDLA_RET_COMMUNICATIONS		0x01
+#define SDLA_RET_CHANNEL_INACTIVE	0x02
+#define SDLA_RET_DLCI_INACTIVE		0x03
+#define SDLA_RET_DLCI_CONFIG		0x04
+#define SDLA_RET_BUF_TOO_BIG		0x05
+#define SDLA_RET_NO_DATA		0x05
+#define SDLA_RET_BUF_OVERSIZE		0x06
+#define SDLA_RET_CIR_OVERFLOW		0x07
+#define SDLA_RET_NO_BUFF		0x08
+#define SDLA_RET_TIMEOUT		0x0A
+#define SDLA_RET_MODEM			0x10
+#define SDLA_RET_CHANNEL_OFF		0x11
+#define SDLA_RET_CHANNEL_ON		0x12
+#define SDLA_RET_DLCI_STATUS		0x13
+#define SDLA_RET_DLCI_UNKNOWN       	0x14
+#define SDLA_RET_COMMAND_INVALID    	0x1F
+
+/* Configuration flags */
+#define SDLA_DIRECT_RECV		0x0080
+
+/* IRQ selection flags */
+#define SDLA_IRQ_RECEIVE		0x01
+#define SDLA_IRQ_TRANSMIT		0x02
+#define SDLA_IRQ_MODEM_STAT		0x04
+#define SDLA_IRQ_COMMAND		0x08
+#define SDLA_IRQ_CHANNEL		0x10
+#define SDLA_IRQ_TIMER			0x20
+
+/* definitions for PC memory mapping */
+#define SDLA_8K_WINDOW			0x01
+#define SDLA_S502_SEG_A			0x10
+#define SDLA_S502_SEG_C			0x20
+#define SDLA_S502_SEG_D			0x00
+#define SDLA_S502_SEG_E			0x30
+#define SDLA_S507_SEG_A			0x00
+#define SDLA_S507_SEG_B			0x40
+#define SDLA_S507_SEG_C			0x80
+#define SDLA_S507_SEG_E			0xC0
+#define SDLA_S508_SEG_A			0x00
+#define SDLA_S508_SEG_C			0x10
+#define SDLA_S508_SEG_D			0x08
+#define SDLA_S508_SEG_E			0x18
+
+/* SDLA adapter port constants */
+#define SDLA_IO_EXTENTS			0x04
+	
+#define SDLA_REG_CONTROL		0x00
+#define SDLA_REG_PC_WINDOW		0x01	/* offset for PC window select latch */
+#define SDLA_REG_Z80_WINDOW 		0x02	/* offset for Z80 window select latch */
+#define SDLA_REG_Z80_CONTROL		0x03	/* offset for Z80 control latch */
+	
+#define SDLA_S502_STS			0x00	/* status reg for 502, 502E, 507 */
+#define SDLA_S508_GNRL			0x00	/* general purp. reg for 508 */
+#define SDLA_S508_STS			0x01	/* status reg for 508 */
+#define SDLA_S508_IDR			0x02	/* ID reg for 508 */
+	
+/* control register flags */
+#define SDLA_S502A_START		0x00	/* start the CPU */
+#define SDLA_S502A_INTREQ		0x02
+#define SDLA_S502A_INTEN		0x04
+#define SDLA_S502A_HALT			0x08	/* halt the CPU */	
+#define SDLA_S502A_NMI			0x10	/* issue an NMI to the CPU */
+
+#define SDLA_S502E_CPUEN		0x01
+#define SDLA_S502E_ENABLE		0x02
+#define SDLA_S502E_INTACK		0x04
+	
+#define SDLA_S507_ENABLE		0x01
+#define SDLA_S507_IRQ3			0x00
+#define SDLA_S507_IRQ4			0x20
+#define SDLA_S507_IRQ5			0x40
+#define SDLA_S507_IRQ7			0x60
+#define SDLA_S507_IRQ10			0x80
+#define SDLA_S507_IRQ11			0xA0
+#define SDLA_S507_IRQ12			0xC0
+#define SDLA_S507_IRQ15			0xE0
+	
+#define SDLA_HALT			0x00
+#define SDLA_CPUEN			0x02
+#define SDLA_MEMEN			0x04
+#define SDLA_S507_EPROMWR		0x08
+#define SDLA_S507_EPROMCLK		0x10
+#define SDLA_S508_INTRQ			0x08
+#define SDLA_S508_INTEN			0x10
+
+struct sdla_cmd {
+   char  opp_flag		__attribute__((packed));
+   char  cmd			__attribute__((packed));
+   short length			__attribute__((packed));
+   char  retval			__attribute__((packed));
+   short dlci			__attribute__((packed));
+   char  flags			__attribute__((packed));
+   short rxlost_int		__attribute__((packed));
+   long  rxlost_app		__attribute__((packed));
+   char  reserve[2]		__attribute__((packed));
+   char  data[SDLA_MAX_DATA]	__attribute__((packed));	/* transfer data buffer */
+};
+
+struct intr_info {
+   char  flags		__attribute__((packed));
+   short txlen		__attribute__((packed));
+   char  irq		__attribute__((packed));
+   char  flags2		__attribute__((packed));
+   short timeout	__attribute__((packed));
+};
+
+/* found in the 508's control window at RXBUF_INFO */
+struct buf_info {
+   unsigned short rse_num	__attribute__((packed));
+   unsigned long  rse_base	__attribute__((packed));
+   unsigned long  rse_next	__attribute__((packed));
+   unsigned long  buf_base	__attribute__((packed));
+   unsigned short reserved	__attribute__((packed));
+   unsigned long  buf_top	__attribute__((packed));
+};
+
+/* structure pointed to by rse_base in RXBUF_INFO struct */
+struct buf_entry {
+   char  opp_flag	__attribute__((packed));
+   short length		__attribute__((packed));
+   short dlci		__attribute__((packed));
+   char  flags		__attribute__((packed));
+   short timestamp	__attribute__((packed));
+   short reserved[2]	__attribute__((packed));
+   long  buf_addr	__attribute__((packed));
+};
+
+#endif
+
+#endif
diff -u --recursive --new-file v1.3.77/linux/include/linux/smp.h linux/include/linux/smp.h
--- v1.3.77/linux/include/linux/smp.h	Sun Mar 17 09:04:08 1996
+++ linux/include/linux/smp.h	Mon Mar 25 08:58:22 1996
@@ -14,7 +14,6 @@
 extern void smp_callin(void);			/* Processor call in. Must hold processors until .. */
 extern void smp_commence(void);			/* Multiprocessors may now schedule */
 extern int smp_num_cpus;
-extern int smp_top_cpu;				/* Top CPU number  */
 extern int smp_threads_ready;			/* True once the per process idle is forked */
 #ifdef __SMP_PROF__
 extern volatile unsigned long smp_spins[NR_CPUS];	/* count of interrupt spins */
@@ -48,7 +47,6 @@
  
 #define smp_num_cpus			1
 #define smp_processor_id()		0
-#define smp_top_cpu			0
 #define smp_message_pass(t,m,d,w)	
 #define smp_threads_ready		1
 #define kernel_lock()
diff -u --recursive --new-file v1.3.77/linux/include/linux/socket.h linux/include/linux/socket.h
--- v1.3.77/linux/include/linux/socket.h	Sun Mar 10 09:49:57 1996
+++ linux/include/linux/socket.h	Sun Mar 24 13:33:16 1996
@@ -96,6 +96,8 @@
 #define SOL_TCP		6
 #define SOL_UDP		17
 
+#ifdef __KERNEL__
+
 /* IP options */
 #define IP_TOS		1
 #define	IPTOS_LOWDELAY		0x10
@@ -111,6 +113,7 @@
 #define IP_ADD_MEMBERSHIP		35
 #define IP_DROP_MEMBERSHIP		36
 
+#endif /* __KERNEL__ */
 
 /* These need to appear somewhere around here */
 #define IP_DEFAULT_MULTICAST_TTL        1
diff -u --recursive --new-file v1.3.77/linux/include/linux/sockios.h linux/include/linux/sockios.h
--- v1.3.77/linux/include/linux/sockios.h	Fri Feb  9 17:53:10 1996
+++ linux/include/linux/sockios.h	Sun Mar 24 13:33:16 1996
@@ -18,6 +18,8 @@
 #ifndef _LINUX_SOCKIOS_H
 #define _LINUX_SOCKIOS_H
 
+#include <asm/sockios.h>
+
 /* Routing table calls. */
 #define SIOCADDRT	0x890B		/* add routing table entry	*/
 #define SIOCDELRT	0x890C		/* delete routing table entry	*/
diff -u --recursive --new-file v1.3.77/linux/include/linux/tty.h linux/include/linux/tty.h
--- v1.3.77/linux/include/linux/tty.h	Sun Mar 17 09:04:08 1996
+++ linux/include/linux/tty.h	Mon Mar 25 10:22:43 1996
@@ -5,6 +5,16 @@
  * 'tty.h' defines some structures used by tty_io.c and some defines.
  */
 
+/*
+ * These constants are also useful for user-level apps (e.g., VC
+ * resizing).
+ */
+#define MIN_NR_CONSOLES	1	/* must be at least 1 */
+#define MAX_NR_CONSOLES	63	/* serial lines start at 64 */
+#define MAX_NR_USER_CONSOLES 63	/* must be root to allocate above this */
+		/* Note: the ioctl VT_GETSTATE does not work for
+		   consoles 16 and higher (since it returns a short) */
+
 #ifdef __KERNEL__
 #include <linux/fs.h>
 #include <linux/termios.h>
@@ -21,11 +31,6 @@
  * (Note: the *_driver.minor_start values 1, 64, 128, 192 are
  * hardcoded at present.)
  */
-#define MIN_NR_CONSOLES	1	/* must be at least 1 */
-#define MAX_NR_CONSOLES	63	/* serial lines start at 64 */
-#define MAX_NR_USER_CONSOLES 63	/* must be root to allocate above this */
-		/* Note: the ioctl VT_GETSTATE does not work for
-		   consoles 16 and higher (since it returns a short) */
 #define NR_PTYS		256
 #define NR_LDISCS	16
 
diff -u --recursive --new-file v1.3.77/linux/include/linux/types.h linux/include/linux/types.h
--- v1.3.77/linux/include/linux/types.h	Sun Sep  3 12:27:03 1995
+++ linux/include/linux/types.h	Mon Mar 25 10:22:30 1996
@@ -1,68 +1,92 @@
 #ifndef _LINUX_TYPES_H
 #define _LINUX_TYPES_H
 
-/*
- * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that
- * you'll have to change this too. But 256 fd's seem to be enough even for such
- * "real" unices like SunOS, so hopefully this is one limit that doesn't have
- * to be changed.
- *
- * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in <sys/time.h>
- * (and thus <linux/time.h>) - but this is a more logical place for them. Solved
- * by having dummy defines in <sys/time.h>.
- */
+#include <linux/posix_types.h>
+#include <asm/types.h>
+
+#ifndef _LINUX_TYPES_DONT_EXPORT
+
+typedef __fd_set	fd_set;
+typedef __dev_t		dev_t;
+typedef __ino_t		ino_t;
+typedef __mode_t	mode_t;
+typedef __nlink_t	nlink_t;
+typedef __off_t		off_t;
+typedef __pid_t		pid_t;
+typedef __uid_t		uid_t;
+typedef __gid_t		gid_t;
+typedef __daddr_t	daddr_t;
+
+/* bsd */
+
+typedef __u_char	u_char;
+typedef __u_short	u_short;
+typedef __u_int		u_int;
+typedef __u_long	u_long;
 
 /*
- * Those macros may have been defined in <gnu/types.h>. But we always
- * use the ones here. 
+ * The following typedefs are also protected by individual ifdefs for
+ * historical reasons:
  */
-#undef __NFDBITS
-#define __NFDBITS	(8 * sizeof(unsigned int))
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __size_t	size_t;
+#endif
 
-#undef __FD_SETSIZE
-#define __FD_SETSIZE	256
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef __ssize_t	ssize_t;
+#endif
 
-#undef __FDSET_INTS
-#define __FDSET_INTS	(__FD_SETSIZE/__NFDBITS)
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
+typedef __ptrdiff_t	ptrdiff_t;
+#endif
 
-typedef struct fd_set {
-	unsigned int fds_bits [__FDSET_INTS];
-} fd_set;
+#ifndef _TIME_T
+#define _TIME_T
+typedef __time_t	time_t;
+#endif
 
-#include <asm/types.h>
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef __clock_t	clock_t;
+#endif
 
-#ifndef NULL
-#define NULL ((void *) 0)
+#ifndef _CADDR_T
+#define _CADDR_T
+typedef __caddr_t	caddr_t;
 #endif
 
+/* sysv */
+typedef unsigned char	unchar;
+typedef unsigned short	ushort;
+typedef unsigned int	uint;
+typedef unsigned long	ulong;
+
+#endif /* _LINUX_TYPES_DONT_EXPORT */
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
+
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+
+typedef long long	__loff_t;
+
+#ifndef _LINUX_TYPES_DONT_EXPORT
 #define _LOFF_T
-typedef long long loff_t;
+typedef __loff_t	loff_t;
 #endif
 
-/* bsd */
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-
-/* sysv */
-typedef unsigned char unchar;
-typedef unsigned short ushort;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-
-typedef char *caddr_t;
-
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
+#endif
 
 struct ustat {
-	daddr_t f_tfree;
-	ino_t f_tinode;
-	char f_fname[6];
-	char f_fpack[6];
+	__daddr_t	f_tfree;
+	__ino_t		f_tinode;
+	char		f_fname[6];
+	char		f_fpack[6];
 };
 
-#endif
+#endif /* _LINUX_TYPES_H */
diff -u --recursive --new-file v1.3.77/linux/include/linux/vt.h linux/include/linux/vt.h
--- v1.3.77/linux/include/linux/vt.h	Wed Dec 13 09:02:47 1995
+++ linux/include/linux/vt.h	Sun Mar 24 12:09:37 1996
@@ -19,9 +19,9 @@
 #define		VT_ACKACQ	0x02	/* acknowledge switch */
 
 struct vt_stat {
-	ushort v_active;	/* active vt */
-	ushort v_signal;	/* signal to send */
-	ushort v_state;		/* vt bitmask */
+	unsigned short v_active;	/* active vt */
+	unsigned short v_signal;	/* signal to send */
+	unsigned short v_state;		/* vt bitmask */
 };
 #define VT_GETSTATE	0x5603	/* get global vt state info */
 #define VT_SENDSIG	0x5604	/* signal to send to bitmask of vts */
@@ -33,19 +33,19 @@
 #define VT_DISALLOCATE	0x5608  /* free memory associated to vt */
 
 struct vt_sizes {
-	ushort v_rows;		/* number of rows */
-	ushort v_cols;		/* number of columns */
-	ushort v_scrollsize;	/* number of lines of scrollback */
+	unsigned short v_rows;		/* number of rows */
+	unsigned short v_cols;		/* number of columns */
+	unsigned short v_scrollsize;	/* number of lines of scrollback */
 };
 #define VT_RESIZE	0x5609	/* set kernel's idea of screensize */
 
 struct vt_consize {
-        ushort v_rows;		/* number of rows */
-	ushort v_cols;		/* number of columns */
-	ushort v_vlin;		/* number of pixel rows on screen */
-	ushort v_clin;		/* number of pixel rows per character */
-	ushort v_vcol;		/* number of pixel columns on screen */
-	ushort v_ccol;		/* number of pixel columns per character */
+	unsigned short v_rows;	/* number of rows */
+	unsigned short v_cols;	/* number of columns */
+	unsigned short v_vlin;	/* number of pixel rows on screen */
+	unsigned short v_clin;	/* number of pixel rows per character */
+	unsigned short v_vcol;	/* number of pixel columns on screen */
+	unsigned short v_ccol;	/* number of pixel columns per character */
 };
 #define VT_RESIZEX      0x560A  /* set kernel's idea of screensize + more */
 #define VT_LOCKSWITCH   0x560B  /* disallow vt switching */
diff -u --recursive --new-file v1.3.77/linux/include/net/af_unix.h linux/include/net/af_unix.h
--- v1.3.77/linux/include/net/af_unix.h	Tue Mar  5 10:11:13 1996
+++ linux/include/net/af_unix.h	Mon Mar 25 08:58:22 1996
@@ -1,9 +1,9 @@
 extern void unix_proto_init(struct net_proto *pro);
-
+extern struct proto_ops unix_proto_ops;
+extern void unix_inflight(struct file *fp);
+extern void unix_notinflight(struct file *fp);
 typedef struct sock unix_socket;
 
-extern int unix_gc_free;
-extern void unix_gc_add(struct sock *sk, struct file *fp);
-extern void unix_gc_remove(struct file *fp);
+unix_socket *unix_socket_list;
 
 #define UNIX_MAX_FD	8
diff -u --recursive --new-file v1.3.77/linux/include/net/gc.h linux/include/net/gc.h
--- v1.3.77/linux/include/net/gc.h	Thu Jan  1 02:00:00 1970
+++ linux/include/net/gc.h	Mon Mar 25 08:58:22 1996
@@ -0,0 +1,46 @@
+/*
+ *	Interface routines assumed by gc()
+ *
+ *	Copyright (C) Barak A. Pearlmutter.
+ *	Released under the GPL version 2 or later.
+ *
+ */
+
+typedef struct object *pobj;	/* pointer to a guy of the type we gc */
+
+/*
+ *	How to mark and unmark objects
+ */
+
+extern void gc_mark(pobj);
+extern void gc_unmark(pobj);
+extern int gc_marked(pobj);
+
+/* 
+ *	How to count and access an object's children
+ */
+
+extern int n_children(pobj);	/* how many children */
+extern pobj child_n(pobj, int);	/* child i, numbered 0..n-1 */
+
+/*
+ *	How to access the root set
+ */
+
+extern int root_size(void);	/* number of things in root set */
+extern pobj root_elt(int);	/* element i of root set, numbered 0..n-1 */
+
+/*
+ *	How to access the free list
+ */
+
+extern void clear_freelist(void);
+extern void add_to_free_list(pobj);
+
+/*
+ *	How to iterate through all objects in memory
+ */
+
+extern int N_OBJS;
+extern pobj obj_number(int);
+
diff -u --recursive --new-file v1.3.77/linux/include/net/ipx.h linux/include/net/ipx.h
--- v1.3.77/linux/include/net/ipx.h	Wed Feb  7 15:11:39 1996
+++ linux/include/net/ipx.h	Mon Mar 25 10:24:40 1996
@@ -11,6 +11,7 @@
 #ifndef _NET_INET_IPX_H_
 #define _NET_INET_IPX_H_
 
+#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/datalink.h>
 #include <linux/ipx.h>
diff -u --recursive --new-file v1.3.77/linux/include/net/p8022.h linux/include/net/p8022.h
--- v1.3.77/linux/include/net/p8022.h	Tue Jun  6 11:22:17 1995
+++ linux/include/net/p8022.h	Mon Mar 25 08:58:22 1996
@@ -1,2 +1,7 @@
-struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_P8022_H
+#define _NET_P8022_H
 
+extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_8022_client(unsigned char type);
+
+#endif
diff -u --recursive --new-file v1.3.77/linux/include/net/psnap.h linux/include/net/psnap.h
--- v1.3.77/linux/include/net/psnap.h	Tue Jun  6 11:22:18 1995
+++ linux/include/net/psnap.h	Mon Mar 25 08:58:22 1996
@@ -1,2 +1,7 @@
-struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_PSNAP_H
+#define _NET_PSNAP_H
 
+extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_snap_client(unsigned char *desc);
+
+#endif
diff -u --recursive --new-file v1.3.77/linux/include/net/sock.h linux/include/net/sock.h
--- v1.3.77/linux/include/net/sock.h	Thu Mar 21 20:36:54 1996
+++ linux/include/net/sock.h	Mon Mar 25 10:24:40 1996
@@ -46,10 +46,12 @@
 #include <net/netrom.h>
 #endif
 #endif
-#ifdef CONFIG_IPX
+
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 #include <net/ipx.h>
 #endif
-#ifdef CONFIG_ATALK
+
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
 #include <linux/atalk.h>
 #endif
 
@@ -73,6 +75,9 @@
 	struct inode *		inode;
 	struct semaphore	readsem;
 	struct sock *		other;
+	int 			marksweep;
+#define MARKED			1
+	int			inflight;
 };
 
 /*
@@ -92,7 +97,7 @@
  *	Once the IPX ncpd patches are in these are going into protinfo
  */
 
-#ifdef CONFIG_IPX 
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 struct ipx_opt
 {
 	ipx_address		dest_addr;
@@ -261,12 +266,12 @@
 	union
 	{
 	  	struct unix_opt	af_unix;
-#ifdef CONFIG_ATALK
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
 		struct atalk_sock	af_at;
 #endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 		struct ipx_opt		af_ipx;
-#endif		
+#endif
 #ifdef CONFIG_INET
 		struct inet_packet_opt  af_packet;
 #ifdef CONFIG_NUTCP		
diff -u --recursive --new-file v1.3.77/linux/init/main.c linux/init/main.c
--- v1.3.77/linux/init/main.c	Sun Mar 17 09:04:08 1996
+++ linux/init/main.c	Mon Mar 25 08:58:23 1996
@@ -586,32 +586,29 @@
  
 static void smp_init(void)
 {
-	int i=0;
+	int i, j;
 	smp_boot_cpus();
 	
 	/*
 	 *	Create the slave init tasks as sharing pid 0.
+	 *
+	 *	This should only happen if we have virtual CPU numbers
+	 *	higher than 0.
 	 */
 
-	for (i=0; i<NR_CPUS; i++)
+	for (i=1; i<smp_num_cpus; i++)
 	{
+		j = cpu_logical_map[i];
 		/*
-		 *	This should only do anything if the mapping
-		 *	corresponds to a live CPU which is not the boot CPU.
+		 *	We use kernel_thread for the idlers which are
+		 *	unlocked tasks running in kernel space.
 		 */
-		if (cpu_number_map[i] > 0)
-		{
-			/*
-			 *	We use kernel_thread for the idlers which are
-			 *	unlocked tasks running in kernel space.
-			 */
-			kernel_thread(cpu_idle, NULL, CLONE_PID);
-			/*
-			 *	Don't assume linear processor numbering
-			 */
-			current_set[i]=task[cpu_number_map[i]];
-			current_set[i]->processor=i;
-		}
+		kernel_thread(cpu_idle, NULL, CLONE_PID);
+		/*
+		 *	Don't assume linear processor numbering
+		 */
+		current_set[j]=task[i];
+		current_set[j]->processor=j;
 	}
 }		
 
diff -u --recursive --new-file v1.3.77/linux/kernel/exit.c linux/kernel/exit.c
--- v1.3.77/linux/kernel/exit.c	Wed Mar 13 10:09:24 1996
+++ linux/kernel/exit.c	Sat Mar 23 14:31:02 1996
@@ -49,7 +49,9 @@
 	if (!p || sig > 32)
 		return -EINVAL;
 	if (!priv && ((sig != SIGCONT) || (current->session != p->session)) &&
-	    (current->euid != p->euid) && (current->euid != p->uid) && !suser())
+	    (current->euid ^ p->euid) && (current->euid ^ p->uid) &&
+	    (current->uid ^ p->euid) && (current->uid ^ p->uid) &&
+	    !suser())
 		return -EPERM;
 	if (!sig)
 		return 0;
diff -u --recursive --new-file v1.3.77/linux/kernel/fork.c linux/kernel/fork.c
--- v1.3.77/linux/kernel/fork.c	Thu Mar 21 20:36:54 1996
+++ linux/kernel/fork.c	Sun Mar 24 20:07:01 1996
@@ -227,7 +227,7 @@
 	p->kernel_stack_page = new_stack;
 	*(unsigned long *) p->kernel_stack_page = STACK_MAGIC;
 	p->state = TASK_UNINTERRUPTIBLE;
-	p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPREV);
+	p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPRIV);
 	p->flags |= PF_FORKNOEXEC;
 	p->pid = get_pid(clone_flags);
 	p->next_run = NULL;
diff -u --recursive --new-file v1.3.77/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.77/linux/kernel/ksyms.c	Wed Mar 20 11:00:00 1996
+++ linux/kernel/ksyms.c	Mon Mar 25 08:58:23 1996
@@ -48,32 +48,6 @@
 
 extern unsigned char aux_device_present, kbd_read_mask;
 
-#ifdef CONFIG_NET
-#include <linux/in.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/firewall.h>
-#include <linux/trdevice.h>
-
-#ifdef CONFIG_AX25
-#include <net/ax25.h>
-#endif
-#ifdef CONFIG_INET
-#include <linux/ip.h>
-#include <linux/etherdevice.h>
-#include <net/protocol.h>
-#include <net/arp.h>
-#include <net/ip.h>
-#include <net/udp.h>
-#include <net/tcp.h>
-#include <net/icmp.h>
-#include <net/route.h>
-#include <linux/net_alias.h>
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
 #ifdef CONFIG_PCI
 #include <linux/bios32.h>
 #include <linux/pci.h>
@@ -96,17 +70,9 @@
 
 extern void *sys_call_table;
 
-#if	defined(CONFIG_ULTRA)	||	defined(CONFIG_WD80x3)		|| \
-	defined(CONFIG_EL2)	||	defined(CONFIG_NE2000)		|| \
-	defined(CONFIG_E2100)	||	defined(CONFIG_HPLAN_PLUS)	|| \
-	defined(CONFIG_HPLAN)	||	defined(CONFIG_AC3200)
-#include "../drivers/net/8390.h"
-#endif
-
 extern int sys_tz;
 extern int request_dma(unsigned int dmanr, char * deviceID);
 extern void free_dma(unsigned int dmanr);
-extern int (*rarp_ioctl_hook)(int,void*);
 
 struct symbol_table symbol_table = {
 #include <linux/symtab_begin.h>
@@ -251,6 +217,7 @@
 	X(unregister_binfmt),
 	X(search_binary_handler),
 	X(prepare_binprm),
+	X(remove_arg_zero),
 
 	/* execution environment registration */
 	X(lookup_exec_domain),
@@ -339,94 +306,7 @@
 
 	/* Miscellaneous access points */
 	X(si_meminfo),
-#ifdef CONFIG_NET
-	/* Socket layer registration */
-	X(sock_register),
-	X(sock_unregister),
-	/* Socket layer support routines */
-	X(skb_recv_datagram),
-	X(skb_free_datagram),
-	X(skb_copy_datagram),
-	X(skb_copy_datagram_iovec),
-	X(datagram_select),
-#ifdef CONFIG_FIREWALL
-	/* Firewall registration */
-	X(register_firewall),
-	X(unregister_firewall),
-#endif
-#ifdef CONFIG_INET	
-	/* Internet layer registration */
-	X(inet_add_protocol),
-	X(inet_del_protocol),
-	X(rarp_ioctl_hook),
-	X(init_etherdev),
-	X(ip_rt_route),
-	X(icmp_send),
-	X(ip_options_compile),
-	X(ip_rt_put),
-	X(arp_send),
-#ifdef CONFIG_IP_FORWARD
-	X(ip_forward),
-#endif
-#if	defined(CONFIG_ULTRA)	||	defined(CONFIG_WD80x3)		|| \
-	defined(CONFIG_EL2)	||	defined(CONFIG_NE2000)		|| \
-	defined(CONFIG_E2100)	||	defined(CONFIG_HPLAN_PLUS)	|| \
-	defined(CONFIG_HPLAN)	||	defined(CONFIG_AC3200)
-	/* If 8390 NIC support is built in, we will need these. */
-	X(ei_open),
-	X(ei_close),
-	X(ei_debug),
-	X(ei_interrupt),
-	X(ethdev_init),
-	X(NS8390_init),
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
-	/* Device callback registration */
-	X(register_netdevice_notifier),
-	X(unregister_netdevice_notifier),
-#ifdef CONFIG_NET_ALIAS
-	X(register_net_alias_type),
-	X(unregister_net_alias_type),
-#endif
-#endif
-
-	/* support for loadable net drivers */
-#ifdef CONFIG_AX25
-	X(ax25_encapsulate),
-	X(ax25_rebuild_header),	
-#endif	
-#ifdef CONFIG_INET
-	X(register_netdev),
-	X(unregister_netdev),
-	X(ether_setup),
-	X(eth_type_trans),
-	X(eth_copy_and_sum),
-	X(alloc_skb),
-	X(kfree_skb),
-	X(skb_clone),
-	X(dev_alloc_skb),
-	X(dev_kfree_skb),
-	X(netif_rx),
-	X(dev_tint),
-	X(irq2dev_map),
-	X(dev_add_pack),
-	X(dev_remove_pack),
-	X(dev_get),
-	X(dev_ioctl),
-	X(dev_queue_xmit),
-	X(dev_base),
-	X(dev_close),
-	X(arp_find),
-	X(n_tty_ioctl),
-	X(tty_register_ldisc),
-	X(kill_fasync),
-#ifdef CONFIG_FIREWALL
-	X(call_in_firewall),
-#endif
-#endif
+
 #ifndef CONFIG_SCSI
 	/*
 	 * With no scsi configured, we still need to export a few
diff -u --recursive --new-file v1.3.77/linux/kernel/module.c linux/kernel/module.c
--- v1.3.77/linux/kernel/module.c	Wed Mar 20 11:00:00 1996
+++ linux/kernel/module.c	Sun Mar 24 20:07:01 1996
@@ -38,7 +38,7 @@
  *
  * On 1-Aug-95:  <Matti.Aarnio@utu.fi>  altered code to use same style as
  *		 do  /proc/net/XXX  "files".  Namely allow more than 4kB
- *		 (or what the block size if) output.
+ *		 (or what the block size is) output.
  *
  *	- Use dummy syscall functions for users who disable all
  *	  module support. Similar to kernel/sys.c (Paul Gortmaker)
diff -u --recursive --new-file v1.3.77/linux/kernel/sched.c linux/kernel/sched.c
--- v1.3.77/linux/kernel/sched.c	Thu Mar 21 20:36:54 1996
+++ linux/kernel/sched.c	Mon Mar 25 08:58:23 1996
@@ -7,7 +7,7 @@
 /*
  * 'sched.c' is the main kernel file. It contains scheduling primitives
  * (sleep_on, wakeup, schedule etc) as well as a number of simple system
- * call functions (type getpid(), which just extracts a field from
+ * call functions (type getpid()), which just extract a field from
  * current-task
  */
 
@@ -136,13 +136,11 @@
 	if ((0!=p->pid) && smp_threads_ready)
 	{
 		int i;
-		for (i=0;i<=smp_top_cpu;i++)
+		for (i=0;i<smp_num_cpus;i++)
 		{
-			if (cpu_number_map[i]==-1)
-				continue;
-			if (0==current_set[i]->pid) 
+			if (0==current_set[cpu_logical_map[i]]->pid) 
 			{
-				smp_message_pass(i, MSG_RESCHEDULE, 0L, 0);
+				smp_message_pass(cpu_logical_map[i], MSG_RESCHEDULE, 0L, 0);
 				break;
 			}
 		}
@@ -929,14 +927,13 @@
 		update_one_process(p, ticks, ticks-system, system);
 	}
 #else
-	int cpu,i;
+	int cpu,j;
 	cpu = smp_processor_id();
-	for (i=0;i<=smp_top_cpu;i++)
+	for (j=0;j<smp_num_cpus;j++)
 	{
+		int i = cpu_logical_map[j];
 		struct task_struct *p;
 		
-		if(cpu_number_map[i]==-1)
-			continue;
 #ifdef __SMP_PROF__
 		if (test_bit(i,&smp_idle_map)) 
 			smp_idle_count[i]++;
diff -u --recursive --new-file v1.3.77/linux/kernel/sys.c linux/kernel/sys.c
--- v1.3.77/linux/kernel/sys.c	Fri Mar 15 16:03:21 1996
+++ linux/kernel/sys.c	Sun Mar 24 20:07:01 1996
@@ -22,7 +22,6 @@
 #include <linux/fcntl.h>
 #include <linux/acct.h>
 #include <linux/tty.h>
-#include <sys/sysmacros.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -297,12 +296,12 @@
       ac.ac_etime = CURRENT_TIME - ac.ac_btime;
       ac.ac_uid   = current->uid;
       ac.ac_gid   = current->gid;
-      ac.ac_tty   = (current)->tty == NULL ? -1 : 
-         makedev (4, current->tty->device);
+      ac.ac_tty   = (current)->tty == NULL ? -1 :
+	  MKDEV(4, current->tty->device);
       ac.ac_flag  = 0;
       if (current->flags & PF_FORKNOEXEC)
          ac.ac_flag |= AFORK;
-      if (current->flags & PF_SUPERPREV)
+      if (current->flags & PF_SUPERPRIV)
          ac.ac_flag |= ASU;
       if (current->flags & PF_DUMPCORE)
          ac.ac_flag |= ACORE;
diff -u --recursive --new-file v1.3.77/linux/mm/Makefile linux/mm/Makefile
--- v1.3.77/linux/mm/Makefile	Sun Jan 14 16:30:16 1996
+++ linux/mm/Makefile	Fri Mar 22 12:56:56 1996
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS	 := memory.o mmap.o filemap.o mprotect.o mlock.o \
+O_OBJS	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
 	    kmalloc.o vmalloc.o \
 	    swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
 
diff -u --recursive --new-file v1.3.77/linux/mm/memory.c linux/mm/memory.c
--- v1.3.77/linux/mm/memory.c	Fri Mar 15 16:03:21 1996
+++ linux/mm/memory.c	Fri Mar 22 14:05:44 1996
@@ -734,16 +734,23 @@
 	return -EFAULT;
 }
 
-static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma, pte_t * page_table)
+static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma,
+	pte_t * page_table, int write_access)
 {
-	unsigned long tmp;
+	pte_t pte;
 
-	if (!(tmp = get_free_page(GFP_KERNEL))) {
-		oom(tsk);
-		put_page(page_table, BAD_PAGE);
-		return;
+	pte = pte_wrprotect(mk_pte(ZERO_PAGE, vma->vm_page_prot));
+	if (write_access) {
+		unsigned long page = get_free_page(GFP_KERNEL);
+		pte = pte_mkwrite(mk_pte(page, vma->vm_page_prot));
+		vma->vm_mm->rss++;
+		tsk->min_flt++;
+		if (!page) {
+			oom(tsk);
+			pte = BAD_PAGE;
+		}
 	}
-	put_page(page_table, pte_mkwrite(mk_pte(tmp, vma->vm_page_prot)));
+	put_page(page_table, pte);
 }
 
 /*
@@ -894,9 +901,7 @@
 	}
 	address &= PAGE_MASK;
 	if (!vma->vm_ops || !vma->vm_ops->nopage) {
-		++vma->vm_mm->rss;
-		++tsk->min_flt;
-		get_empty_page(tsk, vma, page_table);
+		get_empty_page(tsk, vma, page_table, write_access);
 		return;
 	}
 	++tsk->maj_flt;
diff -u --recursive --new-file v1.3.77/linux/mm/mmap.c linux/mm/mmap.c
--- v1.3.77/linux/mm/mmap.c	Wed Feb 28 11:50:15 1996
+++ linux/mm/mmap.c	Fri Mar 22 14:07:14 1996
@@ -18,17 +18,6 @@
 #include <asm/pgtable.h>
 
 /*
- * Map memory not associated with any file into a process
- * address space.  Adjacent memory is merged.
- */
-static inline int anon_map(struct inode *ino, struct file * file, struct vm_area_struct * vma)
-{
-	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
-		return -ENOMEM;
-	return 0;
-}
-
-/*
  * description of effects of mapping type and prot in current implementation.
  * this is due to the limited x86 page protection hardware.  The expected
  * behavior is in parens:
@@ -53,7 +42,6 @@
 unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long off)
 {
-	int error;
 	struct vm_area_struct * vma;
 
 	if ((len = PAGE_ALIGN(len)) == 0)
@@ -165,15 +153,15 @@
 
 	do_munmap(addr, len);	/* Clear old maps */
 
-	if (file)
-		error = file->f_op->mmap(file->f_inode, file, vma);
-	else
-		error = anon_map(NULL, NULL, vma);
+	if (file) {
+		int error = file->f_op->mmap(file->f_inode, file, vma);
 	
-	if (error) {
-		kfree(vma);
-		return error;
+		if (error) {
+			kfree(vma);
+			return error;
+		}
 	}
+
 	flags = vma->vm_flags;
 	insert_vm_struct(current, vma);
 	merge_segments(current, vma->vm_start, vma->vm_end);
diff -u --recursive --new-file v1.3.77/linux/mm/mremap.c linux/mm/mremap.c
--- v1.3.77/linux/mm/mremap.c	Thu Jan  1 02:00:00 1970
+++ linux/mm/mremap.c	Sat Mar 23 19:25:55 1996
@@ -0,0 +1,219 @@
+/*
+ *	linux/mm/remap.c
+ *
+ *	(C) Copyright 1996 Linus Torvalds
+ */
+
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/swap.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr)
+{
+	pgd_t * pgd;
+	pmd_t * pmd;
+	pte_t * pte = NULL;
+
+	pgd = pgd_offset(mm, addr);
+	if (pgd_none(*pgd))
+		goto end;
+	if (pgd_bad(*pgd)) {
+		printk("move_one_page: bad source pgd (%08lx)\n", pgd_val(*pgd));
+		pgd_clear(pgd);
+		goto end;
+	}
+
+	pmd = pmd_offset(pgd, addr);
+	if (pmd_none(*pmd))
+		goto end;
+	if (pmd_bad(*pmd)) {
+		printk("move_one_page: bad source pmd (%08lx)\n", pmd_val(*pmd));
+		pmd_clear(pmd);
+		goto end;
+	}
+
+	pte = pte_offset(pmd, addr);
+	if (pte_none(*pte))
+		pte = NULL;
+end:
+	return pte;
+}
+
+static inline pte_t *alloc_one_pte(struct mm_struct *mm, unsigned long addr)
+{
+	pmd_t * pmd;
+	pte_t * pte = NULL;
+
+	pmd = pmd_alloc(pgd_offset(mm, addr), addr);
+	if (pmd)
+		pte = pte_alloc(pmd, addr);
+	return pte;
+}
+
+static inline int copy_one_pte(pte_t * src, pte_t * dst)
+{
+	int error = 0;
+	pte_t pte = *src;
+
+	if (!pte_none(pte)) {
+		error++;
+		if (dst) {
+			pte_clear(src);
+			set_pte(dst, pte);
+			error--;
+		}
+	}
+	return error;
+}
+
+static int move_one_page(struct mm_struct *mm, unsigned long old_addr, unsigned long new_addr)
+{
+	int error = 0;
+	pte_t * src;
+
+	src = get_one_pte(mm, old_addr);
+	if (src)
+		error = copy_one_pte(src, alloc_one_pte(mm, new_addr));
+	return error;
+}
+
+static int move_page_tables(struct mm_struct * mm,
+	unsigned long new_addr, unsigned long old_addr, unsigned long len)
+{
+	unsigned long offset = len;
+
+	invalidate_range(mm, old_addr, old_addr + len);
+
+	/*
+	 * This is not the clever way to do this, but we're taking the
+	 * easy way out on the assumption that most remappings will be
+	 * only a few pages.. This also makes error recovery easier.
+	 */
+	while (offset) {
+		offset -= PAGE_SIZE;
+		if (move_one_page(mm, old_addr + offset, new_addr + offset))
+			goto oops_we_failed;
+	}
+	return 0;
+
+	/*
+	 * Ok, the move failed because we didn't have enough pages for
+	 * the new page table tree. This is unlikely, but we have to
+	 * take the possibility into account. In that case we just move
+	 * all the pages back (this will work, because we still have
+	 * the old page tables)
+	 */
+oops_we_failed:
+	while ((offset += PAGE_SIZE) < len)
+		move_one_page(mm, new_addr + offset, old_addr + offset);
+	invalidate_range(mm, new_addr, new_addr + len);
+	zap_page_range(mm, new_addr, new_addr + len);
+	return -1;
+}
+
+static inline unsigned long move_vma(struct vm_area_struct * vma,
+	unsigned long addr, unsigned long old_len, unsigned long new_len)
+{
+	struct vm_area_struct * new_vma;
+
+	new_vma = (struct vm_area_struct *)
+		kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (new_vma) {
+		unsigned long new_addr = get_unmapped_area(addr, new_len);
+
+		if (new_addr && !move_page_tables(current->mm, new_addr, addr, old_len)) {
+			*new_vma = *vma;
+			new_vma->vm_start = new_addr;
+			new_vma->vm_end = new_addr+new_len;
+			new_vma->vm_offset = vma->vm_offset + (addr - vma->vm_start);
+			if (new_vma->vm_inode)
+				new_vma->vm_inode->i_count++;
+			if (new_vma->vm_ops && new_vma->vm_ops->open)
+				new_vma->vm_ops->open(new_vma);
+			insert_vm_struct(current, new_vma);
+			merge_segments(current, new_vma->vm_start, new_vma->vm_end);
+			do_munmap(addr, old_len);
+			return new_addr;
+		}
+		kfree(new_vma);
+	}
+	return -ENOMEM;
+}
+
+/*
+ * Expand (or shrink) an existing mapping, potentially moving it at the
+ * same time (controlled by the "may_move" flag and available VM space)
+ */
+asmlinkage unsigned long sys_mremap(unsigned long addr,
+	unsigned long old_len, unsigned long new_len,
+	int may_move)
+{
+	struct vm_area_struct *vma;
+
+	if (addr & ~PAGE_MASK)
+		return -EINVAL;
+	old_len = PAGE_ALIGN(old_len);
+	new_len = PAGE_ALIGN(new_len);
+	if (old_len == new_len)
+		return addr;
+
+	/*
+	 * Always allow a shrinking remap: that just unmaps
+	 * the unnecessary pages..
+	 */
+	if (old_len > new_len) {
+		do_munmap(addr+new_len, old_len - new_len);
+		return addr;
+	}
+
+	/*
+	 * Ok, we need to grow..
+	 */
+	vma = find_vma(current, addr);
+	if (!vma || vma->vm_start > addr)
+		return -EFAULT;
+	/* We can't remap across vm area boundaries */
+	if (old_len > vma->vm_end - addr)
+		return -EFAULT;
+	if (vma->vm_flags & VM_LOCKED) {
+		unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+		locked += new_len - old_len;
+		if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+			return -EAGAIN;
+	}
+
+	/* old_len exactly to the end of the area.. */
+	if (old_len == vma->vm_end - addr) {
+		unsigned long max_addr = TASK_SIZE;
+		if (vma->vm_next)
+			max_addr = vma->vm_next->vm_start;
+		/* can we just expand the current mapping? */
+		if (max_addr - addr >= new_len) {
+			int pages = (new_len - old_len) >> PAGE_SHIFT;
+			vma->vm_end = addr + new_len;
+			current->mm->total_vm += pages;
+			if (vma->vm_flags & VM_LOCKED)
+				current->mm->locked_vm += pages;
+			return addr;
+		}
+	}
+
+	/*
+	 * We weren't able to just expand or shrink the area,
+	 * we need to create a new one and move it..
+	 */
+	if (!may_move)
+		return -ENOMEM;
+	return move_vma(vma, addr, old_len, new_len);
+}
diff -u --recursive --new-file v1.3.77/linux/net/802/Makefile linux/net/802/Makefile
--- v1.3.77/linux/net/802/Makefile	Tue Aug 15 20:39:05 1995
+++ linux/net/802/Makefile	Mon Mar 25 08:58:23 1996
@@ -15,12 +15,12 @@
 endif
 
 ifdef CONFIG_IPX
-O_OBJS += p8022.o psnap.o
+OX_OBJS += p8022.o psnap.o
 endif
 
 ifdef CONFIG_ATALK
 ifndef CONFIG_IPX
-O_OBJS += p8022.o psnap.o
+OX_OBJS += p8022.o psnap.o
 endif
 endif
 
diff -u --recursive --new-file v1.3.77/linux/net/802/p8022.c linux/net/802/p8022.c
--- v1.3.77/linux/net/802/p8022.c	Sat Nov 25 19:04:57 1995
+++ linux/net/802/p8022.c	Mon Mar 25 08:58:23 1996
@@ -1,8 +1,10 @@
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/datalink.h>
 #include <linux/mm.h>
 #include <linux/in.h>
+#include <net/p8022.h>
 
 static struct datalink_proto *p8022_list = NULL;
 
@@ -65,12 +67,20 @@
 	NULL,
 	NULL,
 };
+
+static struct symbol_table p8022_proto_syms = {
+#include <linux/symtab_begin.h>
+	X(register_8022_client),
+	X(unregister_8022_client),
+#include <linux/symtab_end.h>
+};
  
 
 void p8022_proto_init(struct net_proto *pro)
 {
 	p8022_packet_type.type=htons(ETH_P_802_2);
 	dev_add_pack(&p8022_packet_type);
+	register_symtab(&p8022_proto_syms);
 }
 	
 struct datalink_proto *
@@ -96,3 +106,24 @@
 	return proto;
 }
 
+void unregister_8022_client(unsigned char type)
+{
+	struct datalink_proto *tmp, **clients = &p8022_list;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	while ((tmp = *clients) != NULL)
+	{
+		if (tmp->type[0] == type) {
+			*clients = tmp->next;
+			kfree_s(tmp, sizeof(struct datalink_proto));
+			break;
+		} else {
+			clients = &tmp->next;
+		}
+	}
+
+	restore_flags(flags);
+}
diff -u --recursive --new-file v1.3.77/linux/net/802/p8023.c linux/net/802/p8023.c
--- v1.3.77/linux/net/802/p8023.c	Mon Jul 31 15:59:03 1995
+++ linux/net/802/p8023.c	Mon Mar 25 08:58:23 1996
@@ -29,3 +29,9 @@
 	return proto;
 }
 
+void destroy_8023_client(struct datalink_proto *dl)
+{
+	if (dl)
+		kfree_s(dl,sizeof(struct datalink_proto));
+}
+
diff -u --recursive --new-file v1.3.77/linux/net/802/psnap.c linux/net/802/psnap.c
--- v1.3.77/linux/net/802/psnap.c	Mon Jul 31 15:59:03 1995
+++ linux/net/802/psnap.c	Mon Mar 25 08:58:23 1996
@@ -10,6 +10,7 @@
  *		2 of the License, or (at your option) any later version.
  */
  
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/datalink.h>
@@ -81,12 +82,20 @@
 /*
  *	Set up the SNAP layer
  */
+
+static struct symbol_table snap_proto_syms = {
+#include <linux/symtab_begin.h>
+	X(register_snap_client),
+	X(unregister_snap_client),
+#include <linux/symtab_end.h>
+};
  
 void snap_proto_init(struct net_proto *pro)
 {
 	snap_dl=register_8022_client(0xAA, snap_rcv);
 	if(snap_dl==NULL)
 		printk("SNAP - unable to register with 802.2\n");
+	register_symtab(&snap_proto_syms);
 }
 	
 /*
@@ -114,5 +123,33 @@
 	}
 
 	return proto;
+}
+
+/*
+ *	Unregister SNAP clients. Protocols no longer want to play with us ...
+ */
+
+void unregister_snap_client(unsigned char *desc)
+{
+	struct datalink_proto **clients = &snap_list;
+	struct datalink_proto *tmp;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	while ((tmp = *clients) != NULL)
+	{
+		if (memcmp(tmp->type,desc,5) == 0)
+		{
+			*clients = tmp->next;
+			kfree_s(tmp, sizeof(struct datalink_proto));
+			break;
+		}
+		else
+			clients = &tmp->next;
+	}
+
+	restore_flags(flags);
 }
 
diff -u --recursive --new-file v1.3.77/linux/net/Config.in linux/net/Config.in
--- v1.3.77/linux/net/Config.in	Wed Feb  7 15:11:40 1996
+++ linux/net/Config.in	Mon Mar 25 08:58:23 1996
@@ -10,11 +10,11 @@
   source net/ipv4/Config.in
 fi
 comment ' '
-bool 'The IPX protocol' CONFIG_IPX
-if [ "$CONFIG_IPX" = "y" ]; then
+tristate 'The IPX protocol' CONFIG_IPX
+if [ ! "$CONFIG_IPX" = "n" ]; then
   bool 'Full internal IPX network' CONFIG_IPX_INTERN
 fi
-bool 'Appletalk DDP' CONFIG_ATALK
+tristate 'Appletalk DDP' CONFIG_ATALK
 bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25
 if [ "$CONFIG_AX25" = "y" ]; then
   bool 'AX.25 over Ethernet' CONFIG_BPQETHER
diff -u --recursive --new-file v1.3.77/linux/net/Makefile linux/net/Makefile
--- v1.3.77/linux/net/Makefile	Thu Nov  9 11:23:56 1995
+++ linux/net/Makefile	Mon Mar 25 08:58:23 1996
@@ -10,6 +10,7 @@
 MOD_SUB_DIRS := ipv4
 ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom
 SUB_DIRS     := 802 core ethernet unix
+MOD_LIST_NAME := NET_MISC_MODULES
 
 ifeq ($(CONFIG_INET),y)
 SUB_DIRS += ipv4
@@ -17,10 +18,18 @@
 
 ifeq ($(CONFIG_IPX),y)
 SUB_DIRS += ipx
+else
+  ifeq ($(CONFIG_IPX),m)
+  MOD_SUB_DIRS += ipx
+  endif
 endif
 
 ifeq ($(CONFIG_ATALK),y)
 SUB_DIRS += appletalk
+else
+  ifeq ($(CONFIG_ATALK),m)
+  MOD_SUB_DIRS += appletalk
+  endif
 endif
 
 ifeq ($(CONFIG_NETROM),y)
@@ -33,6 +42,10 @@
 
 L_TARGET     := network.a
 L_OBJS	     := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
+ifeq ($(CONFIG_MODULES),y)
+LX_OBJS = netsyms.o
+endif
+
 M_OBJS	     :=
 
 ifeq ($(CONFIG_NETLINK),y)
diff -u --recursive --new-file v1.3.77/linux/net/appletalk/Makefile linux/net/appletalk/Makefile
--- v1.3.77/linux/net/appletalk/Makefile	Tue Aug 15 20:39:05 1995
+++ linux/net/appletalk/Makefile	Mon Mar 25 08:58:23 1996
@@ -9,6 +9,7 @@
 
 O_TARGET := appletalk.o
 O_OBJS	 := aarp.o ddp.o
+M_OBJS   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
 
diff -u --recursive --new-file v1.3.77/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c
--- v1.3.77/linux/net/appletalk/aarp.c	Wed Mar 13 10:09:25 1996
+++ linux/net/appletalk/aarp.c	Mon Mar 25 09:00:04 1996
@@ -26,7 +26,6 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -38,18 +37,17 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
-#include <linux/if_arp.h>
 #include <linux/inet.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <linux/atalk.h>
 
-#ifdef CONFIG_ATALK
 /*
  *	Lists of aarp entries
  */
@@ -790,10 +788,11 @@
 	0
 };
 
+static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
+
 
 void aarp_proto_init(void)
 {
-	static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
 	if((aarp_dl=register_snap_client(aarp_snap_id, aarp_rcv))==NULL)
 		printk("Unable to register AARP with SNAP.\n");
 	init_timer(&aarp_timer);
@@ -803,4 +802,43 @@
 	add_timer(&aarp_timer);
 	register_netdevice_notifier(&aarp_notifier);
 }
-#endif
+
+
+#ifdef MODULE
+
+/* Free all the entries in an aarp list. Caller should turn off interrupts. */
+static void free_entry_list(struct aarp_entry *list)
+{
+	struct aarp_entry *tmp;
+
+	while (list != NULL)
+	{
+		tmp = list->next;
+		aarp_expire(list);
+		list = tmp;
+	}
+}
+
+/* General module cleanup. Called from cleanup_module() in ddp.c. */
+void aarp_cleanup_module(void)
+{
+	unsigned long flags;
+	int i;
+
+	save_flags(flags);
+	cli();
+
+	del_timer(&aarp_timer);
+	unregister_netdevice_notifier(&aarp_notifier);
+	unregister_snap_client(aarp_snap_id);
+
+	for (i = 0; i < AARP_HASH_SIZE; i++)
+	{
+		free_entry_list(resolved[i]);
+		free_entry_list(unresolved[i]);
+	}
+
+	restore_flags(flags);
+}
+
+#endif  /* MODULE */
diff -u --recursive --new-file v1.3.77/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v1.3.77/linux/net/appletalk/ddp.c	Thu Mar 21 20:36:54 1996
+++ linux/net/appletalk/ddp.c	Mon Mar 25 09:00:04 1996
@@ -20,6 +20,9 @@
  *		Alan Cox		:	Supports new ARPHRD_LOOPBACK
  *		Christer Weinigel	: 	Routing and /proc fixes.
  *		Bradford Johnson	:	Locatalk.
+ *		Tom Dyas		:	Module support.
+ *		Alan Cox		:	Hooks for PPP (based on the
+ *						localtalk hook).
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -30,10 +33,11 @@
  *		ASYNC I/O
  */
  
+#include <linux/config.h>
+#include <linux/module.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -45,12 +49,12 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
-#include <linux/if_arp.h>
 #include <linux/route.h>
 #include <linux/inet.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <linux/termios.h>	/* For TIOCOUTQ/INQ */
 #include <net/datalink.h>
@@ -62,7 +66,6 @@
 #include <linux/stat.h>
 #include <linux/firewall.h>
 
-#ifdef CONFIG_ATALK
 
 #undef APPLETALK_DEBUG
 
@@ -214,7 +217,10 @@
 	}
 	
 	if(sk->wmem_alloc == 0 && sk->rmem_alloc == 0 && sk->dead)
+	{
 		kfree_s(sk,sizeof(*sk));
+		MOD_DEC_USE_COUNT;
+	}
 	else
 	{
 		/*
@@ -256,7 +262,7 @@
 			ntohs(s->protinfo.af_at.dest_net),
 			s->protinfo.af_at.dest_node,
 			s->protinfo.af_at.dest_port);
-		len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc);
+		len += sprintf (buffer+len,"%08X:%08X ", s->wmem_alloc, s->rmem_alloc);
 		len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
 		
 		/* Are we still dumping unwanted data then discard the record */
@@ -359,8 +365,8 @@
  *	now for the 1.4 release as is.
  *
  */
-	if(atif->dev->type == ARPHRD_LOCALTLK &&
-		atif->dev->do_ioctl) 
+	if((atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP)
+		&& atif->dev->do_ioctl) 
 	{
 		/* fake up the request and pass it down */
 		sa = (struct sockaddr_at*)&atreq.ifr_addr;
@@ -753,7 +759,7 @@
 			if(sa->sat_family!=AF_APPLETALK)
 				return -EINVAL;
 			if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK
-				&&dev->type!=ARPHRD_LOCALTLK)
+				&&dev->type!=ARPHRD_LOCALTLK && dev->type!=ARPHRD_PPP)
 				return -EPROTONOSUPPORT;
 			nr=(struct netrange *)&sa->sat_zero[0];
 			/*
@@ -1133,6 +1139,9 @@
 			kfree_s((void *)sk,sizeof(*sk));
 			return(-ESOCKTNOSUPPORT);
 	}
+
+	MOD_INC_USE_COUNT;
+
 	sk->dead=0;
 	sk->next=NULL;
 	sk->broadcast=0;
@@ -1400,7 +1409,8 @@
 /*
  *	Receive a packet (in skb) from device dev. This has come from the SNAP decoder, and on entry
  *	skb->h.raw is the DDP header, skb->len is the DDP length. The physical headers have been 
- *	extracted.
+ *	extracted. PPP should probably pass frames marked as for this layer
+ *	[ie ARPHRD_ETHERTALK]
  */
  
 static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
@@ -2005,11 +2015,22 @@
 	NULL
 };
 
+struct packet_type ppptalk_packet_type=
+{
+	0,
+	NULL,
+	atalk_rcv,
+	NULL,
+	NULL
+};
+
+static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
+
+
 /* Called by proto.c on kernel start up */
 
 void atalk_proto_init(struct net_proto *pro)
 {
-	static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
 	(void) sock_register(atalk_proto_ops.family, &atalk_proto_ops);
 	if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL)
 		printk("Unable to register DDP with SNAP.\n");
@@ -2017,6 +2038,9 @@
 	ltalk_packet_type.type=htons(ETH_P_LOCALTALK);	
 	dev_add_pack(&ltalk_packet_type);
 	
+	ppptalk_packet_type.type=htons(ETH_P_PPPTALK);
+	dev_add_pack(&ppptalk_packet_type);
+	
 	register_netdevice_notifier(&ddp_notifier);
 	aarp_proto_init();
 
@@ -2039,6 +2063,71 @@
 		atalk_if_get_info
 	});
 
-	printk("Appletalk 0.16 for Linux NET3.033\n");
+	printk("Appletalk 0.17 for Linux NET3.034\n");
 }
-#endif
+
+#ifdef MODULE
+
+int init_module(void)
+{
+	atalk_proto_init(NULL);
+	register_symtab(0);
+	return 0;
+}
+
+/*
+ *	FIX THIS: If there are any routes/devices configured
+ *	for appletalk we must not be unloaded.
+ */
+ 
+/* Remove all route entries. Interrupts must be off. */
+extern inline void free_route_list(void)
+{
+	struct atalk_route *list = atalk_router_list, *tmp;
+
+	while (list != NULL)
+	{
+		tmp = list->next;
+		kfree_s(list, sizeof(struct atalk_route));
+		list = tmp;
+	}
+}
+
+/* Remove all interface entries. Interrupts must be off. */
+extern inline void free_interface_list(void)
+{
+	struct atalk_iface *list = atalk_iface_list, *tmp;
+
+	while (list != NULL)
+	{
+		tmp = list->next;
+		kfree_s(list, sizeof(struct atalk_iface));
+		list = tmp;
+	}
+}
+
+void cleanup_module(void)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	aarp_cleanup_module();
+
+	proc_net_unregister(PROC_NET_ATALK);
+	proc_net_unregister(PROC_NET_AT_ROUTE);
+	proc_net_unregister(PROC_NET_ATIF);
+	unregister_netdevice_notifier(&ddp_notifier);
+	dev_remove_pack(&ltalk_packet_type);
+	dev_remove_pack(&ppptalk_packet_type);
+	unregister_snap_client(ddp_snap_id);
+	sock_unregister(atalk_proto_ops.family);
+
+	free_route_list();
+	free_interface_list();
+
+	restore_flags(flags);
+}
+
+#endif  /* MODULE */
diff -u --recursive --new-file v1.3.77/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- v1.3.77/linux/net/ax25/af_ax25.c	Thu Mar 21 20:36:55 1996
+++ linux/net/ax25/af_ax25.c	Mon Mar 25 08:58:24 1996
@@ -2310,7 +2310,7 @@
 		len += sprintf(buffer + len, " %s", ax25->dama_slave? " slave" : "    no");
 
 		if (ax25->sk != NULL) {
-			len += sprintf(buffer + len, " %5ld %5ld\n",
+			len += sprintf(buffer + len, " %5d %5d\n",
 				ax25->sk->wmem_alloc,
 				ax25->sk->rmem_alloc);
 		} else {
@@ -2419,7 +2419,7 @@
 		ax25_cs_get_info
 	});
 
-	printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.31 BETA for Linux NET3.032 (Linux 1.3.53)\n");
+	printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.32 BETA for Linux NET3.034 (Linux 1.3.77)\n");
 
 #ifdef CONFIG_BPQETHER
 	proc_net_register(&(struct proc_dir_entry) {
@@ -2584,7 +2584,7 @@
 			 *	freeing it).
 			 */
 			struct sk_buff *ourskb=skb_clone(skb, GFP_ATOMIC);
-			dev_kfree_skb(skb, FREE_READ);
+			dev_kfree_skb(skb, FREE_WRITE);
 			if(ourskb==NULL)
 				return 1;			
 			skb_pull(ourskb, AX25_HEADER_LEN - 1);	/* Keep PID */
diff -u --recursive --new-file v1.3.77/linux/net/core/dev.c linux/net/core/dev.c
--- v1.3.77/linux/net/core/dev.c	Thu Mar 21 20:36:55 1996
+++ linux/net/core/dev.c	Mon Mar 25 08:58:24 1996
@@ -655,7 +655,6 @@
 	 
 		else
 			kfree_skb(skb, FREE_WRITE);
-
 		/*
 		 *	Again, see if we can transmit anything now. 
 		 *	[Ought to take this out judging by tests it slows
@@ -1142,8 +1141,14 @@
 			 
 			if(ifr.ifr_mtu<68)
 				return -EINVAL;
-			dev->mtu = ifr.ifr_mtu;
-			ret = 0;
+
+                        if (dev->change_mtu)
+				ret = (*dev->change_mtu)(dev, ifr.ifr_mtu);
+                        else
+                        {
+				dev->mtu = ifr.ifr_mtu;
+				ret = 0;
+			}
 			break;
 	
 		case SIOCGIFMEM:	/* Get the per device memory space. We can add this but currently
@@ -1301,6 +1306,8 @@
 extern int ni65_init(void);
 extern int pi_init(void);
 extern int dec21040_init(void);
+extern void sdla_setup(void);
+extern void dlci_setup(void);
 
 int net_dev_init(void)
 {
@@ -1332,6 +1339,12 @@
 #if defined(CONFIG_DEC_ELCP)
 	dec21040_init();
 #endif	
+#if defined(CONFIG_DLCI)
+        dlci_setup();
+#endif
+#if defined(CONFIG_SDLA)
+        sdla_setup();
+#endif
 	/*
 	 *	SLHC if present needs attaching so other people see it
 	 *	even if not opened.
diff -u --recursive --new-file v1.3.77/linux/net/ethernet/pe2.c linux/net/ethernet/pe2.c
--- v1.3.77/linux/net/ethernet/pe2.c	Sat Nov 25 19:04:57 1995
+++ linux/net/ethernet/pe2.c	Mon Mar 25 08:58:24 1996
@@ -30,3 +30,8 @@
 	return proto;
 }
 
+void destroy_EII_client(struct datalink_proto *dl)
+{
+	if (dl)
+		kfree_s(dl, sizeof(struct datalink_proto));
+}
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/Config.in linux/net/ipv4/Config.in
--- v1.3.77/linux/net/ipv4/Config.in	Sat Feb 17 16:02:58 1996
+++ linux/net/ipv4/Config.in	Mon Mar 25 08:58:24 1996
@@ -21,6 +21,9 @@
 if [ "$CONFIG_NET_ALIAS" = "y" ]; then
 	tristate 'IP: aliasing support' CONFIG_IP_ALIAS
 fi
+if [ "$CONFIG_KERNELD" = "y" ]; then
+	bool 'IP: ARP daemon support (experimental)' CONFIG_ARPD
+fi
 comment '(it is safe to leave these untouched)'
 bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
 tristate 'IP: Reverse ARP' CONFIG_INET_RARP
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v1.3.77/linux/net/ipv4/af_inet.c	Thu Mar 21 20:36:55 1996
+++ linux/net/ipv4/af_inet.c	Mon Mar 25 08:58:24 1996
@@ -1463,7 +1463,7 @@
 	int i;
 
 
-	printk("Swansea University Computer Society TCP/IP for NET3.033\n");
+	printk("Swansea University Computer Society TCP/IP for NET3.034\n");
 
 	/*
 	 *	Tell SOCKET that we are alive... 
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v1.3.77/linux/net/ipv4/arp.c	Sun Mar 17 09:04:08 1996
+++ linux/net/ipv4/arp.c	Mon Mar 25 08:58:24 1996
@@ -18,7 +18,6 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- *
  * Fixes:
  *		Alan Cox	:	Removed the ethernet assumptions in Florian's code
  *		Alan Cox	:	Fixed some small errors in the ARP logic
@@ -53,6 +52,8 @@
  *		Eckes		:	ARP ioctl control errors.
  *		Alexey Kuznetsov:	Arp free fix.
  *		Manuel Rodriguez:	Gratutious ARP.
+ *              Jonathan Layes  :       Added arpd support through kerneld 
+ *                                      message queue (960314)
  */
 
 /* RFC1122 Status:
@@ -74,12 +75,12 @@
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/errno.h>
-#include <linux/if_arp.h>
 #include <linux/in.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/trdevice.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
@@ -101,6 +102,9 @@
 #ifdef CONFIG_NET_ALIAS
 #include <linux/net_alias.h>
 #endif
+#ifdef CONFIG_ARPD
+#include <linux/kerneld.h>
+#endif /* CONFIG_ARPD */
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -189,6 +193,14 @@
 
 static struct arp_table *arp_backlog;
 
+/* If we have arpd configured, assume that we will be running arpd and keep
+   the internal cache small */
+#ifdef CONFIG_ARPD
+#define ARP_MAXSIZE	256
+#endif /* CONFIG_ARPD */
+
+static unsigned int arp_size = 0;
+
 static void arp_run_bh(void);
 static void arp_check_expire (unsigned long);  
 
@@ -340,6 +352,7 @@
 	restore_flags(flags);
 
 	kfree_s(entry, sizeof(struct arp_table));
+	--arp_size;
 	return;
 }
 
@@ -368,6 +381,179 @@
 	return count;
 }
 
+
+/*
+ *	Force the expiry of an entry in the internal cache so the memory
+ *	can be used for a new request or for loading a query from arpd.
+ *	I'm not really sure what the best algorithm should be, so I just
+ *	search for the oldest.  NOTE:  make sure the cache is locked before
+ *      jumping into this function!  If someone wants to do something
+ *	other than searching the whole cache, by all means do so!
+ */
+
+#ifdef CONFIG_ARPD
+static int arp_force_expire(void)
+{
+	int i;
+	struct arp_table *entry = NULL;
+	struct arp_table **pentry = NULL;
+	struct arp_table **oldest_entry = NULL, **last_resort = NULL;
+	unsigned long oldest_used = ~0;
+
+#if RT_CACHE_DEBUG >= 2
+	printk("Looking for something to force expire.\n");
+#endif
+	for (i = 0; i < ARP_TABLE_SIZE; i++)
+	{
+		pentry = &arp_tables[i];
+
+		while ((entry = *pentry) != NULL)
+		{
+			if (entry->last_used < oldest_used)
+			{
+				if (arp_count_hhs(entry) == 0)
+				{
+					oldest_entry = pentry;
+				}
+				last_resort = pentry;
+				oldest_used = entry->last_used;
+			}
+			pentry = &entry->next;	/* go to next entry */
+		}
+	}
+	if (oldest_entry == NULL)
+	{
+		if (last_resort == NULL)
+			return -1;
+		oldest_entry = last_resort;
+	}
+		
+	entry = *oldest_entry;
+	*oldest_entry = (*oldest_entry)->next;
+#if RT_CACHE_DEBUG >= 2
+	printk("Force expiring %08x\n", entry->ip);
+#endif
+	arp_free_entry(entry);
+	return 0;
+}
+#endif /* CONFIG_ARPD */
+
+
+static void arpd_update(struct arp_table * entry, int loc)
+{
+#ifdef CONFIG_ARPD
+	static struct arpd_request arpreq;
+
+	arpreq.req = ARPD_UPDATE;
+	arpreq.ip = entry->ip;
+	arpreq.mask = entry->mask;
+	memcpy (arpreq.ha, entry->ha, MAX_ADDR_LEN);
+	arpreq.loc = loc;
+	arpreq.last_used = entry->last_used;
+	arpreq.last_updated = entry->last_updated;
+	arpreq.flags = entry->flags;
+	arpreq.dev = entry->dev;
+
+	kerneld_send(KERNELD_ARP, 0, sizeof(arpreq),
+				(char *) &arpreq, NULL);
+#endif /* CONFIG_ARPD */
+}
+
+/* 
+ * Allocate memory for a new entry.  If we are at the maximum limit
+ * of the internal ARP cache, arp_force_expire() an entry.  NOTE:  
+ * arp_force_expire() needs the cache to be locked, so therefore
+ * arp_add_entry() should only be called with the cache locked too!
+ */
+
+static struct arp_table * arp_add_entry(void)
+{
+	struct arp_table * entry;
+
+#ifdef CONFIG_ARPD
+	if (arp_size >= ARP_MAXSIZE)
+	{
+		if (arp_force_expire() < 0)
+			return NULL;
+	}
+#endif /* CONFIG_ARPD */
+
+	entry = (struct arp_table *)
+		kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
+
+	if (entry != NULL)
+		++arp_size;
+	return entry;
+}
+
+
+/*
+ * Lookup ARP entry by (addr, dev) pair in the arpd.
+ */
+
+static struct arp_table * arpd_lookup(u32 addr, unsigned short flags, 
+						struct device * dev,
+						int loc)
+{
+#ifdef CONFIG_ARPD
+	static struct arpd_request arpreq, retreq;
+	struct arp_table * entry;
+	int rv, i;
+
+	arpreq.req = ARPD_LOOKUP;
+	arpreq.ip = addr;
+	arpreq.loc = loc;
+
+	rv = kerneld_send(KERNELD_ARP, 
+			sizeof(retreq) | KERNELD_WAIT,
+			sizeof(arpreq),
+			(char *) &arpreq,
+			(char *) &retreq);
+	/* don't worry about rv != 0 too much, it's probably
+	   because arpd isn't running or an entry couldn't
+	   be found */
+
+	if (rv != 0)
+		return NULL;
+	if (dev != retreq.dev)
+		return NULL;
+	if (! memcmp (retreq.ha, "\0\0\0\0\0\0", 6))
+		return NULL;
+
+	arp_fast_lock();
+	entry = arp_add_entry();
+	arp_unlock();
+
+	if (entry == NULL)
+		return NULL;
+
+	entry->next = NULL;
+	entry->last_used = retreq.last_used;
+	entry->last_updated = retreq.last_updated;
+	entry->flags = retreq.flags;
+	entry->ip = retreq.ip;
+	entry->mask = retreq.mask;
+	memcpy (entry->ha, retreq.ha, MAX_ADDR_LEN);
+	arpreq.dev = entry->dev;
+
+	skb_queue_head_init(&entry->skb);
+	entry->hh = NULL;
+	entry->retries = 0;
+
+#if RT_CACHE_DEBUG >= 2
+	printk("Inserting arpd entry %08x\n in local cache.", entry->ip);
+#endif
+	i = HASH(entry->ip);
+	arp_fast_lock();
+	entry->next = arp_tables[i]->next;
+	arp_tables[i]->next = entry;
+	arp_unlock();
+	return entry;
+#endif /* CONFIG_ARPD */
+	return NULL;
+}
+
+
 /*
  * Invalidate all hh's, so that higher level will not try to use it.
  */
@@ -1015,6 +1201,7 @@
 		if (!(entry->flags & ATF_PERM)) {
 			memcpy(entry->ha, sha, dev->addr_len);
 			entry->last_updated = jiffies;
+			arpd_update(entry, __LINE__);
 		}
 		if (!(entry->flags & ATF_COM))
 		{
@@ -1042,11 +1229,13 @@
 		if (grat) 
 			goto end;
 
-		entry = (struct arp_table *)kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
+                entry = arp_add_entry();
 		if(entry == NULL)
 		{
 			arp_unlock();
+#if RT_CACHE_DEBUG >= 2
 			printk("ARP: no memory for new arp entry\n");
+#endif
 			kfree_skb(skb, FREE_READ);
 			return 0;
 		}
@@ -1060,6 +1249,7 @@
 		entry->timer.data = (unsigned long)entry;
 		memcpy(entry->ha, sha, dev->addr_len);
 		entry->last_updated = entry->last_used = jiffies;
+		arpd_update(entry, __LINE__);
 /*
  *	make entry point to	'correct' device
  */
@@ -1077,7 +1267,7 @@
 		}
 		else
 		{
-#if RT_CACHE_DEBUG >= 1
+#if RT_CACHE_DEBUG >= 2
 			printk("arp_rcv: %08x backlogged\n", entry->ip);
 #endif
 			arp_enqueue(&arp_backlog, entry);
@@ -1142,6 +1332,8 @@
 	arp_fast_lock();
 
 	entry = arp_lookup(paddr, 0, dev);
+	if (entry == NULL)
+		entry = arpd_lookup(paddr, 0, dev, __LINE__);
 
 	if (entry != NULL)
 	{
@@ -1149,10 +1341,12 @@
 		if (entry->flags & ATF_COM)
 		{
 			memcpy(haddr, entry->ha, dev->addr_len);
+			arpd_update(entry, __LINE__);
 			arp_unlock();
 			return 1;
 		}
 	}
+	arpd_update(entry, __LINE__);
 	arp_unlock();
 	return 0;
 }
@@ -1218,6 +1412,8 @@
 	 *	Find an entry
 	 */
 	entry = arp_lookup(paddr, 0, dev);
+	if (entry == NULL)
+		entry = arpd_lookup(paddr, 0, dev, __LINE__);
 
 	if (entry != NULL) 	/* It exists */
 	{
@@ -1267,6 +1463,7 @@
 		
 		entry->last_used = jiffies;
 		memcpy(haddr, entry->ha, dev->addr_len);
+		arpd_update(entry, __LINE__);
 		if (skb)
 			skb->arp = 1;
 		arp_unlock();
@@ -1277,8 +1474,7 @@
 	 *	Create a new unresolved entry.
 	 */
 	
-	entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
-					GFP_ATOMIC);
+	entry = arp_add_entry();
 	if (entry != NULL)
 	{
 		entry->last_updated = entry->last_used = jiffies;
@@ -1288,6 +1484,7 @@
 		memset(entry->ha, 0, dev->addr_len);
 		entry->dev = dev;
 		entry->hh    = NULL;
+		arpd_update(entry, __LINE__);
 		init_timer(&entry->timer);
 		entry->timer.function = arp_expire_request;
 		entry->timer.data = (unsigned long)entry;
@@ -1307,7 +1504,7 @@
 		}
 		else
 		{
-#if RT_CACHE_DEBUG >= 1
+#if RT_CACHE_DEBUG >= 2
 			printk("arp_find: %08x backlogged\n", entry->ip);
 #endif
 			arp_enqueue(&arp_backlog, entry);
@@ -1457,6 +1654,8 @@
 	arp_fast_lock();
 
 	entry = arp_lookup(paddr, 0, dev);
+	if (entry == NULL)
+		entry = arpd_lookup(paddr, 0, dev, __LINE__);
 
 	if (entry)
 	{
@@ -1498,6 +1697,7 @@
 		hh->hh_refcnt++;
 		restore_flags(flags);
 		entry->last_used = jiffies;
+		arpd_update(entry, __LINE__);
 		arp_unlock();
 		return 0;
 	}
@@ -1507,8 +1707,7 @@
 	 *	Create a new unresolved entry.
 	 */
 	
-	entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
-					GFP_ATOMIC);
+	entry = arp_add_entry();
 	if (entry == NULL)
 	{
 		kfree_s(hh, sizeof(struct hh_cache));
@@ -1523,6 +1722,7 @@
 	memset(entry->ha, 0, dev->addr_len);
 	entry->dev = dev;
 	entry->hh = hh;
+	arpd_update(entry, __LINE__);
 	ATOMIC_INCR(&hh->hh_refcnt);
 	init_timer(&entry->timer);
 	entry->timer.function = arp_expire_request;
@@ -1731,6 +1931,8 @@
 	 */
 	
 	entry = arp_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev);
+	if (entry == NULL)
+		entry = arpd_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev, __LINE__);
 
 	if (entry)
 	{
@@ -1744,8 +1946,7 @@
 	
 	if (entry == NULL)
 	{
-		entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
-					GFP_ATOMIC);
+		entry = arp_add_entry();
 		if (entry == NULL)
 		{
 			arp_unlock();
@@ -1782,6 +1983,7 @@
 		ha = dev->dev_addr;
 	memcpy(entry->ha, ha, dev->addr_len);
 	entry->last_updated = entry->last_used = jiffies;
+	arpd_update(entry, __LINE__);
 	entry->flags = r->arp_flags | ATF_COM;
 	if ((entry->flags & ATF_PUBL) && (entry->flags & ATF_NETMASK))
 	{
@@ -1816,6 +2018,9 @@
 	arp_fast_lock();
 
 	entry = arp_lookup(si->sin_addr.s_addr, r->arp_flags|ATF_NETMASK, dev);
+	if (entry == NULL)
+		entry = arpd_lookup(si->sin_addr.s_addr, 
+					r->arp_flags|ATF_NETMASK, dev, __LINE__);
 
 	if (entry == NULL)
 	{
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/ip_alias.c linux/net/ipv4/ip_alias.c
--- v1.3.77/linux/net/ipv4/ip_alias.c	Wed Dec 27 09:12:14 1995
+++ linux/net/ipv4/ip_alias.c	Mon Mar 25 08:58:25 1996
@@ -38,74 +38,77 @@
 #include <net/ip_alias.h>
 
 /*
- * AF_INET alias init
+ *	AF_INET alias init
  */
-static int 
-ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa)
+ 
+static int ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa)
 {
 #ifdef ALIAS_USER_LAND_DEBUG
-  printk("alias_init(%s) called.\n", alias->name);
+	printk("alias_init(%s) called.\n", alias->name);
 #endif
-  MOD_INC_USE_COUNT;
-  return 0;
+	MOD_INC_USE_COUNT;
+	return 0;
 }
 
 /*
- * AF_INET alias done
+ *	AF_INET alias done
  */
-static int
-ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias)
+ 
+static int ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias)
 {
 #ifdef ALIAS_USER_LAND_DEBUG
-  printk("alias_done(%s) called.\n", alias->name);
+	printk("alias_done(%s) called.\n", alias->name);
 #endif
-  MOD_DEC_USE_COUNT;
-  return 0;
+	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 /*
- * print alias address info
+ *	Print alias address info
  */
 
-int
-ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len)
+int ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len)
 {
-  char *p;
+	char *p;
 
-  p = (char *) &alias->dev.pa_addr;
-  return sprintf(buf, "%d.%d.%d.%d",
-		 (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
+	p = (char *) &alias->dev.pa_addr;
+	return sprintf(buf, "%d.%d.%d.%d",
+		(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
 }
 
-struct device *
-ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
+struct device *ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
 {
-  __u32 addr;
-  struct rtable *rt;
+	__u32 addr;
+	struct rtable *rt;
+	struct device *dev=NULL;
   
-  /*
-   * defensive...
-   */
+	/*
+	 *	Defensive...	
+	 */
   
-  if (main_dev == NULL) return NULL;
-
-  /*
-   * get u32 address. 
-   */
-
-  addr =  (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0;
-
-  if (addr == 0) return NULL;
-
-  /*
-   * find 'closest' device to address given. any other suggestions? ...
-   * net_alias module will check if returned device is main_dev's alias
-   */
-
-  rt = ip_rt_route(addr, 0);
-
-  return (rt)? rt->rt_dev : NULL;
+	if (main_dev == NULL) 
+		return NULL;
 
+	/*
+	 *	Get u32 address. 
+	 */
+
+	addr =  (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0;
+	if (addr == 0)
+		return NULL;
+
+	/*
+	 *	Find 'closest' device to address given. any other suggestions? ...
+	 *	net_alias module will check if returned device is main_dev's alias
+	 */
+
+	rt = ip_rt_route(addr, 0);
+	if(rt)
+	{
+		dev=rt->rt_dev;
+		ip_rt_put(rt);
+	}
+	return dev;
 }
 
 /*
@@ -114,16 +117,16 @@
 
 struct net_alias_type ip_alias_type =
 {
-  AF_INET,			/* type */
-  0,				/* n_attach */
-  "ip",				/* name */
-  NULL,				/* get_addr32() */
-  NULL,				/* dev_addr_chk() */
-  ip_alias_dev_select,		/* dev_select() */
-  ip_alias_init_1,		/* alias_init_1() */
-  ip_alias_done_1,		/* alias_done_1() */
-  ip_alias_print_1,		/* alias_print_1() */
-  NULL				/* next */
+	AF_INET,		/* type */
+	0,			/* n_attach */
+	"ip",			/* name */
+	NULL,			/* get_addr32() */
+	NULL,			/* dev_addr_chk() */
+	ip_alias_dev_select,	/* dev_select() */
+	ip_alias_init_1,	/* alias_init_1() */
+	ip_alias_done_1,	/* alias_done_1() */
+	ip_alias_print_1,	/* alias_print_1() */
+	NULL			/* next */
 };
 
 /*
@@ -132,7 +135,7 @@
 
 int ip_alias_init(void)
 {
-  return register_net_alias_type(&ip_alias_type, AF_INET);
+	return register_net_alias_type(&ip_alias_type, AF_INET);
 }
 
 /*
@@ -141,22 +144,22 @@
 
 int ip_alias_done(void)
 {
-  return unregister_net_alias_type(&ip_alias_type);
+	return unregister_net_alias_type(&ip_alias_type);
 }
 
 #ifdef MODULE
 
 int init_module(void)
 {
-  if (ip_alias_init() != 0)
-    return -EIO;
-  return 0;
+	if (ip_alias_init() != 0)
+		return -EIO;
+	return 0;
 }
 
 void cleanup_module(void)
 {
-  if (ip_alias_done() != 0)
-    printk("ip_alias: can't remove module");
+	if (ip_alias_done() != 0)
+		printk("ip_alias: can't remove module");
 }
 
 #endif /* MODULE */
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c
--- v1.3.77/linux/net/ipv4/ip_forward.c	Fri Feb  9 17:53:10 1996
+++ linux/net/ipv4/ip_forward.c	Mon Mar 25 08:58:25 1996
@@ -208,9 +208,10 @@
 		 *	we calculated.
 		 */
 #ifndef CONFIG_IP_NO_ICMP_REDIRECT
-		if (dev == dev2 && !((iph->saddr^iph->daddr)&dev->pa_mask) &&
-		    (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
-			icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
+		if (dev == dev2 && 
+			!((iph->saddr^dev->pa_addr)&dev->pa_mask) &&
+		    	(rt->rt_flags&RTF_MODIFIED) && !opt->srr)
+				icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
 #endif
 #ifdef CONFIG_IP_MROUTE
 	}
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c
--- v1.3.77/linux/net/ipv4/ip_fragment.c	Thu Mar 21 20:36:55 1996
+++ linux/net/ipv4/ip_fragment.c	Mon Mar 25 08:58:25 1996
@@ -641,7 +641,7 @@
 	if (ntohs(iph->frag_off) & IP_DF)
 	{
 		ip_statistics.IpFragFails++;
-		printk("ip_queue_xmit: frag needed\n");
+		NETDEBUG(printk("ip_queue_xmit: frag needed\n"));
 		return;
 	}
 
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/ip_input.c linux/net/ipv4/ip_input.c
--- v1.3.77/linux/net/ipv4/ip_input.c	Fri Feb  9 17:53:11 1996
+++ linux/net/ipv4/ip_input.c	Mon Mar 25 08:58:25 1996
@@ -260,6 +260,17 @@
 
 	skb_trim(skb,ntohs(iph->tot_len));
 
+	/*
+	 *	Try to select closest <src,dst> alias device, if any.
+	 *	net_alias_dev_rcv_sel32 returns main device if it 
+	 *	fails to found other.
+	 */
+
+#ifdef CONFIG_NET_ALIAS
+	if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) 
+		skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
+#endif
+
 	if (iph->ihl > 5) 
 	{
 		skb->ip_summed = 0;
@@ -275,17 +286,6 @@
 #endif					
 	}
 	
-	/*
-	 *	Try to select closest <src,dst> alias device, if any.
-	 *	net_alias_dev_rcv_sel32 returns main device if it 
-	 *	fails to found other.
-	 */
-
-#ifdef CONFIG_NET_ALIAS
-	if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) 
-		skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
-#endif
-
 	/*
 	 *	Account for the packet (even if the packet is
 	 *	not accepted by the firewall!).
diff -u --recursive --new-file v1.3.77/linux/net/ipv4/proc.c linux/net/ipv4/proc.c
--- v1.3.77/linux/net/ipv4/proc.c	Thu Mar 21 20:36:55 1996
+++ linux/net/ipv4/proc.c	Mon Mar 25 08:58:25 1996
@@ -71,7 +71,8 @@
 	off_t begin=0;
   
 	s_array = pro->sock_array;
-	len += sprintf(buffer, "sl  local_address rem_address   st tx_queue rx_queue tr tm->when uid\n");
+	len += sprintf(buffer, "sl  local_address rem_address   st tx_queue "
+	    "rx_queue tr tm->when uid inode\n");
 /*
  *	This was very pretty but didn't work when a socket is destroyed
  *	at the wrong moment (eg a syn recv socket getting a reset), or
@@ -108,13 +109,16 @@
 			    timer_active=timer_active2;
 			    timer_expires=sp->timer.expires;
 			}
-			len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08X:%08X %02X:%08lX %08X %d %d\n",
+			len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X"
+			    " %02X %08X:%08X %02X:%08lX %08X %d %d %ld\n",
 				i, src, srcp, dest, destp, sp->state, 
 				format==0?sp->write_seq-sp->rcv_ack_seq:sp->wmem_alloc, 
 				format==0?sp->acked_seq-sp->copied_seq:sp->rmem_alloc,
 				timer_active, timer_expires-jiffies, (unsigned) sp->retransmits,
 				(sp->socket&&SOCK_INODE(sp->socket))?SOCK_INODE(sp->socket)->i_uid:0,
-				timer_active?sp->timeout:0);
+				timer_active?sp->timeout:0,
+				sp->socket && SOCK_INODE(sp->socket) ?
+				SOCK_INODE(sp->socket)->i_ino : 0);
 			if (timer_active1) add_timer(&sp->retransmit_timer);
 			if (timer_active2) add_timer(&sp->timer);
 			/*
diff -u --recursive --new-file v1.3.77/linux/net/ipx/Makefile linux/net/ipx/Makefile
--- v1.3.77/linux/net/ipx/Makefile	Tue Aug 15 20:39:11 1995
+++ linux/net/ipx/Makefile	Mon Mar 25 08:58:25 1996
@@ -9,6 +9,7 @@
 
 O_TARGET := ipx.o
 O_OBJS   := af_ipx.o
+M_OBJS   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
 
diff -u --recursive --new-file v1.3.77/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v1.3.77/linux/net/ipx/af_ipx.c	Thu Mar 21 20:36:56 1996
+++ linux/net/ipx/af_ipx.c	Mon Mar 25 08:58:25 1996
@@ -41,13 +41,16 @@
  *			Supports sendmsg/recvmsg
  *	Revision 0.33:	Internal network support, routing changes, uses a
  *			protocol private area for ipx data.
+ *	Revision 0.34:	Module support. <Jim Freeman>
  *
  * 	Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
  *	Neither Greg Page nor Caldera, Inc. admit liability nor provide 
  *	warranty for any of this software. This material is provided 
  *	"AS-IS" and at no charge.		
  */
-  
+
+#include <linux/module.h>
+
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/types.h>
@@ -59,11 +62,10 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
-#include <linux/ipx.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <net/ipx.h>
+#include <linux/inet.h>
 #include <linux/route.h>
-#include <linux/skbuff.h>
 #include <net/sock.h>
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -77,7 +79,10 @@
 #include <linux/stat.h>
 #include <linux/firewall.h>
 
-#ifdef CONFIG_IPX
+#ifdef MODULE
+static void ipx_proto_finito(void);
+#endif /* def MODULE */
+
 /* Configuration Variables */
 static unsigned char	ipxcfg_max_hops = 16;
 static char		ipxcfg_auto_select_primary = 0;
@@ -89,10 +94,10 @@
 static struct datalink_proto	*p8023_datalink = NULL;
 static struct datalink_proto	*pSNAP_datalink = NULL;
 
-static ipx_interface	*ipx_interfaces = NULL;
 static ipx_route 	*ipx_routes = NULL;
-static ipx_interface	*ipx_internal_net = NULL;
+static ipx_interface	*ipx_interfaces = NULL;
 static ipx_interface	*ipx_primary_net = NULL;
+static ipx_interface	*ipx_internal_net = NULL;
 
 static int
 ipxcfg_set_auto_create(char val)
@@ -187,6 +192,7 @@
 	}
 	
 	kfree_s(sk,sizeof(*sk));
+	MOD_DEC_USE_COUNT;
 }
 	
 /* The following code is used to support IPX Interfaces (IPXITF).  An
@@ -194,7 +200,7 @@
  */
 
 static ipx_route * ipxrtr_lookup(unsigned long);
- 
+
 static void
 ipxitf_clear_primary_net(void)
 {
@@ -324,6 +330,10 @@
 		ipx_internal_net = NULL;
 
 	kfree_s(intrfc, sizeof(*intrfc));
+	/* sockets still dangling
+	 * - must be closed from user space
+	 */
+	return;
 }
 
 static int 
@@ -790,6 +800,7 @@
 
 	if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
 		ipx_primary_net = intrfc;
+	return;
 }
 
 static int 
@@ -1155,7 +1166,7 @@
 /*
  *	Route an outgoing frame from a socket.
  */
- 
+
 static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len)
 {
 	struct sk_buff *skb;
@@ -1259,7 +1270,7 @@
 /*
  *	We use a normal struct rtentry for route handling
  */
- 
+
 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
 {
 	int err;
@@ -1483,7 +1494,7 @@
 *	      Handling for system calls applied via the various interfaces to an IPX socket object		    *
 *														    *
 \*******************************************************************************************************************/
- 
+
 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	switch(cmd)
@@ -1642,6 +1653,7 @@
 	sk->error_report=def_callback1;
 
 	sk->zapped=1;
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -1830,8 +1842,10 @@
 
 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
 {
-	if(newsock->data)
+	if(newsock->data) {
 		kfree_s(newsock->data,sizeof(ipx_socket));
+		MOD_DEC_USE_COUNT;
+	}
 	return -EOPNOTSUPP;
 }
 
@@ -2187,7 +2201,7 @@
 	NULL,
 	NULL,
 };
- 
+
 static struct packet_type ipx_dix_packet_type = 
 {
 	0,	/* MUTTER ntohs(ETH_P_IPX),*/
@@ -2196,7 +2210,7 @@
 	NULL,
 	NULL,
 };
- 
+
 static struct notifier_block ipx_dev_notifier={
 	ipxitf_device_event,
 	NULL,
@@ -2206,12 +2220,30 @@
 
 extern struct datalink_proto	*make_EII_client(void);
 extern struct datalink_proto	*make_8023_client(void);
+extern void	destroy_EII_client(struct datalink_proto *);
+extern void	destroy_8023_client(struct datalink_proto *);
 
-void ipx_proto_init(struct net_proto *pro)
-{
-	unsigned char	val = 0xE0;
-	unsigned char	snapval[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
+struct proc_dir_entry ipx_procinfo = {
+	PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO,
+	1, 0, 0, 0, &proc_net_inode_operations, ipx_get_info
+};
 
+struct proc_dir_entry ipx_if_procinfo = {
+	PROC_NET_IPX_INTERFACE, 13, "ipx_interface", S_IFREG | S_IRUGO,
+	1, 0, 0, 0, &proc_net_inode_operations, ipx_interface_get_info
+};
+
+struct proc_dir_entry ipx_rt_procinfo = {
+	PROC_NET_IPX_ROUTE, 9, "ipx_route", S_IFREG | S_IRUGO,
+	1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info
+};
+
+static unsigned char	ipx_8022_type = 0xE0;
+static unsigned char	ipx_snap_id[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
+
+void
+ipx_proto_init(struct net_proto *pro)
+{
 	(void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
 
 	pEII_datalink = make_EII_client();
@@ -2222,34 +2254,82 @@
 	ipx_8023_packet_type.type=htons(ETH_P_802_3);
 	dev_add_pack(&ipx_8023_packet_type);
 	
-	if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
+	if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
 		printk("IPX: Unable to register with 802.2\n");
 
-	if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL)
+	if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
 		printk("IPX: Unable to register with SNAP\n");
 	
 	register_netdevice_notifier(&ipx_dev_notifier);
 
-	proc_net_register(&(struct proc_dir_entry) {
-		PROC_NET_IPX, 3, "ipx",
-		S_IFREG | S_IRUGO, 1, 0, 0,
-		0, &proc_net_inode_operations,
-		ipx_get_info
-	});
-	proc_net_register(&(struct proc_dir_entry) {
-		PROC_NET_IPX_INTERFACE, 13, "ipx_interface",
-		S_IFREG | S_IRUGO, 1, 0, 0,
-		0, &proc_net_inode_operations,
-		ipx_interface_get_info
-	});
-	proc_net_register(&(struct proc_dir_entry) {
-		PROC_NET_IPX_ROUTE, 9, "ipx_route",
-		S_IFREG | S_IRUGO, 1, 0, 0,
-		0, &proc_net_inode_operations,
-		ipx_rt_get_info
-	});
+	proc_net_register(&ipx_procinfo);
+	proc_net_register(&ipx_if_procinfo);
+	proc_net_register(&ipx_rt_procinfo);
 		
-	printk("Swansea University Computer Society IPX 0.33 for NET3.032\n");
+	printk("Swansea University Computer Society IPX 0.34 for NET3.034\n");
 	printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
 }
-#endif
+
+#ifdef MODULE
+/* Note on MOD_{INC,DEC}_USE_COUNT:
+ *
+ * Use counts are incremented/decremented when
+ * sockets are created/deleted.
+ * 
+ * Routes are always associated with an interface, and
+ * allocs/frees will remain properly accounted for by
+ * their associated interfaces.
+ * 
+ * Ergo, before the ipx module can be removed, all IPX
+ * sockets be closed from user space. 
+ */
+
+static void
+ipx_proto_finito(void)
+{	ipx_interface	*ifc;
+
+	while (ipx_interfaces) {
+		ifc = ipx_interfaces;
+		ipx_interfaces = ifc->if_next;
+		ifc->if_next = NULL;
+		ipxitf_down(ifc);
+	}
+
+	proc_net_unregister(PROC_NET_IPX_ROUTE);
+	proc_net_unregister(PROC_NET_IPX_INTERFACE);
+	proc_net_unregister(PROC_NET_IPX);
+
+	unregister_netdevice_notifier(&ipx_dev_notifier);
+
+	unregister_snap_client(ipx_snap_id);
+	pSNAP_datalink = NULL;
+
+	unregister_8022_client(ipx_8022_type);
+	p8022_datalink = NULL;
+
+	dev_remove_pack(&ipx_8023_packet_type);
+	destroy_8023_client(p8023_datalink);
+	p8023_datalink = NULL;
+
+	dev_remove_pack(&ipx_dix_packet_type);
+	destroy_EII_client(pEII_datalink);
+	pEII_datalink = NULL;
+
+	(void) sock_unregister(ipx_proto_ops.family);
+
+	return;
+}
+
+int init_module(void)
+{
+	ipx_proto_init(NULL);
+	register_symtab(0);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	ipx_proto_finito();
+	return;
+}
+#endif /* def MODULE */
diff -u --recursive --new-file v1.3.77/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- v1.3.77/linux/net/netrom/af_netrom.c	Fri Feb 23 13:54:44 1996
+++ linux/net/netrom/af_netrom.c	Mon Mar 25 08:58:26 1996
@@ -1274,7 +1274,7 @@
 			ax2asc(&s->nr->user_addr));
 		len += sprintf(buffer + len, "%-9s ",
 			ax2asc(&s->nr->dest_addr));
-		len += sprintf(buffer + len, "%-9s %-3s  %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5ld %5ld\n",
+		len += sprintf(buffer + len, "%-9s %-3s  %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5d %5d\n",
 			ax2asc(&s->nr->source_addr),
 			devname, s->nr->my_index, s->nr->my_id,
 			s->nr->your_index, s->nr->your_id,
@@ -1341,7 +1341,7 @@
 {
 	sock_register(nr_proto_ops.family, &nr_proto_ops);
 	register_netdevice_notifier(&nr_dev_notifier);
-	printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.030 Linux 1.3.45\n");
+	printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.032 Linux 1.3.77\n");
 
 	nr_default.quality    = NR_DEFAULT_QUAL;
 	nr_default.obs_count  = NR_DEFAULT_OBS;
diff -u --recursive --new-file v1.3.77/linux/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c
--- v1.3.77/linux/net/netrom/nr_dev.c	Fri Feb 23 13:54:44 1996
+++ linux/net/netrom/nr_dev.c	Mon Mar 25 08:58:26 1996
@@ -30,7 +30,6 @@
 #include <linux/fcntl.h>
 #include <linux/in.h>
 #include <linux/if_ether.h>	/* For the statistics structure. */
-#include <linux/if_arp.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -39,6 +38,7 @@
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/skbuff.h>
 
 #include <net/ip.h>
diff -u --recursive --new-file v1.3.77/linux/net/netsyms.c linux/net/netsyms.c
--- v1.3.77/linux/net/netsyms.c	Thu Jan  1 02:00:00 1970
+++ linux/net/netsyms.c	Mon Mar 25 08:58:28 1996
@@ -0,0 +1,173 @@
+/*
+ *  linux/net/netsyms.c
+ *
+ *  Symbol table for the linux networking subsystem. Moved here to
+ *  make life simpler in ksyms.c.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/firewall.h>
+#include <linux/trdevice.h>
+#include <linux/ioport.h>
+
+#ifdef CONFIG_AX25
+#include <net/ax25.h>
+#endif
+
+#ifdef CONFIG_INET
+#include <linux/ip.h>
+#include <linux/etherdevice.h>
+#include <net/protocol.h>
+#include <net/arp.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+#include <net/icmp.h>
+#include <net/route.h>
+#include <linux/net_alias.h>
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#if     defined(CONFIG_ULTRA)   ||      defined(CONFIG_WD80x3)          || \
+        defined(CONFIG_EL2)     ||      defined(CONFIG_NE2000)          || \
+        defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
+        defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)
+#include "../drivers/net/8390.h"
+#endif
+
+extern int (*rarp_ioctl_hook)(int,void*);
+
+#ifdef CONFIG_IPX_MODULE
+extern struct datalink_proto   *make_EII_client(void);
+extern struct datalink_proto   *make_8023_client(void);
+extern void destroy_EII_client(struct datalink_proto *);
+extern void destroy_8023_client(struct datalink_proto *);
+#endif
+
+
+static struct symbol_table net_syms = {
+#include <linux/symtab_begin.h>
+
+        /* Socket layer registration */
+        X(sock_register),
+        X(sock_unregister),
+
+        /* Socket layer support routines */
+	X(memcpy_fromiovec),
+	X(sock_setsockopt),
+	X(sock_getsockopt),
+	X(sock_wake_async),
+	X(sock_alloc_send_skb),
+	X(skb_recv_datagram),
+	X(skb_free_datagram),
+	X(skb_copy_datagram),
+	X(skb_copy_datagram_iovec),
+	X(datagram_select),
+
+#ifdef CONFIG_IPX_MODULE
+	X(make_8023_client),
+	X(destroy_8023_client),
+	X(make_EII_client),
+	X(destroy_EII_client),
+#endif
+
+#ifdef CONFIG_FIREWALL
+	/* Firewall registration */
+	X(register_firewall),
+	X(unregister_firewall),
+#endif
+
+#ifdef CONFIG_INET
+	/* Internet layer registration */
+	X(inet_add_protocol),
+	X(inet_del_protocol),
+	X(rarp_ioctl_hook),
+	X(init_etherdev),
+	X(ip_rt_route),
+	X(icmp_send),
+	X(ip_options_compile),
+	X(ip_rt_put),
+	X(arp_send),
+#ifdef CONFIG_IP_FORWARD
+	X(ip_forward),
+#endif
+
+#if	defined(CONFIG_ULTRA)	||	defined(CONFIG_WD80x3)		|| \
+	defined(CONFIG_EL2)	||	defined(CONFIG_NE2000)		|| \
+	defined(CONFIG_E2100)	||	defined(CONFIG_HPLAN_PLUS)	|| \
+	defined(CONFIG_HPLAN)	||	defined(CONFIG_AC3200)
+	/* If 8390 NIC support is built in, we will need these. */
+	X(ei_open),
+	X(ei_close),
+	X(ei_debug),
+	X(ei_interrupt),
+	X(ethdev_init),
+	X(NS8390_init),
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#endif  /* CONFIG_INET */
+
+	/* Device callback registration */
+	X(register_netdevice_notifier),
+	X(unregister_netdevice_notifier),
+
+#ifdef CONFIG_NET_ALIAS
+	X(register_net_alias_type),
+	X(unregister_net_alias_type),
+#endif
+
+        /* support for loadable net drivers */
+#ifdef CONFIG_AX25
+	X(ax25_encapsulate),
+	X(ax25_rebuild_header),
+#endif
+#ifdef CONFIG_INET
+	X(register_netdev),
+	X(unregister_netdev),
+	X(ether_setup),
+	X(eth_type_trans),
+	X(eth_copy_and_sum),
+	X(alloc_skb),
+	X(kfree_skb),
+	X(skb_clone),
+	X(dev_alloc_skb),
+	X(dev_kfree_skb),
+	X(netif_rx),
+	X(dev_tint),
+	X(irq2dev_map),
+	X(dev_add_pack),
+	X(dev_remove_pack),
+	X(dev_get),
+	X(dev_ioctl),
+	X(dev_queue_xmit),
+	X(dev_base),
+	X(dev_close),
+	X(dev_mc_add),
+	X(arp_find),
+	X(n_tty_ioctl),
+	X(tty_register_ldisc),
+	X(kill_fasync),
+#ifdef CONFIG_FIREWALL
+	X(call_in_firewall),
+#endif
+#endif  /* CONFIG_INET */
+
+#include <linux/symtab_end.h>
+};
+
+void export_net_symbols(void)
+{
+	register_symtab(&net_syms);
+}
diff -u --recursive --new-file v1.3.77/linux/net/protocols.c linux/net/protocols.c
--- v1.3.77/linux/net/protocols.c	Tue Mar  5 10:11:16 1996
+++ linux/net/protocols.c	Mon Mar 25 08:58:28 1996
@@ -18,7 +18,7 @@
 #ifdef	CONFIG_INET
 #include <linux/inet.h>
 #endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 #include <net/ipxcall.h>
 #include <net/p8022call.h>
 #endif
@@ -28,8 +28,8 @@
 #include <net/nrcall.h>
 #endif
 #endif
-#ifdef CONFIG_ATALK
-#ifndef CONFIG_IPX
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
+#if ! ( defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) )
 #include <net/p8022call.h>
 #endif
 #include <net/atalkcall.h>
@@ -48,7 +48,8 @@
 #ifdef	CONFIG_UNIX
   { "UNIX",	unix_proto_init	},			/* Unix domain socket family 	*/
 #endif
-#if defined(CONFIG_IPX)||defined(CONFIG_ATALK)  
+#if defined(CONFIG_IPX)   || defined(CONFIG_IPX_MODULE) || \
+    defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
   { "802.2",	p8022_proto_init },			/* 802.2 demultiplexor		*/
   { "SNAP",	snap_proto_init },			/* SNAP demultiplexor		*/
 #endif
@@ -72,5 +73,3 @@
 #endif
   { NULL,	NULL		}			/* End marker			*/
 };
-
-
diff -u --recursive --new-file v1.3.77/linux/net/socket.c linux/net/socket.c
--- v1.3.77/linux/net/socket.c	Wed Feb 14 14:37:20 1996
+++ linux/net/socket.c	Mon Mar 25 08:58:28 1996
@@ -33,6 +33,7 @@
  *					for NetROM and future kernel nfsd type
  *					stuff.
  *		Alan Cox	:	sendmsg/recvmsg basics.
+ *		Tom Dyas	:	Export net symbols.
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -64,12 +65,17 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/firewall.h>
+#include <linux/kerneld.h>
 
 #include <net/netlink.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
 
+#ifdef CONFIG_MODULES
+extern void export_net_symbols(void);
+#endif
+
 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
 		      int whence);
 static int sock_read(struct inode *inode, struct file *file, char *buf,
@@ -255,6 +261,7 @@
 	sock->conn = NULL;
 	sock->iconn = NULL;
 	sock->next = NULL;
+	sock->file = NULL;
 	sock->wait = &inode->i_wait;
 	sock->inode = inode;		/* "backlink": we could use pointer arithmetic instead */
 	sock->fasync_list = NULL;
@@ -302,6 +309,7 @@
 	if (peersock)
 		sock_release_peer(peersock);
 	--sockets_in_use;	/* Bookkeeping.. */
+	sock->file=NULL;
 	iput(SOCK_INODE(sock));
 }
 
@@ -506,6 +514,19 @@
  *	family, then create a fresh socket.
  */
 
+static int find_protocol_family(int family)
+{
+	register int i;
+	for (i = 0; i < NPROTO; i++)
+	{
+		if (pops[i] == NULL)
+			continue;
+		if (pops[i]->family == family)
+			return i;
+	}
+	return -1;
+}
+
 asmlinkage int sys_socket(int family, int type, int protocol)
 {
 	int i, fd;
@@ -513,14 +534,20 @@
 	struct proto_ops *ops;
 
 	/* Locate the correct protocol family. */
-	for (i = 0; i < NPROTO; ++i) 
-	{
-		if (pops[i] == NULL) continue;
-		if (pops[i]->family == family) 
-			break;
+	i = find_protocol_family(family);
+
+#ifdef CONFIG_KERNELD
+	/* Attempt to load a protocol module if the find failed. */
+	if (i < 0)
+	{
+		char module_name[30];
+		sprintf(module_name,"net-pf-%d",family);
+		request_module(module_name);
+		i = find_protocol_family(family);
 	}
+#endif
 
-	if (i == NPROTO) 
+	if (i < 0)
 	{
   		return -EINVAL;
 	}
@@ -565,6 +592,8 @@
 		return(-EINVAL);
 	}
 
+	sock->file=current->files->fd[fd];
+
 	return(fd);
 }
 
@@ -745,7 +774,8 @@
 		sock_release(newsock);
 		return(-EINVAL);
 	}
-
+	sock->file=current->files->fd[fd];
+	
 	if (upeer_sockaddr)
 	{
 		newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1);
@@ -1347,7 +1377,7 @@
 {
 	int i;
 
-	printk("Swansea University Computer Society NET3.033 for Linux 1.3.50\n");
+	printk("Swansea University Computer Society NET3.034 for Linux 1.3.77\n");
 
 	/*
 	 *	Initialize all address (protocol) families. 
@@ -1383,6 +1413,14 @@
 	 */
 
 	proto_init();
+
+	/*
+	 *	Export networking symbols to the world.
+	 */
+
+#ifdef CONFIG_MODULES
+	export_net_symbols();
+#endif
 }
 
 int socket_get_info(char *buffer, char **start, off_t offset, int length)
diff -u --recursive --new-file v1.3.77/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
--- v1.3.77/linux/net/unix/af_unix.c	Sun Mar 17 09:04:09 1996
+++ linux/net/unix/af_unix.c	Mon Mar 25 08:58:28 1996
@@ -26,6 +26,7 @@
  *					Mike Shaver's work.
  *		Marty Leisner	:	Fixes to fd passing
  *		Nick Nevin	:	recvmsg bugfix.
+ *		Alan Cox	:	Started proper garbage collector
  *
  * Known differences from reference BSD that was tested:
  *
@@ -69,7 +70,7 @@
 #include <net/af_unix.h>
 #include <linux/proc_fs.h>
 
-static unix_socket *unix_socket_list=NULL;
+unix_socket *unix_socket_list=NULL;
 
 #define min(a,b)	(((a)<(b))?(a):(b))
 
@@ -745,19 +746,12 @@
 			return -EBADF;
 	}
 	
-	/*
-	 *	Make sure the garbage collector can cope.
-	 */
-	 
-	if(unix_gc_free<num)
-		return -ENOBUFS;
-	
         /* add another reference to these files */
 	for(i=0; i< num; i++)
 	{
 		fp[i]=current->files->fd[fdp[i]];
 		fp[i]->f_count++;
-		unix_gc_add(sk, fp[i]);
+		unix_inflight(fp[i]);
 	}
 	
 	return num;
@@ -773,7 +767,7 @@
 	for(i=0;i<num;i++)
 	{
 		close_fp(fp[i]);
-		unix_gc_remove(fp[i]);
+		unix_notinflight(fp[i]);
 	}
 }
 
@@ -851,7 +845,7 @@
 		ufp[ufn]=fp[i];
 		*cmfptr++=ufn;
 		FD_CLR(ufn,&current->files->close_on_exec);
-		unix_gc_remove(fp[i]);
+		unix_notinflight(fp[i]);
 	}
 	/*
 	 *	Dump those that don't
@@ -859,7 +853,7 @@
 	for(;i<fdnum;i++)
 	{
 		close_fp(fp[i]);
-		unix_gc_remove(fp[i]);
+		unix_notinflight(fp[i]);
 	}
 	kfree(skb->h.filp);
 	skb->h.filp=NULL;
@@ -1265,17 +1259,19 @@
 	int len=0;
 	unix_socket *s=unix_socket_list;
 	
-	len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St Path\n");
+	len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St "
+	    "Inode Path\n");
 	
 	while(s!=NULL)
 	{
-		len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
+		len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld",
 			s,
 			s->protinfo.af_unix.locks,
 			0,
 			s->socket->flags,
 			s->socket->type,
-			s->socket->state);
+			s->socket->state,
+			s->socket->inode ? s->socket->inode->i_ino : 0);
 		if(s->protinfo.af_unix.name!=NULL)
 			len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name);
 		else
@@ -1299,7 +1295,7 @@
 }
 #endif
 
-static struct proto_ops unix_proto_ops = {
+struct proto_ops unix_proto_ops = {
 	AF_UNIX,
 	
 	unix_create,
diff -u --recursive --new-file v1.3.77/linux/net/unix/garbage.c linux/net/unix/garbage.c
--- v1.3.77/linux/net/unix/garbage.c	Tue Mar  5 10:11:16 1996
+++ linux/net/unix/garbage.c	Mon Mar 25 08:58:28 1996
@@ -1,13 +1,38 @@
 /*
- * NET3:	Garbage Collector For AF_UNIX sockets (STUB)
+ * NET3:	Garbage Collector For AF_UNIX sockets (STUBS)
  *
- * Authors:	
+ * Garbage Collector:
+ *	Copyright (C) Barak A. Pearlmutter.
+ *	Released under the GPL version 2 or later.
  *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
- * Fixes:
+ * NOTE:
+ *	We don't actually call this yet. I'm finishing some tests before I
+ *	enable it. The bold can add it in themselves.
+ *
+ * Chopped about by Alan Cox 22/3/96 to make it fit the AF_UNIX socket problem.
+ * If it doesnt work blame me, it worked when Barak sent it.
+ *
+ * Assumptions:
+ *
+ *  - object w/ a bit
+ *  - free list
+ *
+ * Current optimizations:
+ *
+ *  - explicit stack instead of recursion
+ *  - tail recurse on first born instead of immediate push/pop
+ *
+ *  Future optimizations:
+ *
+ *  - don't just push entire root set; process in place
+ *  - use linked list for internal stack
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *  Fixes:
  *
  */
  
@@ -35,19 +60,218 @@
 #include <net/tcp.h>
 #include <net/af_unix.h>
 #include <linux/proc_fs.h>
+
+/* Internal data structures and random procedures: */
+
+#define MAX_STACK 1000		/* Maximum depth of tree (about 1 page) */
+static unix_socket **stack;	/* stack of objects to mark */
+static int in_stack = 0;	/* first free entry in stack */
+
+
+extern inline unix_socket *unix_get_socket(struct file *filp)
+{
+	struct socket *s;
+	/*
+	 *	Socket ?
+	 */
+	if(filp->f_inode->i_mode!=S_IFSOCK)
+		return NULL;
+	s=&(filp->f_inode->u.socket_i);
+	/*
+	 *	AF_UNIX ?
+	 */
+	if(s->ops!=&unix_proto_ops)
+		return NULL;
+	/*
+	 *	Got one.
+	 */
+	return s->data;	
+}
+
+/*
+ *	Keep the number of times in flight count for the file
+ *	descriptor if it is for an AF_UNIX socket.
+ */
+ 
+void unix_inflight(struct file *fp)
+{
+	unix_socket *s=unix_get_socket(fp);
+	if(s)
+		s->protinfo.af_unix.inflight++;
+}
+
+void unix_notinflight(struct file *fp)
+{
+	unix_socket *s=unix_get_socket(fp);
+	if(s)
+		s->protinfo.af_unix.inflight--;
+}
+
+
 /*
- *	Garbage Collector Stubs
+ *	Garbage Collector Support Functions
  */
  
+extern inline void push_stack(unix_socket *x)
+{
+	if (in_stack == MAX_STACK)
+		panic("can't push onto full stack");
+	stack[in_stack++] = x;
+}
 
-int unix_gc_free=128;		/* GC slots free */
+extern inline unix_socket *pop_stack(void)
+{
+	if (in_stack == 0)
+		panic("can't pop empty gc stack");
+	return stack[--in_stack];
+}
+
+extern inline int empty_stack(void)
+{
+	return in_stack == 0;
+}
 
-void unix_gc_remove(struct file *fp)
+extern inline void maybe_mark_and_push(unix_socket *x)
 {
-	;
+	if (x->protinfo.af_unix.marksweep&MARKED)
+		return;
+	x->protinfo.af_unix.marksweep|=MARKED;
+	push_stack(x);
 }
 
-void unix_gc_add(struct sock *sk, struct file *fp)
+
+/* The external entry point: unix_gc() */
+
+void unix_gc(void)
 {
-	;
+	static int in_unix_gc=0;
+	unix_socket *s;
+	unix_socket *next;
+	
+	/*
+	 *	Avoid a recursive GC.
+	 */
+
+	if(in_unix_gc)
+		return;
+	in_unix_gc=1;
+	
+	stack=(unix_socket **)get_free_page(GFP_KERNEL);
+	
+	/*
+	 *	Assume everything is now unmarked 
+	 */
+
+	/* Invariant to be maintained:
+		- everything marked is either:
+		-- (a) on the stack, or
+		-- (b) has all of its children marked
+		- everything on the stack is always marked
+		- nothing is ever pushed onto the stack twice, because:
+		-- nothing previously marked is ever pushed on the stack
+	 */
+
+	/*
+	 *	Push root set
+	 */
+
+	for(s=unix_socket_list;s!=NULL;s=s->next)
+	{
+		/*
+		 *	If all instances of the descriptor are not
+		 *	in flight we are in use.
+		 */
+		if(s->socket && s->socket->file && s->socket->file->f_count > s->protinfo.af_unix.inflight)
+			maybe_mark_and_push(s);
+	}
+
+	/*
+	 *	Mark phase 
+	 */
+
+	while (!empty_stack())
+	{
+		unix_socket *x = pop_stack();
+		unix_socket *f=NULL,*sk;
+		struct sk_buff *skb;
+tail:		
+		skb=skb_peek(&x->receive_queue);
+		
+		/*
+		 *	Loop through all but first born 
+		 */
+		
+		while(skb && skb != (struct sk_buff *)&x->receive_queue)
+		{
+			/*
+			 *	Do we have file descriptors ?
+			 */
+			if(skb->h.filp)
+			{
+				/*
+				 *	Process the descriptors of this socket
+				 */
+				int nfd=*(int *)skb->h.filp;
+				struct file **fp=(struct file **)(skb->h.filp+sizeof(int));
+				while(nfd--)
+				{
+					/*
+					 *	Get the socket the fd matches if
+					 *	it indeed does so
+					 */
+					if((sk=unix_get_socket(*fp++))!=NULL)
+					{
+						/*
+						 *	Remember the first, mark the
+						 *	rest.
+						 */
+						if(f==NULL)
+							f=sk;
+						else
+							maybe_mark_and_push(sk);
+					}
+				}
+			}
+			skb=skb->next;
+		}
+		/*
+		 *	Handle first born specially 
+		 */
+
+		if (f) 
+		{
+			if (!(f->protinfo.af_unix.marksweep&MARKED))
+			{
+				f->protinfo.af_unix.marksweep|=MARKED;
+				x=f;
+				f=NULL;
+				goto tail;
+			}
+		}
+	}
+
+	/*
+	 *	Sweep phase.  NOTE: this part dominates the time complexity 
+	 */
+
+	for(s=unix_socket_list;s!=NULL;s=next)
+	{
+		next=s->next;
+		if (!(s->protinfo.af_unix.marksweep&MARKED))
+		{
+			/*
+			 *	We exist only in the passing tree of sockets
+			 *	that is no longer connected to active descriptors
+			 *	Time to die..
+			 */
+			if(s->socket && s->socket->file)
+				close_fp(s->socket->file);
+		}
+		else
+			s->protinfo.af_unix.marksweep&=~MARKED;	/* unmark everything for next collection */
+	}
+	
+	in_unix_gc=0;
+	
+	free_page((long)stack);
 }
diff -u --recursive --new-file v1.3.77/linux/scripts/Configure linux/scripts/Configure
--- v1.3.77/linux/scripts/Configure	Fri Feb 23 13:54:44 1996
+++ linux/scripts/Configure	Mon Mar 25 08:58:28 1996
@@ -9,7 +9,7 @@
 #
 # Please send comments / questions / bug fixes to raymondc@microsoft.com.
 #
-#              ***** IMPORTANT COMPATABILITY NOTE ****
+#              ***** IMPORTANT COMPATIBILITY NOTE ****
 # If configuration changes are made which might adversely effect 
 # Menuconfig or xconfig, please notify the respective authors so that 
 # those utilities can be updated in parallel.
@@ -39,6 +39,9 @@
 #
 # 150296 Dick Streefland (dicks@tasking.nl) - report new configuration
 # items and ask for a value even when doing a "make oldconfig"
+#
+# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is
+# chosen for an item, define the macro <option_name>_MODULE
 
 #
 # Make sure we're really running bash.
@@ -141,6 +144,7 @@
 	 "m")
 		echo "$1=m" >>$CONFIG
 		echo "#undef  $1" >>$CONFIG_H
+		echo "#define $1_MODULE 1" >>$CONFIG_H
 		;;
 
 	 "n")
diff -u --recursive --new-file v1.3.77/linux/scripts/Menuconfig linux/scripts/Menuconfig
--- v1.3.77/linux/scripts/Menuconfig	Wed Mar 20 11:00:01 1996
+++ linux/scripts/Menuconfig	Sun Mar 24 20:02:36 1996
@@ -40,6 +40,180 @@
 #
 set -h
 
+
+
+
+
+#
+# Load the functions used by the config.in files.
+#
+# I do this because these functions must be redefined depending
+# on whether they are being called for interactive use or for
+# saving a configuration to a file.
+#
+# Thank the heavens bash supports nesting function definitions.
+#
+load_functions () {
+
+#
+# Additional comments
+#
+function comment () {
+	comment_ctr=$[ comment_ctr + 1 ]
+	echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
+}
+
+#
+# Don't need this yet, but we don't want to puke either.
+#
+function define_bool () {
+	:	
+}
+
+#
+# Create a boolean (Yes/No) function for our current menu
+# which calls our local bool function.
+#
+function bool () {
+	eval $2=\${$2:-'n'}  x=\$$2
+
+	case $x in
+	y|m) yes='ON' no='OFF' flag="*"
+	   ;;
+	n) yes='OFF' no='ON' flag=" "
+	   ;;
+	esac
+
+	echo -ne "'$2' '($flag) $1' " >>MCmenu
+
+	echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \
+		>>MCradiolists
+}
+
+#
+# Create a tristate (Yes/No/Module) radiolist function
+# which calls our local tristate function.
+#
+# Collapses to a boolean (Yes/No) if module support is disabled.
+#
+function tristate () {
+	if [ "$CONFIG_MODULES" != "y" ]
+	then
+		bool "$1" "$2"
+	else
+		eval $2=\${$2:-'n'}  x=\$$2
+	
+		case $x in
+		y) yes='ON'  no='OFF' module='OFF' flag="*"
+   		;;
+		m) yes='OFF' no='OFF' module='ON' flag="M"
+   		;;
+		*) yes='OFF' no='ON'  module='OFF' flag=" "
+   		;;
+		esac
+	
+		echo -ne "'$2' '<$flag> $1' " >>MCmenu
+	
+		echo -e "
+		function $2 () { \
+			l_tristate '$1' '$yes' '$no' '$module' '$2'
+		}"  >>MCradiolists
+	fi
+}
+
+#
+# Create a tristate radiolist function which is dependent on
+# another kernel configuration option.
+#
+# Quote from the original configure script:
+#
+#       If the option we depend upon is a module,
+#       then the only allowable options are M or N.  If Y, then
+#       this is a normal tristate.  This is used in cases where modules
+#       are nested, and one module requires the presence of something
+#       else in the kernel.
+#
+function dep_tristate () {
+	if [ "$CONFIG_MODULES" != "y" ]
+	then
+		bool "$1" "$2"
+	else
+		if  eval [ "_$3" != "_m" ]
+		then
+			tristate "$1" "$2" $3
+		else
+			mod_bool "$1" "$2"
+		fi
+	fi
+}
+
+#
+# Add a menu item which will call our local int function.
+# 
+function int () {
+	eval $2=\${$2:-"$3"} x=\$$2
+
+	echo -ne "'$2' '($x) $1' " >>MCmenu
+
+	echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists
+}
+
+#
+# Add a menu item which will call our local int function.
+# 
+function hex () {
+	eval $2=\${$2:-"$3"} x=\${$2##*[x,X]}
+
+	echo -ne "'$2' '($x) $1' " >>MCmenu
+
+	echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists
+}
+
+#
+# Add a menu item which will call our local One-of-Many choice list.
+#
+function choice () {
+	#
+	# Need to remember params cause the're gonna get reset.
+	#
+	title=$1
+	choices=$2
+	default=$3
+	current=
+
+	#
+	# Find out if one of the choices is already set.
+	# If it's not then make it the default.
+	#
+	set -- $choices
+	firstchoice=$2
+
+	while [ -n "$2" ]
+	do
+		if eval [ "_\$$2" = "_y" ]
+		then
+			current=$1
+			break
+		fi
+		shift ; shift
+	done
+
+	: ${current:=$default}
+
+	echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
+
+	echo -e "
+	function $firstchoice () {
+		l_choice '$title' \"$choices\" $current
+	}\n" >>MCradiolists
+}
+
+} # END load_functions()
+
+
+
+
+
 #
 # Extract available help for an option from Configure.help
 # and send it to standard output.
@@ -108,21 +282,6 @@
 }
 
 #
-# Additional comments
-#
-function comment () {
-	comment_ctr=$[ comment_ctr + 1 ]
-	echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
-}
-
-#
-# Don't need this yet, but we don't want to puke either.
-#
-function define_bool () {
-	:	
-}
-
-#
 # Add a submenu option to the menu currently under construction.
 #
 function submenu () {
@@ -146,27 +305,6 @@
 	$MAKE -C drivers/sound config
 }
 
-
-#
-# Create a boolean (Yes/No) function for our current menu
-# which calls our local bool function.
-#
-function bool () {
-	eval $2=\${$2:-'n'}  x=\$$2
-
-	case $x in
-	y|m) yes='ON' no='OFF' flag="*"
-	   ;;
-	n) yes='OFF' no='ON' flag=" "
-	   ;;
-	esac
-
-	echo -ne "'$2' '($flag) $1' " >>MCmenu
-
-	echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \
-		>>MCradiolists
-}
-
 #
 # Handle a boolean (Yes/No) option.
 #
@@ -202,7 +340,7 @@
 	   ;;
 	esac
 
-	echo -ne "'$2' '($flag) $1' " >>MCmenu
+	echo -ne "'$2' '<$flag> $1' " >>MCmenu
 
 	echo -e "function $2 () { l_mod_bool '$1' '$module' '$no' '$2' }\n" \
 		>>MCradiolists
@@ -232,37 +370,6 @@
 }
 
 #
-# Create a tristate (Yes/No/Module) radiolist function
-# which calls our local tristate function.
-#
-# Collapses to a boolean (Yes/No) if module support is disabled.
-#
-function tristate () {
-	if [ "$CONFIG_MODULES" != "y" ]
-	then
-		bool "$1" "$2"
-	else
-		eval $2=\${$2:-'n'}  x=\$$2
-	
-		case $x in
-		y) yes='ON'  no='OFF' module='OFF' flag="*"
-   		;;
-		m) yes='OFF' no='OFF' module='ON' flag="M"
-   		;;
-		*) yes='OFF' no='ON'  module='OFF' flag=" "
-   		;;
-		esac
-	
-		echo -ne "'$2' '($flag) $1' " >>MCmenu
-	
-		echo -e "
-		function $2 () { \
-			l_tristate '$1' '$yes' '$no' '$module' '$2'
-		}"  >>MCradiolists
-	fi
-}
-
-#
 # Handle a tristate (Yes/No/Module) option.
 #
 function l_tristate () {
@@ -286,43 +393,6 @@
 }
 
 #
-# Create a tristate radiolist function which is dependent on
-# another kernel configuration option.
-#
-# Quote from the original configure script:
-#
-#       If the option we depend upon is a module,
-#       then the only allowable options are M or N.  If Y, then
-#       this is a normal tristate.  This is used in cases where modules
-#       are nested, and one module requires the presence of something
-#       else in the kernel.
-#
-function dep_tristate () {
-	if [ "$CONFIG_MODULES" != "y" ]
-	then
-		bool "$1" "$2"
-	else
-		if  eval [ "_$3" != "_m" ]
-		then
-			tristate "$1" "$2" $3
-		else
-			mod_bool "$1" "$2"
-		fi
-	fi
-}
-
-#
-# Add a menu item which will call our local int function.
-# 
-function int () {
-	eval $2=\${$2:-"$3"} x=\$$2
-
-	echo -ne "'$2' '($x) $1' " >>MCmenu
-
-	echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists
-}
-
-#
 # Create a dialog for entering an integer into a kernel option.
 #
 function l_int () {
@@ -354,18 +424,6 @@
 	done
 }
 
-
-#
-# Add a menu item which will call our local int function.
-# 
-function hex () {
-	eval $2=\${$2:-"$3"} x=\${$2##*[x,X]}
-
-	echo -ne "'$2' '($x) $1' " >>MCmenu
-
-	echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists
-}
-
 #
 # Create a dialog for entering a hexidecimal into a kernel option.
 #
@@ -400,45 +458,8 @@
 }
 
 #
-# Add a menu item which will call our local One-of-Many choice list.
+# Handle a on-of-many choice list.
 #
-function choice () {
-	#
-	# Need to remember params cause the're gonna get reset.
-	#
-	title=$1
-	choices=$2
-	default=$3
-	current=
-
-	#
-	# Find out if one of the choices is already set.
-	# If it's not then make it the default.
-	#
-	set -- $choices
-	firstchoice=$2
-
-	while [ -n "$2" ]
-	do
-		if eval [ "_\$$2" = "_y" ]
-		then
-			current=$1
-			break
-		fi
-		shift ; shift
-	done
-
-	: ${current:=$default}
-
-	echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
-
-	echo -e "
-	function $firstchoice () {
-		l_choice '$title' \"$choices\" $current
-	}\n" >>MCradiolists
-}
-
-
 function l_choice () {
 	#
 	# Need to remember params cause the're gonna get reset.
@@ -590,7 +611,6 @@
 	echo 'default=$1' >>MCmenu0
 	echo "menu_name 'Main Menu'" >>MCmenu0
 
-
 	if [ "_$single_menu_mode" = "_TRUE" ]
 	then
 		parser2
@@ -598,6 +618,10 @@
 		parser1
 	fi
 
+	echo "comment ''"	>>MCmenu0
+	echo "g_alt_config" 	>>MCmenu0
+	echo "s_alt_config" 	>>MCmenu0
+
 	echo "}" >>MCmenu0
 
 	#
@@ -644,7 +668,8 @@
 			default="${selection%% *}"
 
 			case "$selection" in
-			*"-->"*) show_readme ;;
+			*"-->"*|\
+			*"alt_config"*) show_readme ;;
 			*)	 eval help $selection ;;
 			esac
 			;;
@@ -656,16 +681,155 @@
 }
 
 #
+# Create a menu item to load an alternate configuration file.
+#
+g_alt_config () {
+	echo -n "get_alt_config 'Load  an Alternate Configuration File' "\
+		>>MCmenu
+}
+
+#
+# Get alternate config file name and load the 
+# configuration from it.
+#
+get_alt_config () {
+	while true
+	do
+		ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}"
+
+		$DIALOG --backtitle "$backtitle" \
+			--inputbox "\
+Enter the name of the configuration file you wish to load.  \
+Accept the name shown to restore the configuration you \
+last retrieved.  Leave blank to abort."\
+			11 55 "$ALT_CONFIG" 2>MCdialog.out
+
+		if [ "$?" = "0" ]
+		then
+			ALT_CONFIG=`cat MCdialog.out`
+
+			[ "_" = "_$ALT_CONFIG" ] && break
+
+			if [ -r "$ALT_CONFIG" ]
+			then
+				load_config_file "$ALT_CONFIG"
+				break
+			else
+				echo -ne "\007"
+				$DIALOG	--backtitle "$backtitle" \
+					--infobox "File does not exit!"  3 38
+				sleep 2
+			fi
+		else
+			cat <<EOM >help.out
+
+For various reasons, one may wish to keep several different kernel
+configurations available on a single machine.  
+
+If you have saved a previous configuration in a file other than the
+kernel's default, entering the name of the file here will allow you
+to modify that configuration.
+
+If you are uncertain, then you have probably never used alternate 
+configuration files.  You should therefor leave this blank to abort.
+
+EOM
+			$DIALOG	--backtitle "$backtitle"\
+				--title "Load Alternate Configuration"\
+				--textbox help.out $LINES $COLS
+		fi
+	done
+
+	rm -f help.out MCdialog.out
+}
+
+#
+# Create a menu item to store an alternate config file.
+#
+s_alt_config () {
+	echo -n "save_alt_config 'Store an Alternate Configuration File' "\
+		 >>MCmenu
+}
+
+#
+# Get an alternate config file name and save the current
+# configuration to it.
+#
+save_alt_config () {
+	while true
+	do
+		$DIALOG --backtitle "$backtitle" \
+			--inputbox "\
+Enter a filename to which this configuration should be saved \
+as an alternate.  Leave blank to abort."\
+			10 55 "$ALT_CONFIG" 2>MCdialog.out
+
+		if [ "$?" = "0" ]
+		then
+			ALT_CONFIG=`cat MCdialog.out`
+
+			[ "_" = "_$ALT_CONFIG" ] && break
+			
+			if touch $ALT_CONFIG 2>/dev/null
+			then
+				save_configuration $ALT_CONFIG
+				load_functions  ## RELOAD
+				break
+			else
+				echo -ne "\007"
+				$DIALOG	--backtitle "$backtitle" \
+					--infobox "Can't create file!  Probably a nonexistent directory." 3 60
+				sleep 2
+			fi
+		else
+			cat <<EOM >help.out
+
+For various reasons, one may wish to keep different kernel
+configurations available on a single machine.  
+
+Entering a file name here will allow you to later retrieve, modify
+and use the current configuration as an alternate to whatever 
+configuration options you have selected at that time.
+
+If you are uncertain what all this means then you should probably
+leave this blank.
+EOM
+			$DIALOG	--backtitle "$backtitle"\
+				--title "Store Alternate Configuration"\
+				--textbox help.out $LINES $COLS
+		fi
+	done
+
+	rm -f help.out MCdialog.out
+}
+
+#
+# Load config options from a file.
+# Converts all "# OPTION is not set" lines to "OPTION=" lines
+#
+function load_config_file () {
+	awk '
+	  /# .* is not set.*/ { printf("%s=\n", $2) }
+	! /# .* is not set.*/ { print }
+	' $1 >.tmpconfig
+
+	source .tmpconfig
+	rm -f .tmpconfig
+}
+
+#
 # Just what it says.
 #
 save_configuration () {
 	${DIALOG} --backtitle "$backtitle" \
-		  --infobox "Saving your new kernel configuration..."  3 43
+		  --infobox "Saving your kernel configuration..."  3 40
 
 	#
 	# Now, let's redefine the configuration functions for final
 	# output to the config files.
 	#
+	# Nested function definitions, YIPEE!
+	#
 	function bool () {
 		eval define_bool "$2" "\${$2:-n}"
 	}
@@ -721,7 +885,7 @@
                 	;;
 
          	n)
-                	echo "# $1 is not set"	>>$CONFIG
+			echo "# $1 is not set"	>>$CONFIG
                 	echo "#undef  $1"	>>$CONFIG_H
                 	;;
         	esac
@@ -787,6 +951,9 @@
 		fi
 	}
 
+	DEF_CONFIG="${1:-.config}"
+	DEF_CONFIG_H="include/linux/autoconf.h"
+
 	CONFIG=.tmpconfig
 	CONFIG_H=.tmpconfig.h
 
@@ -802,24 +969,30 @@
 	
 	if . $CONFIG_IN >>.menuconfig.log 2>&1
 	then
-		#
-		# Create the sound driver's config files for cards
-		# Which are compatible with the new config method.
-		#
-		if [ "_$CONFIG_TRIX"   != "_y" -a\
-		     "_$CONFIG_PSS"    != "_y" -a\
-		     "_$CONFIG_SMWAVE" != "_y"    ]
+		if [ "$DEF_CONFIG" = ".config" ]
 		then
-			make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1
+			#
+			# Create the sound driver's config files for cards
+			# Which are compatible with the new config method.
+			#
+			if [ "_$CONFIG_TRIX"   != "_y" -a\
+			     "_$CONFIG_PSS"    != "_y" -a\
+			     "_$CONFIG_SMWAVE" != "_y"   ]
+			then
+				make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1
+			fi
+
+			mv $CONFIG_H $DEF_CONFIG_H
 		fi
 
-		if [ -f .config ]
+		if [ -f "$DEF_CONFIG" ]
 		then
-			rm -f .config.old
-			mv .config .config.old
+			rm -f ${DEF_CONFIG}.old
+			mv $DEF_CONFIG ${DEF_CONFIG}.old
 		fi
-		mv .tmpconfig .config
-		mv .tmpconfig.h include/linux/autoconf.h
+
+		mv $CONFIG $DEF_CONFIG
+			
 		return 0
 	else
 		return 1
@@ -856,18 +1029,20 @@
 	
 
 menu_instructions="\
-Arrow keys navigate the menu.  \
+The Arrow keys navigate the menu.  \
 Highlighted letters are hotkeys.  \
-Select an item with <Space Bar> or <Enter>.  \
-When finished press <Esc><Esc> or <X>.  \
-A (*) marks an option to be compiled into the kernel.  \
-An (M) marks an option to be compiled as a module."
+Press the <Space Bar> to select an item.  \
+Press <Esc><Esc> to exit.  \
+Press <?> for Help.  \
+(*) options will be compiled into the kernel.  \
+(M) options will be modules.  \
+< > marks module capable options."
 
 radiolist_instructions="\
 Use the arrow keys to navigate this window or \
 press the hotkey of the item you wish to select \
 followed by the <SPACE BAR>.
-Press <H> for additional information about this option."
+Press <?> for additional information about this option."
 
 inputbox_instructions_int="\
 Please enter a decimal value between 1 and 9999. \
@@ -886,15 +1061,10 @@
 
 trap "cleanup ; rm -f .menuconfig ; exit 1" 1 2 15
 
+
 #
 # Locate default files.
 #
-DEFAULT=""
-if [ "$1" = "-d" ] ; then
-	DEFAULT="-d"
-	shift
-fi
-
 CONFIG_IN=./config.in
 if [ "$1" != "" ] ; then
 	CONFIG_IN=$1
@@ -905,7 +1075,8 @@
   DEFAULTS=.config
 fi
 
-if [ -f $DEFAULTS ]; then
+if [ -f $DEFAULTS ]
+then
   echo "#"
   echo "# Using defaults found in" $DEFAULTS
   echo "#"
@@ -916,10 +1087,10 @@
   echo "#"
 fi
 
+
 # Fresh new log.
 >.menuconfig.log
 
-
 $DIALOG	--backtitle "$backtitle" \
 	--infobox "Preparing configuration scripts..." 3 40
 
@@ -947,6 +1118,9 @@
 
 	echo "# $kernel_version" >.menuconfig
 fi
+
+# Load the functions used by the config.in files.
+load_functions
 
 #
 # Read config.in files and parse them into one shell function per menu.
diff -u --recursive --new-file v1.3.77/linux/scripts/README.Menuconfig linux/scripts/README.Menuconfig
--- v1.3.77/linux/scripts/README.Menuconfig	Wed Mar 20 11:00:01 1996
+++ linux/scripts/README.Menuconfig	Sun Mar 24 20:02:36 1996
@@ -78,6 +78,22 @@
 you may look in the file /usr/src/linux/.menuconfig.log for
 information which may help you determine the cause.
 
+Alternate Configuration Files
+-----------------------------
+Menuconfig supports the use of alternate configuration files for
+those who, for various reasons, find it necessary to switch 
+between different kernel configurations.
+
+At the end of the main menu you will find two options.  One is
+for saving the current configuration to a file of your choosing.
+The other option is for loading a previously saved alternate
+configuration.
+
+Even if you don't use alternate configuration files, but you 
+find during a Menuconfig session that you have completely messed
+up your settings, you may use the "Load Alternate..." option to
+restore your previously saved settings from ".config" without 
+restarting Menuconfig.
 
 Other information
 -----------------
diff -u --recursive --new-file v1.3.77/linux/scripts/lxdialog/inputbox.c linux/scripts/lxdialog/inputbox.c
--- v1.3.77/linux/scripts/lxdialog/inputbox.c	Wed Feb  7 15:11:46 1996
+++ linux/scripts/lxdialog/inputbox.c	Sun Mar 24 20:02:36 1996
@@ -27,14 +27,15 @@
  *  Print the termination buttons
  */
 static void
-print_buttons(WINDOW *dialog, int height, int width, int okval, int cancelval)
+print_buttons(WINDOW *dialog, int height, int width, int selected)
 {
     int x = width / 2 - 11;
     int y = height - 2;
 
-    print_button (dialog, "  Ok  ", y, x, okval);
-    print_button (dialog, " Help ", y, x + 14, cancelval);
+    print_button (dialog, "  Ok  ", y, x, selected==0);
+    print_button (dialog, " Help ", y, x + 14, selected==1);
 
+    wmove(dialog, y, x+1+14*selected);
     wrefresh(dialog);
 }
 
@@ -86,7 +87,7 @@
     draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
 	      border_attr, dialog_attr);
 
-    print_buttons(dialog, height, width, TRUE, FALSE);
+    print_buttons(dialog, height, width, 0);
 
     /* Set up the initial value */
     wmove (dialog, box_y, box_x);
@@ -180,17 +181,17 @@
 	    switch (button) {
 	    case -1:
 		button = 1;	/* Indicates "Cancel" button is selected */
-		print_buttons(dialog, height, width, FALSE, TRUE);
+		print_buttons(dialog, height, width, 1);
 		break;
 	    case 0:
 		button = -1;	/* Indicates input box is selected */
-		print_buttons(dialog, height, width, TRUE, FALSE);
+		print_buttons(dialog, height, width, 0);
 		wmove (dialog, box_y, box_x + input_x);
 		wrefresh (dialog);
 		break;
 	    case 1:
 		button = 0;	/* Indicates "OK" button is selected */
-		print_buttons(dialog, height, width, TRUE, FALSE);
+		print_buttons(dialog, height, width, 0);
 		break;
 	    }
 	    break;
@@ -200,15 +201,15 @@
 	    switch (button) {
 	    case -1:
 		button = 0;	/* Indicates "OK" button is selected */
-		print_buttons(dialog, height, width, TRUE, FALSE);
+		print_buttons(dialog, height, width, 0);
 		break;
 	    case 0:
 		button = 1;	/* Indicates "Cancel" button is selected */
-		print_buttons(dialog, height, width, FALSE, TRUE);
+		print_buttons(dialog, height, width, 1);
 		break;
 	    case 1:
 		button = -1;	/* Indicates input box is selected */
-		print_buttons(dialog, height, width, TRUE, FALSE);
+		print_buttons(dialog, height, width, 0);
 		wmove (dialog, box_y, box_x + input_x);
 		wrefresh (dialog);
 		break;
diff -u --recursive --new-file v1.3.77/linux/scripts/lxdialog/menubox.c linux/scripts/lxdialog/menubox.c
--- v1.3.77/linux/scripts/lxdialog/menubox.c	Wed Mar 20 11:00:01 1996
+++ linux/scripts/lxdialog/menubox.c	Sat Mar 23 19:57:09 1996
@@ -220,7 +220,7 @@
                        (items[(scroll+choice)*2][0] != ':'));
 
 	    if (key == KEY_UP || key == '-') {
-                if (choice < 6 && scroll) {
+                if (choice < 2 && scroll) {
 	            /* Scroll menu down */
                     scrollok (menu, TRUE);
                     wscrl (menu, -1);
@@ -238,7 +238,9 @@
 		print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
                                 (items[(scroll+choice)*2][0] != ':'));
 
-                if ((choice > 4) && (scroll + max_choice < item_no)) {
+                if ((choice > max_choice-3) &&
+                    (scroll + max_choice < item_no)
+                   ) {
 		    /* Scroll menu up */
 		    scrollok (menu, TRUE);
                     scroll (menu);
