diff -u --recursive --new-file v2.1.30/linux/Documentation/Changes linux/Documentation/Changes
--- v2.1.30/linux/Documentation/Changes	Tue Mar  4 10:25:22 1997
+++ linux/Documentation/Changes	Wed Apr  2 14:58:57 1997
@@ -26,7 +26,7 @@
 http://www.datanet.hu/generations/linux/Changes2.html is an
 English-language HTML version.
 
-Last updated: February 27, 1997.
+Last updated: April 1, 1997.
 Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
 
 Current Minimal Requirements
@@ -35,14 +35,13 @@
    Upgrade to at *least* these software revisions before thinking you've
 encountered a bug!
 
-- Kernel modules	 modutils-2.1.23
+- Kernel modules	 modutils-2.1.29-970320
 - Gnu C 		 2.7.2.1
-- Binutils		 2.7.0.3
+- Binutils		 2.7.0.9
 - Linux C Library	 5.4.23
 - Dynamic Linker (ld.so) 1.8.5
 - Linux C++ Library	 2.7.2.1
 - Procps		 1.01
-- SysVinit		 2.69
 - Mount                  2.5p
 - Net-tools              1.32-alpha
 - Kbd                    0.91
@@ -84,7 +83,14 @@
 Modules
 =======
 
-   You need to upgrade to modutils-2.1.23 for kernels 2.1.18 and later.
+   You need to upgrade to modutils-2.1.29-970320 for kernels 2.1.29 and
+later.
+
+Binutils
+========
+
+   If you upgrade binutils, please read its accompanying release notes
+to find out the proper way to upgrade it.
 
 Gnu C
 =====
@@ -113,6 +119,12 @@
 in some standard tools.  Check in /proc/net/rt_local to verify their
 presence.
 
+   To turn on IP forwarding, issue the following command:   echo 1 >
+/proc/sys/net/ipv4/ip_forwarding
+
+   To run bootpd, you'll need to issue the following command:   echo 1
+>/proc/sys/net/ipv4/ip_boot_agent
+
 RPM
 ===
 
@@ -123,7 +135,7 @@
 ======
 
    A new "stable" version of DOSEMU is available for 2.1.x kernels.
-Upgrade to 0.64.3 or later.
+Upgrade to 0.66.1 or later.
 
 Loadlin
 =======
@@ -163,12 +175,12 @@
 Binutils
 ========
 
-The 2.7.0.3 release:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.7.0.3.bin.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.7.0.3.bin.tar.gz
+The 2.7.0.9 release:
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.7.0.9.bin.tar.gz
+ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.7.0.9.bin.tar.gz
 Installation notes:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.7.0.3
-ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.7.0.3
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.7.0.9
+ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.7.0.9
 
 Gnu C
 =====
@@ -210,9 +222,8 @@
 Modules utilities
 =================
 
-The 2.1.23 release:
-ftp://tsx-11.mit.edu/pub/linux/sources/system/v2.1/modutils-2.1.23.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/kernel/v2.1/modutils-2.1.23.tar.gz
+The 2.1.29-970320 release:
+ftp://ftp.redhat.com/pub/alphabits/modutils-2.1.29-970320.tar.gz
 
 Procps utilities
 ================
@@ -237,9 +248,9 @@
 DOSEMU
 ======
 
-The 0.64.3.1 release:
-ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu0.64.3.1.tgz
-ftp://sunsite.unc.edu/pub/Linux/system/emulators/dosemu0.64.3.1.tgz
+The 0.66.1 release:
+ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu0.66.1.tgz
+ftp://sunsite.unc.edu/pub/Linux/system/emulators/dosemu0.66.1.tgz
 
 Loadlin
 =======
diff -u --recursive --new-file v2.1.30/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.30/linux/Documentation/Configure.help	Thu Mar 27 14:39:58 1997
+++ linux/Documentation/Configure.help	Wed Apr  2 14:57:17 1997
@@ -600,13 +600,6 @@
   have access to a machine on the Internet that has one of the
   programs lynx, netscape or Mosaic).
 
-Echo console messages on /dev/ttyS1
-CONFIG_SERIAL_ECHO
-  If you say Y here, all kernel messages that would usually go
-  to the console will also be sent to the device /dev/ttyS1 which
-  corresponds to a serial port; this could be useful if you attached
-  a terminal or printer to that port.
-
 Non-standard serial port support
 CONFIG_SERIAL_NONSTANDARD
   Say Y here if you have any non-standard serial boards --- boards
@@ -1533,11 +1526,12 @@
 Probe all LUNs on each SCSI device
 CONFIG_SCSI_MULTI_LUN
   If you have a SCSI device that supports more than one LUN (Logical
-  Unit Number), e.g. a CD jukebox, you should say Y here so that all
-  will be found by the SCSI driver. An SCSI device with multiple LUNs
-  acts logically like multiple SCSI devices. The vast majority of SCSI
-  devices have only one LUN, and so most people can say N here and
-  should in fact do so, because it is safer.
+  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
+  can say Y here to force the SCSI driver to probe for multiple LUNs. 
+  A SCSI device with multiple LUNs acts logically like multiple SCSI
+  devices.  The vast majority of SCSI devices have only one LUN, and
+  so most people can say N here and should in fact do so, because it
+  is safer.
 
 Verbose SCSI error reporting (kernel size +=12K)
 CONFIG_SCSI_CONSTANTS
@@ -1886,6 +1880,12 @@
   whenever you want). The module will be called ibmmca.o. If you want
   to compile it as a module, say M here and read
   Documentation/modules.txt.
+  Normally, all IBM MCA SCSI adapters are automatically detected. You
+  can completely override auto-detection by specifying
+  "ibmmcascsi=io1,io2,..." at the boot loader's command prompt or
+  "io_port=io1,io2,... scsi_id=id1,id2,..." as a parameter of insmod.
+  "io" and "id" are the I/O base address and the SCSI ID of each
+  adapter, respectively.
 
 Always IN2000 SCSI support
 CONFIG_SCSI_IN2000
@@ -3820,6 +3820,17 @@
   Documentation/modules.txt. The module will be called sysv.o. If you
   haven't heard about all of this before, it's safe to say N.
 
+Kernel automounter support (experimental)
+CONFIG_AUTOFS_FS
+  The automounter is a tool to automatically mount remote filesystems
+  on demand.  This implementation is partially kernel-based to reduce
+  overhead in the already-mounted case; this is unlike the BSD
+  automounter (amd), which is only in user space.  To use the
+  automounter you also need the user-space tools from
+  ftp.kernel.org:/pub/linux/daemons/autofs.  If you are not a part of
+  a fairly large, distributed network, you probably do not need an
+  automounter, and can say N here.
+
 BSD UFS filesystem support (read only)
 CONFIG_UFS_FS
   BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD
@@ -3935,6 +3946,19 @@
   and read Documentation/modules.txt.  If you don't know whether you
   need it, then you don't need it: say N.
 
+Virtual terminal
+CONFIG_VT
+  This includes support for a terminal device using display and
+  keyboard devices. Only people using embedded systems want to say N
+  here. Most say Y here.
+
+Console on virtual terminal
+CONFIG_VT_CONSOLE
+  If you enable this option, all kernel messages will be sent to the
+  device /dev/tty which corresponds to the virtual terminal you have
+  visible on your display. You should say Y here if you have no other
+  console device.
+
 Standard/generic serial support
 CONFIG_SERIAL
   This selects whether you want to include the driver for the standard
@@ -3953,6 +3977,16 @@
   system, try running gpm first.  Most people will say Y or M here, so
   that they can use serial mice, modems and similar devices connecting
   to the standard serial ports.
+
+Console on serial port
+CONFIG_SERIAL_CONSOLE
+  If you enable this option, all kernel messages will be sent to the
+  device /dev/ttyS1 which corresponds to a serial port; this could be
+  useful if you attached a terminal or printer to that port. You can
+  use this in combination with console on virtual terminal, in which
+  case you get the output on both serial and display. Most people say
+  N here so that they can use the serial port for modem, mouse or some
+  other device.
 
 Digiboard PC/Xx Support
 CONFIG_DIGI
diff -u --recursive --new-file v2.1.30/linux/MAINTAINERS linux/MAINTAINERS
--- v2.1.30/linux/MAINTAINERS	Thu Mar 27 14:39:58 1997
+++ linux/MAINTAINERS	Fri Mar 28 14:31:00 1997
@@ -418,6 +418,18 @@
 M:	jam@acm.org
 S:	Maintained
 
+KERNEL AUTOMOUNTER (AUTOFS)
+P:	H. Peter Anvin
+M:	hpa@zytor.com
+L:	linux-kernel@vger.rutgers.edu
+S:	Maintained
+
+DEVICE NUMBER REGISTRY
+P:	H. Peter Anvin
+M:	hpa@zytor.com
+L:	linux-kernel@vger.rutgers.edu
+S:	Maintained
+
 REST:
 P:	Linus Torvalds
 S:	Buried alive in diapers
diff -u --recursive --new-file v2.1.30/linux/Makefile linux/Makefile
--- v2.1.30/linux/Makefile	Thu Mar 27 14:39:58 1997
+++ linux/Makefile	Wed Apr  2 17:51:04 1997
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 30
+SUBLEVEL = 31
 
 ARCH = i386
 
diff -u --recursive --new-file v2.1.30/linux/Rules.make linux/Rules.make
--- v2.1.30/linux/Rules.make	Thu Mar 27 14:39:59 1997
+++ linux/Rules.make	Mon Mar 31 10:26:12 1997
@@ -44,6 +44,9 @@
 %.s: %.c
 	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -S $< -o $@
 
+%.i: %.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E $< > $@
+
 %.o: %.c
 	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
 
diff -u --recursive --new-file v2.1.30/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.1.30/linux/arch/alpha/config.in	Sun Aug  4 03:38:59 1996
+++ linux/arch/alpha/config.in	Thu Mar 27 14:36:38 1997
@@ -83,7 +83,6 @@
 	define_bool CONFIG_ALPHA_AVANTI y
 fi
 
-bool 'Echo console messages on /dev/ttyS0 (COM1)' CONFIG_SERIAL_ECHO
 if [ "$CONFIG_PCI" = "y" ]; then
   bool 'TGA Console Support' CONFIG_TGA_CONSOLE
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -u --recursive --new-file v2.1.30/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v2.1.30/linux/arch/alpha/defconfig	Tue Jan 14 16:46:07 1997
+++ linux/arch/alpha/defconfig	Thu Mar 27 14:36:38 1997
@@ -36,7 +36,6 @@
 CONFIG_ALPHA_EV5=y
 CONFIG_ALPHA_CIA=y
 CONFIG_ALPHA_SRM=y
-# CONFIG_SERIAL_ECHO is not set
 CONFIG_TGA_CONSOLE=y
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
@@ -203,6 +202,8 @@
 #
 # Character devices
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 CONFIG_SERIAL=y
 # CONFIG_DIGI is not set
 # CONFIG_CYCLADES is not set
diff -u --recursive --new-file v2.1.30/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c
--- v2.1.30/linux/arch/i386/boot/compressed/misc.c	Mon Jan 27 01:24:21 1997
+++ linux/arch/i386/boot/compressed/misc.c	Fri Mar 28 13:49:35 1997
@@ -74,24 +74,6 @@
 static void gzip_release(void **);
   
 /*
- * These are set up by the setup-routine at boot-time:
- */
-
-struct screen_info {
-	unsigned char  orig_x;
-	unsigned char  orig_y;
-	unsigned char  unused1[2];
-	unsigned short orig_video_page;
-	unsigned char  orig_video_mode;
-	unsigned char  orig_video_cols;
-	unsigned short unused2;
-	unsigned short orig_video_ega_bx;
-	unsigned short unused3;
-	unsigned char  orig_video_lines;
-	unsigned char  orig_video_isVGA;
-};
-
-/*
  * This is set up by the setup-routine at boot-time
  */
 #define EXT_MEM_K (*(unsigned short *)0x90002)
Binary files v2.1.30/linux/arch/i386/boot/map and linux/arch/i386/boot/map differ
diff -u --recursive --new-file v2.1.30/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.1.30/linux/arch/i386/defconfig	Thu Mar 27 14:39:59 1997
+++ linux/arch/i386/defconfig	Mon Mar 31 13:26:35 1997
@@ -167,6 +167,7 @@
 # CONFIG_SLIP is not set
 # CONFIG_TR is not set
 # CONFIG_LAPBETHER is not set
+# CONFIG_X25_ASY is not set
 
 #
 # ISDN subsystem
@@ -197,11 +198,14 @@
 # CONFIG_SYSV_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_AUTOFS_FS=y
 # CONFIG_UFS_FS is not set
 
 #
 # Character devices
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 CONFIG_SERIAL=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.1.30/linux/arch/i386/kernel/bios32.c	Mon Dec 23 09:25:31 1996
+++ linux/arch/i386/kernel/bios32.c	Mon Mar 31 12:52:24 1997
@@ -49,6 +49,9 @@
  * Dec 7, 1996  : Added support for direct configuration access of boards
  *      with Intel compatible access schemes (tsbogend@alpha.franken.de)
  *
+ * Feb 3, 1997  : Set internal functions to static, save/restore flags
+ *	avoid dead locks reading broken PCI BIOS, werner@suse.de 
+ *
  */
 
 #include <linux/config.h>
@@ -59,6 +62,7 @@
 
 #include <asm/page.h>
 #include <asm/segment.h>
+#include <asm/system.h>
 #include <asm/io.h>
 
 #define PCIBIOS_PCI_FUNCTION_ID 	0xb1XX
@@ -137,7 +141,7 @@
 /*
  * pointer to selected PCI access function table
  */
-struct pci_access *access_pci = NULL;
+static struct pci_access *access_pci = NULL;
 
 
 
@@ -151,7 +155,9 @@
 	unsigned long address;		/* %ebx */
 	unsigned long length;		/* %ecx */
 	unsigned long entry;		/* %edx */
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%edi)"
 		: "=a" (return_code),
 		  "=b" (address),
@@ -160,6 +166,7 @@
 		: "0" (service),
 		  "1" (0),
 		  "D" (&bios32_indirect));
+	restore_flags(flags);
 
 	switch (return_code) {
 		case 0:
@@ -187,11 +194,13 @@
 	unsigned char present_status;
 	unsigned char major_revision;
 	unsigned char minor_revision;
+	unsigned long flags;
 	int pack;
 
 	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
 		pci_indirect.address = pcibios_entry | PAGE_OFFSET;
 
+		save_flags(flags);
 		__asm__("lcall (%%edi)\n\t"
 			"jc 1f\n\t"
 			"xor %%ah, %%ah\n"
@@ -202,6 +211,7 @@
 			: "1" (PCIBIOS_PCI_BIOS_PRESENT),
 			  "D" (&pci_indirect)
 			: "bx", "cx");
+	restore_flags(flags);
 
 		present_status = (pack >> 16) & 0xff;
 		major_revision = (pack >> 8) & 0xff;
@@ -227,12 +237,14 @@
 }
 
 
-int pci_bios_find_class (unsigned int class_code, unsigned short index,
+static int pci_bios_find_class (unsigned int class_code, unsigned short index,
 	unsigned char *bus, unsigned char *device_fn)
 {
 	unsigned long bx;
 	unsigned long ret;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__ ("lcall (%%edi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -243,18 +255,21 @@
 		  "c" (class_code),
 		  "S" ((int) index),
 		  "D" (&pci_indirect));
+	restore_flags(flags);
 	*bus = (bx >> 8) & 0xff;
 	*device_fn = bx & 0xff;
 	return (int) (ret & 0xff00) >> 8;
 }
 
 
-int pci_bios_find_device (unsigned short vendor, unsigned short device_id,
+static int pci_bios_find_device (unsigned short vendor, unsigned short device_id,
 	unsigned short index, unsigned char *bus, unsigned char *device_fn)
 {
 	unsigned short bx;
 	unsigned short ret;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%edi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -266,17 +281,20 @@
 		  "d" (vendor),
 		  "S" ((int) index),
 		  "D" (&pci_indirect));
+	restore_flags(flags);
 	*bus = (bx >> 8) & 0xff;
 	*device_fn = bx & 0xff;
 	return (int) (ret & 0xff00) >> 8;
 }
 
-int pci_bios_read_config_byte(unsigned char bus,
+static int pci_bios_read_config_byte(unsigned char bus,
 	unsigned char device_fn, unsigned char where, unsigned char *value)
 {
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%esi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -287,15 +305,18 @@
 		  "b" (bx),
 		  "D" ((long) where),
 		  "S" (&pci_indirect));
+	restore_flags(flags);
 	return (int) (ret & 0xff00) >> 8;
 }
 
-int pci_bios_read_config_word (unsigned char bus,
+static int pci_bios_read_config_word (unsigned char bus,
 	unsigned char device_fn, unsigned char where, unsigned short *value)
 {
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%esi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -306,15 +327,18 @@
 		  "b" (bx),
 		  "D" ((long) where),
 		  "S" (&pci_indirect));
+	restore_flags(flags);
 	return (int) (ret & 0xff00) >> 8;
 }
 
-int pci_bios_read_config_dword (unsigned char bus,
+static int pci_bios_read_config_dword (unsigned char bus,
 	unsigned char device_fn, unsigned char where, unsigned int *value)
 {
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%esi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -325,15 +349,18 @@
 		  "b" (bx),
 		  "D" ((long) where),
 		  "S" (&pci_indirect));
+	restore_flags(flags);
 	return (int) (ret & 0xff00) >> 8;
 }
 
-int pci_bios_write_config_byte (unsigned char bus,
+static int pci_bios_write_config_byte (unsigned char bus,
 	unsigned char device_fn, unsigned char where, unsigned char value)
 {
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%esi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -344,15 +371,18 @@
 		  "b" (bx),
 		  "D" ((long) where),
 		  "S" (&pci_indirect));
+	restore_flags(flags);
 	return (int) (ret & 0xff00) >> 8;
 }
 
-int pci_bios_write_config_word (unsigned char bus,
+static int pci_bios_write_config_word (unsigned char bus,
 	unsigned char device_fn, unsigned char where, unsigned short value)
 {
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%esi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -363,15 +393,18 @@
 		  "b" (bx),
 		  "D" ((long) where),
 		  "S" (&pci_indirect));
+	restore_flags(flags);
 	return (int) (ret & 0xff00) >> 8;
 }
 
-int pci_bios_write_config_dword (unsigned char bus,
+static int pci_bios_write_config_dword (unsigned char bus,
 	unsigned char device_fn, unsigned char where, unsigned int value)
 {
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
 
+	save_flags(flags);
 	__asm__("lcall (%%esi)\n\t"
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
@@ -382,13 +415,14 @@
 		  "b" (bx),
 		  "D" ((long) where),
 		  "S" (&pci_indirect));
+	restore_flags(flags);
 	return (int) (ret & 0xff00) >> 8;
 }
 
 /*
  * function table for BIOS32 access
  */
-struct pci_access pci_bios_access = {
+static struct pci_access pci_bios_access = {
       pci_bios_find_device,
       pci_bios_find_class,
       pci_bios_read_config_byte,
@@ -405,23 +439,27 @@
  * Given the vendor and device ids, find the n'th instance of that device
  * in the system.  
  */
-int pci_direct_find_device (unsigned short vendor, unsigned short device_id,
+static int pci_direct_find_device (unsigned short vendor, unsigned short device_id,
 			   unsigned short index, unsigned char *bus,
 			   unsigned char *devfn)
 {
     unsigned int curr = 0;
     struct pci_dev *dev;
+    unsigned long flags;
 
+    save_flags(flags);
     for (dev = pci_devices; dev; dev = dev->next) {
 	if (dev->vendor == vendor && dev->device == device_id) {
 	    if (curr == index) {
 		*devfn = dev->devfn;
 		*bus = dev->bus->number;
+		restore_flags(flags);
 		return PCIBIOS_SUCCESSFUL;
 	    }
 	    ++curr;
 	}
     }
+    restore_flags(flags);
     return PCIBIOS_DEVICE_NOT_FOUND;
 }
 
@@ -430,22 +468,26 @@
  * Given the class, find the n'th instance of that device
  * in the system.
  */
-int pci_direct_find_class (unsigned int class_code, unsigned short index,
+static int pci_direct_find_class (unsigned int class_code, unsigned short index,
 			  unsigned char *bus, unsigned char *devfn)
 {
     unsigned int curr = 0;
     struct pci_dev *dev;
+    unsigned long flags;
 
+    save_flags(flags);
     for (dev = pci_devices; dev; dev = dev->next) {
 	if (dev->class == class_code) {
 	    if (curr == index) {
 		*devfn = dev->devfn;
 		*bus = dev->bus->number;
+		restore_flags(flags);
 		return PCIBIOS_SUCCESSFUL;
 	    }
 	    ++curr;
 	}
     }
+    restore_flags(flags);
     return PCIBIOS_DEVICE_NOT_FOUND;
 }
 
@@ -454,9 +496,12 @@
  */
 #define CONFIG_CMD(bus, device_fn, where)   (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
 
-int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn,
+static int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn,
 			       unsigned char where, unsigned char *value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
     switch (where & 3) {
 	case 0: *value = inb(0xCFC);
@@ -468,49 +513,70 @@
 	case 3: *value = inb(0xCFF);
 		break;
     }
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf1_read_config_word (unsigned char bus,
+static int pci_conf1_read_config_word (unsigned char bus,
     unsigned char device_fn, unsigned char where, unsigned short *value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);    
     if (where & 2)
     	*value = inw(0xCFE);
     else
     	*value = inw(0xCFC);
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;    
 }
 
-int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn, 
+static int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn, 
 				 unsigned char where, unsigned int *value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
     *value = inl(0xCFC);
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;    
 }
 
-int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn, 
+static int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn, 
 				 unsigned char where, unsigned char value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);    
     outb(value, 0xCFC);
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn, 
+static int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn, 
 				 unsigned char where, unsigned short value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
     outw(value, 0xCFC);
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn, 
+static int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn, 
 				  unsigned char where, unsigned int value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
     outl(value, 0xCFC);
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
@@ -519,7 +585,7 @@
 /*
  * functiontable for type 1
  */
-struct pci_access pci_direct_conf1 = {
+static struct pci_access pci_direct_conf1 = {
       pci_direct_find_device,
       pci_direct_find_class,
       pci_conf1_read_config_byte,
@@ -536,69 +602,93 @@
 #define IOADDR(devfn, where)   ((0xC000 | ((devfn & 0x78) << 5)) + where)
 #define FUNC(devfn)            (((devfn & 7) << 1) | 0xf0)
 
-int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn, 
+static int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn, 
 			       unsigned char where, unsigned char *value)
 {
+    unsigned long flags;
+
     if (device_fn & 0x80)
 	return PCIBIOS_DEVICE_NOT_FOUND;
+    save_flags(flags);
     outb (FUNC(device_fn), 0xCF8);
     outb (bus, 0xCFA);
     *value = inb(IOADDR(device_fn,where));
     outb (0, 0xCF8);
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn, 
+static int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn, 
 				unsigned char where, unsigned short *value)
 {
+    unsigned long flags;
+
     if (device_fn & 0x80)
 	return PCIBIOS_DEVICE_NOT_FOUND;
+    save_flags(flags);
     outb (FUNC(device_fn), 0xCF8);
     outb (bus, 0xCFA);
     *value = inw(IOADDR(device_fn,where));
-    outb (0, 0xCF8);    
+    outb (0, 0xCF8);
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn, 
+static int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn, 
 				 unsigned char where, unsigned int *value)
 {
+    unsigned long flags;
+
     if (device_fn & 0x80)
 	return PCIBIOS_DEVICE_NOT_FOUND;
+    save_flags(flags);
     outb (FUNC(device_fn), 0xCF8);
     outb (bus, 0xCFA);
     *value = inl (IOADDR(device_fn,where));    
     outb (0, 0xCF8);    
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn, 
+static int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn, 
 				 unsigned char where, unsigned char value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outb (FUNC(device_fn), 0xCF8);
     outb (bus, 0xCFA);
     outb (value, IOADDR(device_fn,where));
     outb (0, 0xCF8);    
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn, 
+static int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn, 
 				 unsigned char where, unsigned short value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outb (FUNC(device_fn), 0xCF8);
     outb (bus, 0xCFA);
     outw (value, IOADDR(device_fn,where));
     outb (0, 0xCF8);    
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
-int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn, 
+static int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn, 
 				  unsigned char where, unsigned int value)
 {
+    unsigned long flags;
+
+    save_flags(flags);
     outb (FUNC(device_fn), 0xCF8);
     outb (bus, 0xCFA);
     outl (value, IOADDR(device_fn,where));    
     outb (0, 0xCF8);    
+    restore_flags(flags);
     return PCIBIOS_SUCCESSFUL;
 }
 
@@ -608,7 +698,7 @@
 /*
  * functiontable for type 2
  */
-struct pci_access pci_direct_conf2 = {
+static struct pci_access pci_direct_conf2 = {
       pci_direct_find_device,
       pci_direct_find_class,
       pci_conf2_read_config_byte,
@@ -620,9 +710,12 @@
 };
 
 
-struct pci_access *check_direct_pci(void)
+static struct pci_access *check_direct_pci(void)
 {
     unsigned int tmp;
+    unsigned long flags;
+
+    save_flags(flags);
 
     /*
      * check if configuration type 1 works
@@ -632,6 +725,7 @@
     outl (0x80000000, 0xCF8);
     if (inl (0xCF8) == 0x80000000) {
 	outl (tmp, 0xCF8);
+	restore_flags(flags);
 	printk("pcibios_init: Using configuration type 1\n");
 	return &pci_direct_conf1;
     }
@@ -644,9 +738,11 @@
     outb (0x00, 0xCF8);
     outb (0x00, 0xCFA);
     if (inb (0xCF8) == 0x00 && inb (0xCFC) == 0x00) {
+	restore_flags(flags);
 	printk("pcibios_init: Using configuration type 2\n");
 	return &pci_direct_conf2;
     }
+    restore_flags(flags);
     printk("pcibios_init: Not supported chipset for direct PCI access !\n");
     return NULL;
 }
diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.1.30/linux/arch/i386/kernel/i386_ksyms.c	Thu Mar 27 14:39:59 1997
+++ linux/arch/i386/kernel/i386_ksyms.c	Mon Mar 31 13:25:25 1997
@@ -24,7 +24,7 @@
 EXPORT_SYMBOL(__verify_write);
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(ioremap);
+EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL_NOVERS(__down_failed);
 EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
@@ -44,6 +44,7 @@
 
 #ifdef CONFIG_MCA
 /* Adapter probing and info methods. */
+EXPORT_SYMBOL(mca_find_adapter);
 EXPORT_SYMBOL(mca_write_pos);
 EXPORT_SYMBOL(mca_read_pos);
 EXPORT_SYMBOL(mca_read_stored_pos);
diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.30/linux/arch/i386/kernel/irq.c	Thu Mar 27 14:39:59 1997
+++ linux/arch/i386/kernel/irq.c	Mon Mar 31 12:52:24 1997
@@ -334,11 +334,6 @@
 #define irq_active(cpu) \
 	(global_irq_count != local_irq_count[cpu])
 
-#define INIT_STUCK 10000000
-
-#define STUCK(x) \
-if (!--stuck) {printk(#x " stuck at %08lx, waiting for %08lx\n", where, previous); stuck = INIT_STUCK;}
-
 /*
  * "global_cli()" is a special case, in that it can hold the
  * interrupts disabled for a longish time, and also because
@@ -355,31 +350,19 @@
 	}
 }
 
-static inline void get_irqlock(int cpu, unsigned long where)
+static unsigned long previous_irqholder;
+
+#undef INIT_STUCK
+#define INIT_STUCK 10000000
+
+#undef STUCK
+#define STUCK \
+if (!--stuck) {printk("wait_on_irq stuck at %08lx, waiting for %08lx (local=%d, global=%d)\n", where, previous_irqholder, local_count, global_irq_count); stuck = INIT_STUCK;}
+
+static inline void wait_on_irq(int cpu, unsigned long where)
 {
-static unsigned long previous;
-	int local_count;
 	int stuck = INIT_STUCK;
-
-	if (set_bit(0,&global_irq_lock)) {
-		/* do we already hold the lock? */
-		if ((unsigned char) cpu == global_irq_holder)
-			return;
-		/* Uhhuh.. Somebody else got it. Wait.. */
-		do {
-			do {
-				STUCK(irqlock1);
-				check_smp_invalidate(cpu);
-			} while (test_bit(0,&global_irq_lock));
-		} while (set_bit(0,&global_irq_lock));		
-	}
-	/*
-	 * Ok, we got the lock bit.
-	 * But that's actually just the easy part.. Now
-	 * we need to make sure that nobody else is running
-	 * in an interrupt context. 
-	 */
-	local_count = local_irq_count[cpu];
+	int local_count = local_irq_count[cpu];
 
 	/* Are we the only one in an interrupt context? */
 	while (local_count != global_irq_count) {
@@ -397,7 +380,7 @@
 		 * their things before trying to get the lock again.
 		 */
 		for (;;) {
-			STUCK(irqlock2);
+			STUCK;
 			check_smp_invalidate(cpu);
 			if (global_irq_count)
 				continue;
@@ -408,12 +391,44 @@
 		}
 		atomic_add(local_count, &global_irq_count);
 	}
+}
+
+#undef INIT_STUCK
+#define INIT_STUCK 10000000
+
+#undef STUCK
+#define STUCK \
+if (!--stuck) {printk("get_irqlock stuck at %08lx, waiting for %08lx\n", where, previous_irqholder); stuck = INIT_STUCK;}
+
+static inline void get_irqlock(int cpu, unsigned long where)
+{
+	int stuck = INIT_STUCK;
+
+	if (set_bit(0,&global_irq_lock)) {
+		/* do we already hold the lock? */
+		if ((unsigned char) cpu == global_irq_holder)
+			return;
+		/* Uhhuh.. Somebody else got it. Wait.. */
+		do {
+			do {
+				STUCK;
+				check_smp_invalidate(cpu);
+			} while (test_bit(0,&global_irq_lock));
+		} while (set_bit(0,&global_irq_lock));		
+	}
+	/*
+	 * Ok, we got the lock bit.
+	 * But that's actually just the easy part.. Now
+	 * we need to make sure that nobody else is running
+	 * in an interrupt context. 
+	 */
+	wait_on_irq(cpu, where);
 
 	/*
 	 * Finally.
 	 */
 	global_irq_holder = cpu;
-	previous = where;
+	previous_irqholder = where;
 }
 
 void __global_cli(void)
@@ -485,8 +500,8 @@
 
 #else
 
-#define irq_enter(cpu, irq)	do { } while (0)
-#define irq_exit(cpu, irq)	do { } while (0)
+#define irq_enter(cpu, irq)	(++intr_count)
+#define irq_exit(cpu, irq)	(--intr_count)
 
 #endif
 
diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.1.30/linux/arch/i386/kernel/process.c	Thu Mar 27 14:39:59 1997
+++ linux/arch/i386/kernel/process.c	Mon Mar 31 10:26:12 1997
@@ -149,7 +149,15 @@
 	{
 		if(cpu_data[smp_processor_id()].hlt_works_ok && !hlt_counter && !need_resched)
 			__asm("hlt");
-		run_task_queue(&tq_scheduler);
+		/*
+		 * tq_scheduler currently assumes we're running in a process
+		 * context (ie that we hold the kernel lock..)
+		 */
+		if (tq_scheduler) {
+			lock_kernel();
+			run_task_queue(&tq_scheduler);
+			unlock_kernel();
+		}
 		schedule();
 	}
 }
@@ -203,7 +211,7 @@
    doesn't work with at least one type of 486 motherboard.  It is easy
    to stop this code working; hence the copious comments. */
 
-unsigned long long
+static unsigned long long
 real_mode_gdt_entries [3] =
 {
 	0x0000000000000000ULL,	/* Null descriptor */
@@ -211,7 +219,7 @@
 	0x000092000100ffffULL		/* 16-bit real-mode 64k data at 0x00000100 */
 };
 
-struct
+static struct
 {
 	unsigned short       size __attribute__ ((packed));
 	unsigned long long * base __attribute__ ((packed));
@@ -238,7 +246,7 @@
    More could be done here to set up the registers as if a CPU reset had
    occurred; hopefully real BIOSes don't assume much. */
 
-unsigned char real_mode_switch [] =
+static unsigned char real_mode_switch [] =
 {
 	0x66, 0x0f, 0x20, 0xc0,			/*    movl  %cr0,%eax        */
 	0x66, 0x83, 0xe0, 0x11,			/*    andl  $0x00000011,%eax */
diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- v2.1.30/linux/arch/i386/kernel/time.c	Thu Mar 27 14:39:59 1997
+++ linux/arch/i386/kernel/time.c	Mon Mar 31 10:26:12 1997
@@ -245,7 +245,7 @@
 /*
  * this is only used if we have fast gettimeoffset:
  */
-void do_x86_get_fast_time(struct timeval * tv)
+static void do_x86_get_fast_time(struct timeval * tv)
 {
 	do_gettimeofday(tv);
 }
@@ -454,7 +454,7 @@
 	  )*60 + sec; /* finally seconds */
 }
 
-unsigned long get_cmos_time(void)
+static unsigned long get_cmos_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
 	int i;
diff -u --recursive --new-file v2.1.30/linux/arch/i386/mm/ioremap.c linux/arch/i386/mm/ioremap.c
--- v2.1.30/linux/arch/i386/mm/ioremap.c	Wed Sep 25 02:12:50 1996
+++ linux/arch/i386/mm/ioremap.c	Fri Mar 28 10:49:40 1997
@@ -9,11 +9,10 @@
  */
 
 #include <linux/vmalloc.h>
-
 #include <asm/io.h>
 
 static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr)
+	unsigned long phys_addr, unsigned long flags)
 {
 	unsigned long end;
 
@@ -24,7 +23,8 @@
 	do {
 		if (!pte_none(*pte))
 			printk("remap_area_pte: page already exists\n");
-		set_pte(pte, mk_pte_phys(phys_addr, PAGE_KERNEL));
+		set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | _PAGE_RW | 
+					_PAGE_DIRTY | _PAGE_ACCESSED | flags)));
 		address += PAGE_SIZE;
 		phys_addr += PAGE_SIZE;
 		pte++;
@@ -32,7 +32,7 @@
 }
 
 static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr)
+	unsigned long phys_addr, unsigned long flags)
 {
 	unsigned long end;
 
@@ -45,14 +45,15 @@
 		pte_t * pte = pte_alloc_kernel(pmd, address);
 		if (!pte)
 			return -ENOMEM;
-		remap_area_pte(pte, address, end - address, address + phys_addr);
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address < end);
 	return 0;
 }
 
-static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size)
+static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+				 unsigned long size, unsigned long flags)
 {
 	pgd_t * dir;
 	unsigned long end = address + size;
@@ -64,7 +65,8 @@
 		pmd_t *pmd = pmd_alloc_kernel(dir, address);
 		if (!pmd)
 			return -ENOMEM;
-		if (remap_area_pmd(pmd, address, end - address, phys_addr + address))
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
 			return -ENOMEM;
 		set_pgdir(address, *dir);
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -75,11 +77,15 @@
 }
 
 /*
+ * Generic mapping function (not visible outside):
+ */
+
+/*
  * Remap an arbitrary physical address space into the kernel virtual
  * address space. Needed when the kernel wants to access high addresses
  * directly.
  */
-void * ioremap(unsigned long phys_addr, unsigned long size)
+void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
 {
 	void * addr;
 	struct vm_struct * area;
@@ -95,7 +101,7 @@
 	if (!area)
 		return NULL;
 	addr = area->addr;
-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size)) {
+	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
 		vfree(addr);
 		return NULL;
 	}
diff -u --recursive --new-file v2.1.30/linux/arch/m68k/Makefile linux/arch/m68k/Makefile
--- v2.1.30/linux/arch/m68k/Makefile	Fri Dec 20 01:19:57 1996
+++ linux/arch/m68k/Makefile	Thu Mar 27 14:36:38 1997
@@ -48,7 +48,7 @@
 
 HEAD := arch/m68k/kernel/head.o
 
-SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/console arch/m68k/lib
+SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib
 ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES)
 LIBS += arch/m68k/lib/lib.a
 
@@ -67,8 +67,11 @@
 SUBDIRS := $(SUBDIRS) arch/m68k/mac
 endif
 
+ifdef CONFIG_VT
 # add in console.a after {amiga,atari}.o that need it
 ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a
+SUBDIRS := $(SUBDIRS) arch/m68k/console
+endif
 
 ifdef CONFIG_M68040
 ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o
diff -u --recursive --new-file v2.1.30/linux/arch/m68k/atari/joystick.c linux/arch/m68k/atari/joystick.c
--- v2.1.30/linux/arch/m68k/atari/joystick.c	Fri Nov 22 05:56:34 1996
+++ linux/arch/m68k/atari/joystick.c	Wed Apr  2 17:43:19 1997
@@ -54,7 +54,7 @@
 /*    ikbd_joystick_event_on(); */
 }
 
-static void release_joystick(struct inode *inode, struct file *file)
+static int release_joystick(struct inode *inode, struct file *file)
 {
     int minor = DEVICE_NR(inode->i_rdev);
 
@@ -63,6 +63,7 @@
 
     if ((joystick[0].active == 0) && (joystick[1].active == 0))
 	ikbd_joystick_disable();
+    return 0;
 }
 
 static int open_joystick(struct inode *inode, struct file *file)
diff -u --recursive --new-file v2.1.30/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.1.30/linux/arch/m68k/config.in	Fri Dec 20 01:19:58 1996
+++ linux/arch/m68k/config.in	Thu Mar 27 14:36:38 1997
@@ -199,6 +199,9 @@
 mainmenu_option next_comment
 comment 'Character devices'
 
+define_bool CONFIG_VT y
+define_bool CONFIG_VT_CONSOLE y
+
 tristate 'Parallel printer support' CONFIG_PRINTER
 if [ "$CONFIG_AMIGA" = "y" ]; then
   dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER
diff -u --recursive --new-file v2.1.30/linux/arch/m68k/defconfig linux/arch/m68k/defconfig
--- v2.1.30/linux/arch/m68k/defconfig	Tue Jan 14 02:59:10 1997
+++ linux/arch/m68k/defconfig	Thu Mar 27 14:36:38 1997
@@ -168,6 +168,8 @@
 #
 # Character devices
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_PRINTER is not set
 CONFIG_AMIGAMOUSE=y
 CONFIG_ATARIMOUSE=y
diff -u --recursive --new-file v2.1.30/linux/arch/m68k/kernel/Makefile linux/arch/m68k/kernel/Makefile
--- v2.1.30/linux/arch/m68k/kernel/Makefile	Fri Jan  3 01:33:25 1997
+++ linux/arch/m68k/kernel/Makefile	Thu Mar 27 14:36:38 1997
@@ -13,7 +13,10 @@
 all: kernel.o head.o
 O_TARGET := kernel.o
 O_OBJS := entry.o process.o traps.o ints.o signal.o ptrace.o \
-	  setup.o bios32.o sys_m68k.o console.o time.o
+	  setup.o bios32.o sys_m68k.o time.o
+ifdef CONFIG_VT
+O_OBJS += console.o
+endif
 OX_OBJS := m68k_ksyms.o
 
 head.o: head.S
diff -u --recursive --new-file v2.1.30/linux/arch/m68k/kernel/console.c linux/arch/m68k/kernel/console.c
--- v2.1.30/linux/arch/m68k/kernel/console.c	Fri Dec 20 01:19:58 1996
+++ linux/arch/m68k/kernel/console.c	Thu Mar 27 14:36:38 1997
@@ -178,6 +178,17 @@
 static int vesa_off_interval = 0;
 static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
 
+/*
+ * fg_console is the current virtual console,
+ * last_console is the last used one,
+ * want_console is the console we want to switch to,
+ * kmsg_redirect is the console for kernel messages,
+ */
+int fg_console = 0;
+int last_console = 0;
+int want_console = -1;
+int kmsg_redirect = 0;
+
 static struct vc {
 	struct vc_data *d;
 
@@ -1003,6 +1014,56 @@
 	int currcons = fg_console;
 
 	return report_mouse;
+}
+
+int tioclinux(struct tty_struct *tty, unsigned long arg)
+{
+	char type, data;
+
+	if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
+		return -EINVAL;
+	if (current->tty != tty && !suser())
+		return -EPERM;
+	if (get_user(type, (char *)arg))
+		return -EFAULT;
+	switch (type)
+	{
+		case 2:
+			return set_selection(arg, tty, 1);
+		case 3:
+			return paste_selection(tty);
+		case 4:
+			do_unblank_screen();
+			return 0;
+		case 5:
+			return sel_loadlut(arg);
+		case 6:
+			
+	/*
+	 * Make it possible to react to Shift+Mousebutton.
+	 * Note that 'shift_state' is an undocumented
+	 * kernel-internal variable; programs not closely
+	 * related to the kernel should not use this.
+	 */
+	 		data = shift_state;
+			return put_user(data, (char *) arg);
+		case 7:
+			data = mouse_reporting();
+			return put_user(data, (char *) arg);
+		case 10:
+			set_vesa_blanking(arg);
+			return 0;
+		case 11:	/* set kmsg redirect */
+			if (!suser())
+				return -EPERM;
+			if (get_user(data, (char *)arg+1))
+					return -EFAULT;
+			kmsg_redirect = data;
+			return 0;
+		case 12:	/* get fg_console */
+			return fg_console;
+	}
+	return -EINVAL;
 }
 
 static inline unsigned short *screenpos(int currcons, int offset, int viewed)
diff -u --recursive --new-file v2.1.30/linux/arch/mips/defconfig linux/arch/mips/defconfig
--- v2.1.30/linux/arch/mips/defconfig	Tue Jan 14 02:59:10 1997
+++ linux/arch/mips/defconfig	Thu Mar 27 14:36:38 1997
@@ -64,6 +64,8 @@
 #
 # character devices
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_CYCLADES is not set
 # CONFIG_STALDRV is not set
 # CONFIG_PRINTER is not set
diff -u --recursive --new-file v2.1.30/linux/arch/sparc/config.in linux/arch/sparc/config.in
--- v2.1.30/linux/arch/sparc/config.in	Mon Mar 17 14:54:20 1997
+++ linux/arch/sparc/config.in	Thu Mar 27 14:36:38 1997
@@ -21,6 +21,9 @@
 mainmenu_option next_comment
 comment 'General setup'
 
+define_bool CONFIG_VT y
+define_bool CONFIG_VT_CONSOLE y
+
 bool 'Support for AP1000 multicomputer' CONFIG_AP1000
 
 if [ "$CONFIG_AP1000" = "y" ]; then
diff -u --recursive --new-file v2.1.30/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.1.30/linux/arch/sparc/defconfig	Thu Mar 27 14:39:59 1997
+++ linux/arch/sparc/defconfig	Thu Mar 27 14:36:38 1997
@@ -17,6 +17,8 @@
 #
 # General setup
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_AP1000 is not set
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
diff -u --recursive --new-file v2.1.30/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.1.30/linux/arch/sparc64/config.in	Mon Dec 30 01:59:59 1996
+++ linux/arch/sparc64/config.in	Thu Mar 27 14:36:39 1997
@@ -21,6 +21,9 @@
 mainmenu_option next_comment
 comment 'General setup'
 
+define_bool CONFIG_VT y
+define_bool CONFIG_VT_CONSOLE y
+
 bool 'Support for AP1000 multicomputer' CONFIG_AP1000
 
 if [ "$CONFIG_AP1000" = "y" ]; then
diff -u --recursive --new-file v2.1.30/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.1.30/linux/arch/sparc64/defconfig	Thu Mar 27 14:40:00 1997
+++ linux/arch/sparc64/defconfig	Thu Mar 27 14:36:39 1997
@@ -17,6 +17,8 @@
 #
 # General setup
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_AP1000 is not set
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
diff -u --recursive --new-file v2.1.30/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c
--- v2.1.30/linux/drivers/block/amiflop.c	Fri Dec 20 01:20:00 1996
+++ linux/drivers/block/amiflop.c	Wed Apr  2 17:43:19 1997
@@ -1779,7 +1779,7 @@
   return 0;
 }
 
-static void floppy_release(struct inode * inode, struct file * filp)
+static int floppy_release(struct inode * inode, struct file * filp)
 {
   unsigned long flags;
 
@@ -1803,6 +1803,7 @@
 /* the mod_use counter is handled this way */
   floppy_off (inode->i_rdev & 3);
 #endif
+  return 0;
 }
 
 void amiga_floppy_setup (char *str, int *ints)
diff -u --recursive --new-file v2.1.30/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c
--- v2.1.30/linux/drivers/block/ataflop.c	Fri Dec 20 01:20:00 1996
+++ linux/drivers/block/ataflop.c	Wed Apr  2 17:43:19 1997
@@ -1946,7 +1946,7 @@
 }
 
 
-static void floppy_release( struct inode * inode, struct file * filp )
+static int floppy_release( struct inode * inode, struct file * filp )
 {
   int drive;
 
@@ -1966,6 +1966,7 @@
     }
 
   MOD_DEC_USE_COUNT;
+  return 0;
 }
 
 static struct file_operations floppy_fops = {
diff -u --recursive --new-file v2.1.30/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.1.30/linux/drivers/block/floppy.c	Thu Mar 27 14:40:02 1997
+++ linux/drivers/block/floppy.c	Wed Apr  2 17:43:19 1997
@@ -3493,7 +3493,7 @@
 	return ret;
 }
 
-static void floppy_release(struct inode * inode, struct file * filp)
+static int floppy_release(struct inode * inode, struct file * filp)
 {
 	int drive;
 
@@ -3511,6 +3511,7 @@
 		UDRS->fd_ref = 0;
 	}
 	floppy_release_irq_and_dma();
+	return 0;
 }
 
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.1.30/linux/drivers/block/genhd.c	Mon Dec 30 02:06:22 1996
+++ linux/drivers/block/genhd.c	Thu Mar 27 14:36:39 1997
@@ -733,7 +733,9 @@
 #ifdef CONFIG_INET
 	net_dev_init();
 #endif
+#ifdef CONFIG_VT
 	console_map_init();
+#endif
 
 	for (p = gendisk_head ; p ; p=p->next) {
 		setup_dev(p);
diff -u --recursive --new-file v2.1.30/linux/drivers/block/hd.c linux/drivers/block/hd.c
--- v2.1.30/linux/drivers/block/hd.c	Sun Jan 26 02:07:10 1997
+++ linux/drivers/block/hd.c	Wed Apr  2 17:43:19 1997
@@ -656,14 +656,14 @@
  * Releasing a block device means we sync() it, so that it can safely
  * be forgotten about...
  */
-static void hd_release(struct inode * inode, struct file * file)
+static int hd_release(struct inode * inode, struct file * file)
 {
         int target;
 	sync_dev(inode->i_rdev);
 
 	target =  DEVICE_NR(inode->i_rdev);
 	access_count[target]--;
-
+	return 0;
 }
 
 static void hd_geninit(struct gendisk *);
diff -u --recursive --new-file v2.1.30/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
--- v2.1.30/linux/drivers/block/ide-tape.c	Thu Mar 27 14:40:02 1997
+++ linux/drivers/block/ide-tape.c	Wed Apr  2 17:43:20 1997
@@ -3271,7 +3271,7 @@
 /*
  *	Our character device release function.
  */
-static void idetape_chrdev_release (struct inode *inode, struct file *filp)
+static int idetape_chrdev_release (struct inode *inode, struct file *filp)
 {
 	ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
 	idetape_tape_t *tape = drive->driver_data;
@@ -3310,6 +3310,7 @@
 	clear_bit (IDETAPE_BUSY, &tape->flags);
 	if (tape->chrdev_direction == idetape_direction_none)
 		MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.1.30/linux/drivers/block/ide.c	Thu Mar 27 14:40:02 1997
+++ linux/drivers/block/ide.c	Wed Apr  2 17:53:11 1997
@@ -1710,7 +1710,7 @@
  * Releasing a block device means we sync() it, so that it can safely
  * be forgotten about...
  */
-static void ide_release(struct inode * inode, struct file * file)
+static int ide_release(struct inode * inode, struct file * file)
 {
 	ide_drive_t *drive;
 
@@ -1721,6 +1721,7 @@
 			DRIVER(drive)->release(inode, file, drive);
 		MOD_DEC_USE_COUNT;
 	}
+	return 0;
 }
 
 void ide_unregister (unsigned int index)
diff -u --recursive --new-file v2.1.30/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.1.30/linux/drivers/block/loop.c	Sun Jan 26 02:07:10 1997
+++ linux/drivers/block/loop.c	Wed Apr  2 17:43:20 1997
@@ -12,6 +12,8 @@
  * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994
  *
  * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
+ *
+ * Fixed do_loop_request() re-entrancy - <Vincent.Renardias@waw.com> Mar 20, 1997
  */
 
 #include <linux/module.h>
@@ -181,12 +183,15 @@
 	char	*dest_addr;
 	struct loop_device *lo;
 	struct buffer_head *bh;
+	struct request *current_request;
 
 repeat:
 	INIT_REQUEST;
-	if (MINOR(CURRENT->rq_dev) >= MAX_LOOP)
+	current_request=CURRENT;
+	CURRENT=current_request->next;
+	if (MINOR(current_request->rq_dev) >= MAX_LOOP)
 		goto error_out;
-	lo = &loop_dev[MINOR(CURRENT->rq_dev)];
+	lo = &loop_dev[MINOR(current_request->rq_dev)];
 	if (!lo->lo_inode || !lo->transfer)
 		goto error_out;
 
@@ -197,14 +202,14 @@
 	      blksize = BLOCK_SIZE;
 	}
 
-	dest_addr = CURRENT->buffer;
+	dest_addr = current_request->buffer;
 	
 	if (blksize < 512) {
-		block = CURRENT->sector * (512/blksize);
+		block = current_request->sector * (512/blksize);
 		offset = 0;
 	} else {
-		block = CURRENT->sector / (blksize >> 9);
-		offset = (CURRENT->sector % (blksize >> 9)) << 9;
+		block = current_request->sector / (blksize >> 9);
+		offset = (current_request->sector % (blksize >> 9)) << 9;
 	}
 	block += lo->lo_offset / blksize;
 	offset += lo->lo_offset % blksize;
@@ -212,13 +217,13 @@
 		block++;
 		offset -= blksize;
 	}
-	len = CURRENT->current_nr_sectors << 9;
+	len = current_request->current_nr_sectors << 9;
 
-	if (CURRENT->cmd == WRITE) {
+	if (current_request->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);
+	} else if (current_request->cmd != READ) {
+		printk("unknown loop device command (%d)?!?", current_request->cmd);
 		goto error_out;
 	}
 	while (len > 0) {
@@ -237,7 +242,7 @@
 			       block, blksize);
 			goto error_out;
 		}
-		if (!buffer_uptodate(bh) && ((CURRENT->cmd == READ) ||
+		if (!buffer_uptodate(bh) && ((current_request->cmd == READ) ||
 					(offset || (len < blksize)))) {
 			ll_rw_block(READ, 1, &bh);
 			wait_on_buffer(bh);
@@ -250,13 +255,13 @@
 		if (size > len)
 			size = len;
 			   
-		if ((lo->transfer)(lo, CURRENT->cmd, bh->b_data + offset,
+		if ((lo->transfer)(lo, current_request->cmd, bh->b_data + offset,
 				   dest_addr, size)) {
 			printk("loop: transfer error block %d\n", block);
 			brelse(bh);
 			goto error_out;
 		}
-		if (CURRENT->cmd == WRITE) {
+		if (current_request->cmd == WRITE) {
 			mark_buffer_uptodate(bh, 1);
 			mark_buffer_dirty(bh, 1);
 		}
@@ -266,9 +271,13 @@
 		offset = 0;
 		block++;
 	}
+	current_request->next=CURRENT;
+	CURRENT=current_request;
 	end_request(1);
 	goto repeat;
 error_out:
+    current_request->next=CURRENT;
+	CURRENT=current_request;
 	end_request(0);
 	goto repeat;
 }
@@ -484,20 +493,20 @@
 	return 0;
 }
 
-static void lo_release(struct inode *inode, struct file *file)
+static int lo_release(struct inode *inode, struct file *file)
 {
 	struct loop_device *lo;
 	int	dev;
 
 	if (!inode)
-		return;
+		return 0;
 	if (MAJOR(inode->i_rdev) != MAJOR_NR) {
 		printk("lo_release: pseudo-major != %d\n", MAJOR_NR);
-		return;
+		return 0;
 	}
 	dev = MINOR(inode->i_rdev);
 	if (dev >= MAX_LOOP)
-		return;
+		return 0;
 	fsync_dev(inode->i_rdev);
 	lo = &loop_dev[dev];
 	if (lo->lo_refcnt <= 0)
@@ -506,6 +515,7 @@
 		lo->lo_refcnt--;
 		MOD_DEC_USE_COUNT;
 	}
+	return 0;
 }
 
 static struct file_operations lo_fops = {
diff -u --recursive --new-file v2.1.30/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.1.30/linux/drivers/block/md.c	Fri Dec 27 02:03:20 1996
+++ linux/drivers/block/md.c	Wed Apr  2 17:43:20 1997
@@ -362,12 +362,13 @@
 }
 
 
-static void md_release (struct inode *inode, struct file *file)
+static int md_release (struct inode *inode, struct file *file)
 {
   int minor=MINOR(inode->i_rdev);
 
   sync_dev (inode->i_rdev);
   md_dev[minor].busy--;
+  return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.1.30/linux/drivers/block/ps2esdi.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/block/ps2esdi.c	Wed Apr  2 17:43:20 1997
@@ -89,7 +89,7 @@
 
 static int ps2esdi_open(struct inode *inode, struct file *file);
 
-static void ps2esdi_release(struct inode *inode, struct file *file);
+static int ps2esdi_release(struct inode *inode, struct file *file);
 
 static int ps2esdi_ioctl(struct inode *inode, struct file *file,
 			 u_int cmd, u_long arg);
@@ -1060,7 +1060,7 @@
 
 
 
-static void ps2esdi_release(struct inode *inode, struct file *file)
+static int ps2esdi_release(struct inode *inode, struct file *file)
 {
 	int dev = DEVICE_NR(MINOR(inode->i_rdev));
 
@@ -1068,6 +1068,7 @@
 		sync_dev(dev);
 		access_count[dev]--;
 	}
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.1.30/linux/drivers/block/rd.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/block/rd.c	Wed Apr  2 17:43:20 1997
@@ -196,7 +196,7 @@
 }
 
 
-static void initrd_release(struct inode *inode,struct file *file)
+static int initrd_release(struct inode *inode,struct file *file)
 {
 	unsigned long i;
 
@@ -204,6 +204,7 @@
 	for (i = initrd_start; i < initrd_end; i += PAGE_SIZE)
 		free_page(i);
 	initrd_start = 0;
+	return 0;
 }
 
 
@@ -243,9 +244,10 @@
 }
 
 #ifdef MODULE
-static void rd_release(struct inode * inode, struct file * filp)
+static int rd_release(struct inode * inode, struct file * filp)
 {
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 #endif
 
diff -u --recursive --new-file v2.1.30/linux/drivers/block/triton.c linux/drivers/block/triton.c
--- v2.1.30/linux/drivers/block/triton.c	Thu Mar 27 14:40:02 1997
+++ linux/drivers/block/triton.c	Thu Mar 27 13:08:54 1997
@@ -443,7 +443,10 @@
 	const char *chipset = "ide";
 	piix_timing_t timings[2];
 
-	if (pcibios_read_config_word(piix_pci_bus, piix_pci_fn, 0x02, &devid))
+	piix_pci_bus = bus;
+	piix_pci_fn  = fn;
+
+	if (pcibios_read_config_word(bus, fn, 0x02, &devid))
 		goto quit;
 	chipset = (devid == PCI_DEVICE_ID_INTEL_82371SB_1) ? "PIIX3" : "PIIX";
 
@@ -462,14 +465,11 @@
 		goto quit;
 	if ((rc = pcibios_read_config_word(bus, fn, 0x42, (short *)&timings[1])))
 		goto quit;
-	if ((!timings[0].ports_enabled) || (!timings[1].ports_enabled)) {
+	if ((!timings[0].ports_enabled) && (!timings[1].ports_enabled)) {
 		printk("%s: neither IDE port is enabled\n", chipset);
 		goto quit;
 	}
 
-	piix_pci_bus = bus;
-	piix_pci_fn  = fn;
-
 	/*
 	 * See if Bus-Mastered DMA is enabled
 	 */
@@ -534,7 +534,7 @@
 			byte recovery = 4 - timing.recovery;
 			if (devid == PCI_DEVICE_ID_INTEL_82371SB_1
 			 && timing.sidetim_enabled
-			 && !pcibios_read_config_byte(piix_pci_bus, piix_pci_fn, 0x44, (byte *) &sidetim))
+			 && !pcibios_read_config_byte(bus, fn, 0x44, (byte *) &sidetim))
 				slave = "";		/* PIIX3 */
 			else
 				slave = "/slave";	/* PIIX, or PIIX3 in compatibility mode */
diff -u --recursive --new-file v2.1.30/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.1.30/linux/drivers/block/xd.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/block/xd.c	Wed Apr  2 17:43:20 1997
@@ -294,7 +294,7 @@
 }
 
 /* xd_release: release the device */
-static void xd_release (struct inode *inode, struct file *file)
+static int xd_release (struct inode *inode, struct file *file)
 {
 	int target;
 
@@ -303,6 +303,7 @@
 		sync_dev(inode->i_rdev);
 		xd_access[target]--;
 	}
+	return 0;
 }
 
 /* xd_reread_partitions: rereads the partition table from a drive */
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/aztcd.c linux/drivers/cdrom/aztcd.c
--- v2.1.30/linux/drivers/cdrom/aztcd.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/aztcd.c	Wed Apr  2 17:43:20 1997
@@ -330,7 +330,7 @@
 static void do_aztcd_request(void);
 static void azt_invalidate_buffers(void);
 int         aztcd_open(struct inode *ip, struct file *fp);
-static void aztcd_release(struct inode * inode, struct file * file);
+static int  aztcd_release(struct inode * inode, struct file * file);
 int         aztcd_init(void);
 #ifdef MODULE
  int        init_module(void);
@@ -1542,7 +1542,7 @@
 /*
  * On close, we flush all azt blocks from the buffer cache.
  */
-static void aztcd_release(struct inode * inode, struct file * file)
+static int aztcd_release(struct inode * inode, struct file * file)
 { 
 #ifdef AZT_DEBUG
   printk("aztcd: executing aztcd_release\n");
@@ -1558,7 +1558,7 @@
            aztSendCmd(ACMD_EJECT);
         CLEAR_TIMER;
   }
-  return;
+  return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- v2.1.30/linux/drivers/cdrom/cdrom.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/cdrom.c	Wed Apr  2 17:43:20 1997
@@ -27,7 +27,7 @@
 
 /* Not-exported routines. */
 static int cdrom_open(struct inode *ip, struct file *fp);
-static void cdrom_release(struct inode *ip, struct file *fp);
+static int cdrom_release(struct inode *ip, struct file *fp);
 static int cdrom_ioctl(struct inode *ip, struct file *fp,
 				unsigned int cmd, unsigned long arg);
 static int cdrom_media_changed(kdev_t dev);
@@ -196,14 +196,14 @@
 
 /* Admittedly, the logic below could be performed in a nicer way. */
 static
-void cdrom_release(struct inode *ip, struct file *fp)
+int cdrom_release(struct inode *ip, struct file *fp)
 {
         kdev_t dev = ip->i_rdev;
         struct cdrom_device_info *cdi = cdrom_find_device (dev);
         struct cdrom_device_ops *cdo;
 	
         if (cdi == NULL)
-                return;
+                return 0;
         cdo = cdi->ops;        
         if (cdi->use_count == 1 &&      /* last process that closes dev*/
             cdi->options & CDO_LOCK &&  
@@ -218,6 +218,7 @@
                     cdo->capability & ~cdi->mask & CDC_OPEN_TRAY)
                         cdo->tray_move(cdi, 1);
         }
+	return 0;
 }
 
 /* We want to make media_changed accessible to the user through an
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v2.1.30/linux/drivers/cdrom/cdu31a.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/cdu31a.c	Wed Apr  2 17:43:20 1997
@@ -171,6 +171,8 @@
  *             still here, if the eject button is pushed while the
  *             drive light is flashing, the drive will return a bad
  *             status and be reset.  It recovers, though.
+ *
+ *  03/07/97 - Fixed a problem with timers.
  */
 
 #include <linux/major.h>
@@ -933,6 +935,9 @@
    volatile int val;
 
 
+#if DEBUG
+   printk("Entering handle_sony_cd_attention\n");
+#endif
    if (is_attention())
    {
       if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
@@ -940,6 +945,9 @@
          printk("cdu31a: Too many consecutive attentions: %d\n",
                 num_consecutive_attentions);
          num_consecutive_attentions = 0;
+#if DEBUG
+         printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
          return(0);
       }
 
@@ -982,6 +990,9 @@
       }
 
       num_consecutive_attentions++;
+#if DEBUG
+      printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
       return(1);
    }
    else if (abort_read_started)
@@ -998,10 +1009,16 @@
          val = read_data_register();
       }
       abort_read_started = 0;
+#if DEBUG
+      printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
       return(1);
    }
 
    num_consecutive_attentions = 0;
+#if DEBUG
+   printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
    return(0);
 }
 
@@ -1090,6 +1107,9 @@
    unsigned int retry_count;
 
 
+#if DEBUG
+   printk("Entering start_request\n");
+#endif
    log_to_msf(sector, params);
    /* If requested, read exactly what was asked. */
    if (read_nsect_only)
@@ -1130,6 +1150,9 @@
    if (is_busy())
    {
       printk("CDU31A: Timeout while waiting to issue command\n");
+#if DEBUG
+      printk("Leaving start_request at %d\n", __LINE__);
+#endif
       return(1);
    }
    else
@@ -1145,8 +1168,14 @@
       sony_next_block = sector * 4;
       readahead_dataleft = 0;
       readahead_bad = 0;
+#if DEBUG
+      printk("Leaving start_request at %d\n", __LINE__);
+#endif
       return(0);
    }
+#if DEBUG
+   printk("Leaving start_request at %d\n", __LINE__);
+#endif
 }
 
 /* Abort a pending read operation.  Clear all the drive status and
@@ -1188,6 +1217,13 @@
 static void
 handle_abort_timeout(unsigned long data)
 {
+   unsigned long flags;
+
+#if DEBUG
+   printk("Entering handle_abort_timeout\n");
+#endif
+   save_flags(flags);
+   cli();
    /* If it is in use, ignore it. */
    if (!sony_inuse)
    {
@@ -1204,6 +1240,10 @@
       readahead_bad = 0;
       abort_read_started = 1;
    }
+   restore_flags(flags);
+#if DEBUG
+   printk("Leaving handle_abort_timeout\n");
+#endif
 }
 
 /* Actually get data and status from the drive. */
@@ -1218,6 +1258,9 @@
    volatile unsigned char val;
 
 
+#if DEBUG
+   printk("Entering input_data\n");
+#endif
    /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
       the disk.  The real data is after that. */
    if (sony_xa_mode)
@@ -1266,6 +1309,9 @@
          val = read_data_register();
       }
    }
+#if DEBUG
+   printk("Leaving input_data at %d\n", __LINE__);
+#endif
 }
 
 /* read data from the drive.  Note the nsect must be <= 4. */
@@ -1282,6 +1328,10 @@
    unsigned int skip;
 
 
+#if DEBUG
+   printk("Entering read_data_block\n");
+#endif
+
    res_reg[0] = 0;
    res_reg[1] = 0;
    *res_size = 0;
@@ -1347,6 +1397,9 @@
          {
             get_result(res_reg, res_size);
          }
+#if DEBUG
+         printk("Leaving read_data_block at %d\n", __LINE__);
+#endif
          return;
       }
    }
@@ -1466,6 +1519,9 @@
          }
       }
    }
+#if DEBUG
+   printk("Leaving read_data_block at %d\n", __LINE__);
+#endif
 }
 
 /*
@@ -1486,6 +1542,10 @@
    unsigned long flags;
 
 
+#if DEBUG
+         printk("Entering do_cdu31a_request\n");
+#endif
+
    /* 
     * Make sure no one else is using the driver; wait for them
     * to finish if it is so.
@@ -1503,6 +1563,9 @@
             end_request(0);
          }
          restore_flags(flags);
+#if DEBUG
+         printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+#endif
          return;
       }
    }
@@ -1518,11 +1581,8 @@
 
    sti();
 
-   /* If the timer is running, cancel it. */
-   if (cdu31a_abort_timer.next != NULL)
-   {
-      del_timer(&cdu31a_abort_timer);
-   }
+   /* Make sure the timer is cancelled. */
+   del_timer(&cdu31a_abort_timer);
 
    while (1)
    {
@@ -1694,6 +1754,7 @@
    }
 
 end_do_cdu31a_request:
+   cli();
 #if 0
    /* After finished, cancel any pending operations. */
    abort_read();
@@ -1708,6 +1769,9 @@
    sony_inuse = 0;
    wake_up_interruptible(&sony_wait);
    restore_flags(flags);
+#if DEBUG
+   printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+#endif
 }
 
 /* Copy overlapping buffers. */
@@ -2852,7 +2916,7 @@
  * Close the drive.  Spin it down if no task is using it.  The spin
  * down will fail if playing audio, so audio play is OK.
  */
-static void
+static int
 scd_release(struct inode *inode,
          struct file *filp)
 {
@@ -2877,6 +2941,7 @@
 
       sony_spun_up = 0;
    }
+   return 0;
 }
 
 
@@ -3141,8 +3206,7 @@
       /* use 'mount -o block=2048' */
       blksize_size[MAJOR_NR] = &cdu31a_block_size;
       
-      cdu31a_abort_timer.next = NULL;
-      cdu31a_abort_timer.prev = NULL;
+      init_timer(&cdu31a_abort_timer);
       cdu31a_abort_timer.function = handle_abort_timeout;
    }
 
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/gscd.c linux/drivers/cdrom/gscd.c
--- v2.1.30/linux/drivers/cdrom/gscd.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/gscd.c	Wed Apr  2 17:43:20 1997
@@ -87,7 +87,7 @@
 static void do_gscd_request       (void);
 static int  gscd_ioctl            (struct inode *, struct file *, unsigned int, unsigned long);
 static int  gscd_open             (struct inode *, struct file *);
-static void gscd_release          (struct inode *, struct file *);
+static int  gscd_release          (struct inode *, struct file *);
 static int  check_gscd_med_chg    (kdev_t);
 
 /*      GoldStar Funktionen    */
@@ -394,7 +394,7 @@
  * On close, we flush all gscd blocks from the buffer cache.
  */
 
-static void gscd_release (struct inode * inode, struct file * file)
+static int gscd_release (struct inode * inode, struct file * file)
 {
 
 #ifdef GSCD_DEBUG
@@ -406,6 +406,7 @@
 	invalidate_buffers(inode -> i_rdev);
 
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v2.1.30/linux/drivers/cdrom/mcd.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/mcd.c	Wed Apr  2 17:43:20 1997
@@ -1142,7 +1142,7 @@
  * On close, we flush all mcd blocks from the buffer cache.
  */
 
-static void
+static int
 mcd_release(struct inode * inode, struct file * file)
 { MOD_DEC_USE_COUNT;
   if (!--mcd_open_count) {
@@ -1150,6 +1150,7 @@
 	sync_dev(inode->i_rdev);
 	invalidate_buffers(inode -> i_rdev);
   }
+  return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- v2.1.30/linux/drivers/cdrom/mcdx.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/mcdx.c	Wed Apr  2 17:43:20 1997
@@ -227,7 +227,7 @@
 
 /* exported by file_ops */
 static int mcdx_open(struct inode*, struct file*);
-static void mcdx_close(struct inode*, struct file*);
+static int mcdx_close(struct inode*, struct file*);
 static int mcdx_ioctl(struct inode*, struct file*, unsigned int, unsigned long);
 
 /* misc internal support functions */
@@ -860,7 +860,7 @@
 
 }
 
-static void
+static int
 mcdx_close(struct inode *ip, struct file *fp)
 {
     struct s_drive_stuff *stuffp;
@@ -889,7 +889,7 @@
     }
 
     MOD_DEC_USE_COUNT;
-    return;
+    return 0;
 }
 
 int check_mcdx_media_change(kdev_t full_dev)
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c
--- v2.1.30/linux/drivers/cdrom/optcd.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/optcd.c	Wed Apr  2 17:43:20 1997
@@ -1914,7 +1914,7 @@
 
 
 /* Release device special file; flush all blocks from the buffer cache */
-static void opt_release(struct inode *ip, struct file *fp)
+static int opt_release(struct inode *ip, struct file *fp)
 {
 	int status;
 
@@ -1939,6 +1939,7 @@
 		CLEAR_REQ_TIMER;
 	}
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v2.1.30/linux/drivers/cdrom/sbpcd.c	Sun Jan 26 02:07:11 1997
+++ linux/drivers/cdrom/sbpcd.c	Wed Apr  2 17:43:20 1997
@@ -5200,7 +5200,7 @@
 /*
  *  On close, we flush all sbp blocks from the buffer cache.
  */
-static void sbpcd_release(struct inode * ip, struct file * file)
+static int sbpcd_release(struct inode * ip, struct file * file)
 {
 	int i;
 	
@@ -5208,7 +5208,7 @@
 	if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
 	{
 		msg(DBG_INF, "release: bad device: %04X\n", ip->i_rdev);
-		return;
+		return 0;
 	}
 	down(&ioctl_read_sem);
 	switch_drive(i);
@@ -5236,6 +5236,7 @@
 		}
 	}
 	up(&ioctl_read_sem);
+	return 0;
 }
 /*==========================================================================*/
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/sjcd.c linux/drivers/cdrom/sjcd.c
--- v2.1.30/linux/drivers/cdrom/sjcd.c	Sun Feb  2 05:18:30 1997
+++ linux/drivers/cdrom/sjcd.c	Wed Apr  2 17:43:21 1997
@@ -1385,7 +1385,7 @@
 /*
  * On close, we flush all sjcd blocks from the buffer cache.
  */
-static void sjcd_release( struct inode *inode, struct file *file ){
+static int sjcd_release( struct inode *inode, struct file *file ){
   int s;
 
 #if defined( SJCD_TRACE )
@@ -1413,6 +1413,7 @@
       }
     }
   }
+  return 0;
 }
 
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c
--- v2.1.30/linux/drivers/cdrom/sonycd535.c	Sun Jan 26 02:07:12 1997
+++ linux/drivers/cdrom/sonycd535.c	Wed Apr  2 17:43:21 1997
@@ -1434,7 +1434,7 @@
  * Close the drive.  Spin it down if no task is using it.  The spin
  * down will fail if playing audio, so audio play is OK.
  */
-static void
+static int
 cdu_release(struct inode *inode,
 			struct file *filp)
 {
@@ -1460,6 +1460,7 @@
 		do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
 #endif
 	}
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.1.30/linux/drivers/char/Config.in	Tue Mar  4 10:25:23 1997
+++ linux/drivers/char/Config.in	Thu Mar 27 14:36:39 1997
@@ -4,6 +4,10 @@
 mainmenu_option next_comment
 comment 'Character devices'
 
+bool 'Virtual terminal' CONFIG_VT
+if [ "$CONFIG_VT" = "y" ]; then
+  bool 'Console on virtual terminal' CONFIG_VT_CONSOLE
+fi
 tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
 bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED
 if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
@@ -11,6 +15,7 @@
    bool '   Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ
    bool '   Support special multiport boards' CONFIG_SERIAL_MULTIPORT
    bool '   Support the Bell Technologies HUB6 card' CONFIG_HUB6
+   bool '   Console on serial port' CONFIG_SERIAL_CONSOLE
 fi
 bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD
 if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then
diff -u --recursive --new-file v2.1.30/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.1.30/linux/drivers/char/Makefile	Tue Dec 31 06:27:23 1996
+++ linux/drivers/char/Makefile	Thu Mar 27 14:36:39 1997
@@ -20,9 +20,12 @@
 
 L_TARGET := char.a
 M_OBJS   :=
-L_OBJS   := tty_io.o n_tty.o console.o \
-	tty_ioctl.o pty.o vt.o mem.o vc_screen.o random.o \
-	consolemap.o selection.o
+L_OBJS   := tty_io.o n_tty.o tty_ioctl.o pty.o mem.o random.o
+
+ifdef CONFIG_VT
+L_OBJS += console.o vt.o vc_screen.o consolemap.o
+LX_OBJS += selection.o
+endif
 
 ifeq ($(CONFIG_SERIAL),y)
   ifndef CONFIG_SUN_SERIAL
@@ -35,8 +38,10 @@
 endif
 
 ifndef CONFIG_SUN_KEYBOARD
+ifdef CONFIG_VT
 L_OBJS += keyboard.o defkeymap.o
 endif
+endif
 
 ifeq ($(CONFIG_DIGI),y)
 L_OBJS += pcxx.o
@@ -235,13 +240,15 @@
   MX_OBJS += misc.o
   endif
 endif
-  
-ifdef CONFIG_TGA_CONSOLE
-L_OBJS += tga.o
-else
- ifndef CONFIG_SUN_CONSOLE
- L_OBJS += vga.o vesa_blank.o
- endif
+
+ifdef CONFIG_VT
+  ifdef CONFIG_TGA_CONSOLE
+  L_OBJS += tga.o
+  else
+   ifndef CONFIG_SUN_CONSOLE
+   L_OBJS += vga.o vesa_blank.o
+   endif
+  endif
 endif
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.30/linux/drivers/char/amigamouse.c linux/drivers/char/amigamouse.c
--- v2.1.30/linux/drivers/char/amigamouse.c	Sat Jan 25 13:46:13 1997
+++ linux/drivers/char/amigamouse.c	Wed Apr  2 17:43:21 1997
@@ -172,7 +172,7 @@
  * close access to the mouse
  */
 
-static void close_mouse(struct inode * inode, struct file * file)
+static int close_mouse(struct inode * inode, struct file * file)
 {
 	fasync_mouse(inode, file, 0);
 	if (--mouse.active)
@@ -180,6 +180,7 @@
 	free_irq(IRQ_AMIGA_VERTB, mouse_interrupt);
 	MSE_INT_OFF();
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c
--- v2.1.30/linux/drivers/char/apm_bios.c	Mon Mar 17 14:54:24 1997
+++ linux/drivers/char/apm_bios.c	Wed Apr  2 17:43:21 1997
@@ -301,7 +301,7 @@
 static void	do_apm_timer(unsigned long);
 
 static int	do_open(struct inode *, struct file *);
-static void	do_release(struct inode *, struct file *);
+static int	do_release(struct inode *, struct file *);
 static long	do_read(struct inode *, struct file *, char *, unsigned long);
 static unsigned int do_poll(struct file *, poll_table *);
 static int	do_ioctl(struct inode *, struct file *, u_int, u_long);
@@ -911,14 +911,14 @@
 	return 0;
 }
 
-static void do_release(struct inode * inode, struct file * filp)
+static int do_release(struct inode * inode, struct file * filp)
 {
 	struct apm_bios_struct *	as;
 
 	as = filp->private_data;
 	filp->private_data = NULL;
 	if (check_apm_bios_struct(as, "release"))
-		return;
+		return 0;
 	if (as->standbys_pending > 0) {
 		standbys_pending -= as->standbys_pending;
 		if (standbys_pending <= 0)
@@ -944,6 +944,7 @@
 			as1->next = as->next;
 	}
 	kfree_s(as, sizeof(*as));
+	return 0;
 }
 
 static int do_open(struct inode * inode, struct file * filp)
diff -u --recursive --new-file v2.1.30/linux/drivers/char/atarimouse.c linux/drivers/char/atarimouse.c
--- v2.1.30/linux/drivers/char/atarimouse.c	Sun Jan 26 02:07:12 1997
+++ linux/drivers/char/atarimouse.c	Wed Apr  2 17:43:21 1997
@@ -62,15 +62,16 @@
 	return 0;
 }
 
-static void release_mouse(struct inode *inode, struct file *file)
+static int release_mouse(struct inode *inode, struct file *file)
 {
     fasync_mouse(inode, file, 0);
     if (--mouse.active)
-      return;
+      return 0;
     ikbd_mouse_disable();
 
     atari_mouse_interrupt_hook = NULL;
     MOD_DEC_USE_COUNT;
+    return 0;
 }
 
 static int open_mouse(struct inode *inode, struct file *file)
diff -u --recursive --new-file v2.1.30/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c
--- v2.1.30/linux/drivers/char/atixlmouse.c	Sun Jan 26 02:07:12 1997
+++ linux/drivers/char/atixlmouse.c	Wed Apr  2 17:43:21 1997
@@ -104,15 +104,16 @@
 	return 0;
 }
 
-static void release_mouse(struct inode * inode, struct file * file)
+static int release_mouse(struct inode * inode, struct file * file)
 {
 	fasync_mouse(inode, file, 0);
 	if (--mouse.active)
-		return;
+		return 0;
 	ATIXL_MSE_INT_OFF(); /* Interrupts are really shut down here */
 	mouse.ready = 0;
 	free_irq(ATIXL_MOUSE_IRQ, NULL);
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 static int open_mouse(struct inode * inode, struct file * file)
diff -u --recursive --new-file v2.1.30/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c
--- v2.1.30/linux/drivers/char/busmouse.c	Sun Jan 26 02:07:14 1997
+++ linux/drivers/char/busmouse.c	Wed Apr  2 17:43:21 1997
@@ -119,14 +119,15 @@
  * close access to the mouse
  */
 
-static void close_mouse(struct inode * inode, struct file * file)
+static int close_mouse(struct inode * inode, struct file * file)
 {
 	fasync_mouse(inode, file, 0);
 	if (--mouse.active)
-		return;
+		return 0;
 	MSE_INT_OFF();
 	free_irq(mouse_irq, NULL);
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/char/console.c linux/drivers/char/console.c
--- v2.1.30/linux/drivers/char/console.c	Sun Feb  2 05:52:22 1997
+++ linux/drivers/char/console.c	Mon Mar 31 10:47:28 1997
@@ -18,7 +18,7 @@
  *     'unsigned long con_init(unsigned long)'
  *     'int con_open(struct tty_struct *tty, struct file * filp)'
  *     'void con_write(struct tty_struct * tty)'
- *     'void console_print(const char * b)'
+ *     'void vt_console_print(const char * b)'
  *     'void update_screen(int new_console)'
  *
  *     'void do_blank_screen(int)'
@@ -91,6 +91,7 @@
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/console.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -131,6 +132,7 @@
 unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
 struct vc vc_cons [MAX_NR_CONSOLES];
 
+static int con_open(struct tty_struct *, struct file *);
 static void con_setsize(unsigned long rows, unsigned long cols);
 static void vc_init(unsigned int console, unsigned long rows,
 		    unsigned long cols, int do_clear);
@@ -148,7 +150,7 @@
 static void reset_terminal(int currcons, int do_clear);
 extern void reset_vc(unsigned int new_console);
 extern void vt_init(void);
-extern void register_console(void (*proc)(const char *));
+extern void set_vesa_blanking(unsigned long arg);
 extern void vesa_blank(void);
 extern void vesa_unblank(void);
 extern void vesa_powerdown(void);
@@ -178,7 +180,7 @@
 int		video_mode_512ch = 0;	/* 512-character mode */
 unsigned long	video_font_height;	/* Height of current screen font */
 unsigned long	video_scan_lines;	/* Number of scan lines on screen */
-unsigned long   default_font_height;    /* Height of default screen font */
+static unsigned long   default_font_height;    /* Height of default screen font */
 int		video_font_is_default = 1;
 static unsigned short console_charmask = 0x0ff;
 
@@ -189,121 +191,16 @@
 static int vesa_off_interval = 0;
 static long blank_origin, blank__origin, unblank_origin;
 
-
-#ifdef CONFIG_SERIAL_ECHO
-
-#include <linux/serial_reg.h>
-
-extern int serial_echo_init (int base);
-extern int serial_echo_print (const char *s);
-
 /*
- * this defines the address for the port to which printk echoing is done
- *  when CONFIG_SERIAL_ECHO is defined
+ * fg_console is the current virtual console,
+ * last_console is the last used one,
+ * want_console is the console we want to switch to,
+ * kmsg_redirect is the console for kernel messages,
  */
-#define SERIAL_ECHO_PORT	0x3f8	/* COM1 */
-
-static int serial_echo_port = 0;
-
-#define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port)
-#define serial_echo_inb(a)    inb((a)+serial_echo_port)
-
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-/* Wait for transmitter & holding register to empty */
-#define WAIT_FOR_XMITR \
- do { \
-       lsr = serial_echo_inb(UART_LSR); \
- } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
-
-/* These two functions abstract the actual communications with the
- * debug port.	This is so we can change the underlying communications
- * mechanism without modifying the rest of the code.
- */
-int
-serial_echo_print(const char *s)
-{
-	int     lsr, ier;
-	int     i;
-
-	if (!serial_echo_port) return (0);
-
-	/*
-	 * First save the IER then disable the interrupts
-	 */
-	ier = serial_echo_inb(UART_IER);
-	serial_echo_outb(0x00, UART_IER);
-
-	/*
-	 * Now, do each character
-	 */
-	for (i = 0; *s; i++, s++) {
-		WAIT_FOR_XMITR;
-
-		/* Send the character out. */
-		serial_echo_outb(*s, UART_TX);
-
-		/* if a LF, also do CR... */
-		if (*s == 10) {
-			WAIT_FOR_XMITR;
-			serial_echo_outb(13, UART_TX);
-		}
-	}
-
-	/*
-	 * Finally, Wait for transmitter & holding register to empty
-	 *  and restore the IER
-	 */
-	do {
-		lsr = serial_echo_inb(UART_LSR);
-	} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
-	serial_echo_outb(ier, UART_IER);
-
-	return (0);
-}
-
-
-int
-serial_echo_init(int base)
-{
-	int comstat, hi, lo;
-	
-	if (base != 0x2f8 && base != 0x3f8) {
-		serial_echo_port = 0;
-		return (0);
-	} else
-	  serial_echo_port = base;
-
-	/*
-	 * read the Divisor Latch
-	 */
-	comstat = serial_echo_inb(UART_LCR);
-	serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR);
-	hi = serial_echo_inb(UART_DLM);
-	lo = serial_echo_inb(UART_DLL);
-	serial_echo_outb(comstat, UART_LCR);
-
-	/*
-	 * now do hardwired init
-	 */
-	serial_echo_outb(0x03, UART_LCR); /* No parity, 8 data bits, 1 stop */
-	serial_echo_outb(0x83, UART_LCR); /* Access divisor latch */
-	serial_echo_outb(0x00, UART_DLM); /* 9600 baud */
-	serial_echo_outb(0x0c, UART_DLL);
-	serial_echo_outb(0x03, UART_LCR); /* Done with divisor */
-
-	/* Prior to disabling interrupts, read the LSR and RBR
-	 * registers
-	 */
-	comstat = serial_echo_inb(UART_LSR); /* COM? LSR */
-	comstat = serial_echo_inb(UART_RX);	/* COM? RBR */
-	serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */
-
-	return(0);
-}
-
-#endif /* CONFIG_SERIAL_ECHO */
-
+int fg_console = 0;
+int last_console = 0;
+int want_console = -1;
+int kmsg_redirect = 0;
 
 int vc_cons_allocated(unsigned int i)
 {
@@ -599,7 +496,7 @@
 	__set_origin(__real_origin);
 }
 
-void scrup(int currcons, unsigned int t, unsigned int b)
+static void scrup(int currcons, unsigned int t, unsigned int b)
 {
 	int hardscroll = hardscroll_enabled;
 
@@ -653,7 +550,7 @@
 	}
 }
 
-void
+static void
 scrdown(int currcons, unsigned int t, unsigned int b)
 {
 	unsigned short *s;
@@ -949,7 +846,7 @@
 	respond_string(buf, tty);
 }
 
-/* invoked via ioctl(TIOCLINUX) */
+/* invoked via ioctl(TIOCLINUX) and through set_selection */
 int mouse_reporting(void)
 {
 	int currcons = fg_console;
@@ -957,6 +854,56 @@
 	return report_mouse;
 }
 
+int tioclinux(struct tty_struct *tty, unsigned long arg)
+{
+	char type, data;
+
+	if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
+		return -EINVAL;
+	if (current->tty != tty && !suser())
+		return -EPERM;
+	if (get_user(type, (char *)arg))
+		return -EFAULT;
+	switch (type)
+	{
+		case 2:
+			return set_selection(arg, tty, 1);
+		case 3:
+			return paste_selection(tty);
+		case 4:
+			do_unblank_screen();
+			return 0;
+		case 5:
+			return sel_loadlut(arg);
+		case 6:
+			
+	/*
+	 * Make it possible to react to Shift+Mousebutton.
+	 * Note that 'shift_state' is an undocumented
+	 * kernel-internal variable; programs not closely
+	 * related to the kernel should not use this.
+	 */
+	 		data = shift_state;
+			return put_user(data, (char *) arg);
+		case 7:
+			data = mouse_reporting();
+			return put_user(data, (char *) arg);
+		case 10:
+			set_vesa_blanking(arg);
+			return 0;
+		case 11:	/* set kmsg redirect */
+			if (!suser())
+				return -EPERM;
+			if (get_user(data, (char *)arg+1))
+					return -EFAULT;
+			kmsg_redirect = data;
+			return 0;
+		case 12:	/* get fg_console */
+			return fg_console;
+	}
+	return -EINVAL;
+}
+
 static inline unsigned short *screenpos(int currcons, int offset, int viewed)
 {
 	unsigned short *p = (unsigned short *)(origin + offset);
@@ -1877,7 +1824,8 @@
 	}
 }
 
-void console_print(const char * b)
+#ifdef CONFIG_VT_CONSOLE
+void vt_console_print(const char * b, unsigned count)
 {
 	int currcons = fg_console;
 	unsigned char c;
@@ -1896,15 +1844,12 @@
 
 	if (!vc_cons_allocated(currcons)) {
 		/* impossible */
-		printk("console_print: tty %d not allocated ??\n", currcons+1);
+		printk("vt_console_print: tty %d not allocated ??\n", currcons+1);
 		return;
 	}
 
-#ifdef CONFIG_SERIAL_ECHO
-        serial_echo_print(b);
-#endif /* CONFIG_SERIAL_ECHO */
-
-	while ((c = *(b++)) != 0) {
+	while (count-- > 0) {
+		c = *(b++);
 		if (c == 10 || c == 13 || need_wrap) {
 			if (c != 13)
 				lf(currcons);
@@ -1929,6 +1874,19 @@
 	printing = 0;
 }
 
+static int vt_console_device(void)
+{
+	return MKDEV(TTY_MAJOR, fg_console + 1);
+}
+
+extern void keyboard_wait_for_keypress(void);
+
+struct console vt_console_driver = {
+	vt_console_print, do_unblank_screen,
+        keyboard_wait_for_keypress, vt_console_device
+};
+#endif
+
 /*
  * con_throttle and con_unthrottle are only used for
  * paste_selection(), which has to stuff in a large number of
@@ -2129,10 +2087,6 @@
 		/* This may be suboptimal but is a safe bet - go with it */
 		video_scan_lines = video_font_height * video_num_lines;
 
-#ifdef CONFIG_SERIAL_ECHO
-		serial_echo_init(SERIAL_ECHO_PORT);
-#endif /* CONFIG_SERIAL_ECHO */
-
 		printk("Console: %ld point font, %ld scans\n",
 		       video_font_height, video_scan_lines);
 	}
@@ -2151,8 +2105,10 @@
 	 * initialization and register_console() event from
 	 * within the bus probing code... :-(
 	 */
+#ifdef CONFIG_VT_CONSOLE
 	if (video_type != VIDEO_TYPE_TGAC)
-		register_console(console_print);
+		register_console(&vt_console_driver);
+#endif
 
 	init_bh(CONSOLE_BH, console_bh);
 	return kmem_start;
@@ -2295,7 +2251,7 @@
 /*
  * Allocate the console screen memory.
  */
-int con_open(struct tty_struct *tty, struct file * filp)
+static int con_open(struct tty_struct *tty, struct file * filp)
 {
 	unsigned int	idx;
 	int i;
diff -u --recursive --new-file v2.1.30/linux/drivers/char/esp.c linux/drivers/char/esp.c
--- v2.1.30/linux/drivers/char/esp.c	Wed Feb  5 03:49:56 1997
+++ linux/drivers/char/esp.c	Mon Mar 31 12:52:29 1997
@@ -290,7 +290,7 @@
 				  int event)
 {
 	info->event |= 1 << event;
-	queue_task_irq_off(&info->tqueue, &tq_esp);
+	queue_task(&info->tqueue, &tq_esp);
 	mark_bh(ESP_BH);
 }
 
@@ -354,13 +354,13 @@
 			memmove(info->tty_buf->char_buf,
 				info->tty_buf->char_buf + x_bytes,
 				info->tty_buf->count);
-			queue_task_irq_off(&info->tty_buf->tqueue,
+			queue_task(&info->tty_buf->tqueue,
 						&tq_timer);
 		}
 
-		queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+		queue_task(&tty->flip.tqueue, &tq_timer);
 	} else {
-		queue_task_irq_off(&info->tty_buf->tqueue, &tq_timer);
+		queue_task(&info->tty_buf->tqueue, &tq_timer);
 	}
 
 	restore_flags(flags);
@@ -429,9 +429,9 @@
 		buffer->flag_buf_ptr++;
 		
 		if (buffer == info->tty_buf)
-			queue_task_irq_off(&info->tty_buf->tqueue, &tq_timer);
+			queue_task(&info->tty_buf->tqueue, &tq_timer);
 
-		queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+		queue_task(&tty->flip.tqueue, &tq_timer);
 	}
 
 	if (dma_bytes != num_bytes) {
@@ -560,7 +560,7 @@
 #ifdef SERIAL_DEBUG_OPEN
 			printk("scheduling hangup...");
 #endif
-			queue_task_irq_off(&info->tqueue_hangup,
+			queue_task(&info->tqueue_hangup,
 					   &tq_scheduler);
 		}
 	}
diff -u --recursive --new-file v2.1.30/linux/drivers/char/fbmem.c linux/drivers/char/fbmem.c
--- v2.1.30/linux/drivers/char/fbmem.c	Sun Jan 26 02:07:16 1997
+++ linux/drivers/char/fbmem.c	Wed Apr  2 17:43:21 1997
@@ -247,15 +247,16 @@
 	return 0;
 }
 
-static void 
+static int 
 fb_release(struct inode *inode, struct file *file)
 {
 	int fbidx=GET_FB_IDX(inode->i_rdev);
 	int vidx=GET_FB_VAR_IDX(inode->i_rdev);
 	if (! vidx)
-		return;
+		return 0;
 	if (! (--fb_open_count[fbidx]))
 		fb_curr_open[fbidx]=0;
+	return 0;
 }
 
 static struct file_operations fb_fops = {
diff -u --recursive --new-file v2.1.30/linux/drivers/char/ftape/kernel-interface.c linux/drivers/char/ftape/kernel-interface.c
--- v2.1.30/linux/drivers/char/ftape/kernel-interface.c	Sun Jan 26 02:07:16 1997
+++ linux/drivers/char/ftape/kernel-interface.c	Wed Apr  2 17:43:21 1997
@@ -58,7 +58,7 @@
 static int old_sigmask;
 
 static int ftape_open(struct inode *ino, struct file *filep);
-static void ftape_close(struct inode *ino, struct file *filep);
+static int ftape_close(struct inode *ino, struct file *filep);
 static int ftape_ioctl(struct inode *ino, struct file *filep,
 		       unsigned int command, unsigned long arg);
 static long ftape_read(struct inode *ino, struct file *fp,
@@ -260,7 +260,7 @@
 
 /*      Close ftape device
  */
-static void ftape_close(struct inode *ino, struct file *filep)
+static int ftape_close(struct inode *ino, struct file *filep)
 {
 	TRACE_FUN(4, "ftape_close");
 	int result;
@@ -268,7 +268,7 @@
 	if (!busy_flag || MINOR(ino->i_rdev) != ftape_unit) {
 		TRACE(1, "failed: not busy or wrong unit");
 		TRACE_EXIT;
-		return;		/* keep busy_flag !(?) */
+		return 0;		/* keep busy_flag !(?) */
 	}
 	current->blocked = _BLOCK_ALL;
 	result = _ftape_close();
@@ -281,6 +281,7 @@
 	current->blocked = old_sigmask;		/* restore before open state */
 	TRACE_EXIT;
 	MOD_DEC_USE_COUNT;	/* unlock module in memory */
+	return 0;
 }
 
 /*      Ioctl for ftape device
diff -u --recursive --new-file v2.1.30/linux/drivers/char/keyb_m68k.c linux/drivers/char/keyb_m68k.c
--- v2.1.30/linux/drivers/char/keyb_m68k.c	Thu Nov  7 01:25:56 1996
+++ linux/drivers/char/keyb_m68k.c	Thu Mar 27 14:36:39 1997
@@ -77,6 +77,13 @@
 
 unsigned char kbd_read_mask = 0x01;	/* modified by psaux.c */
 
+struct wait_queue * keypress_wait = NULL;
+
+void keyboard_wait_for_keypress(void)
+{
+	sleep_on(&keypress_wait);
+}
+
 /*
  * global state includes the following, and various static variables
  * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
diff -u --recursive --new-file v2.1.30/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c
--- v2.1.30/linux/drivers/char/keyboard.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/char/keyboard.c	Thu Mar 27 14:36:39 1997
@@ -71,13 +71,19 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-extern void poke_blanked_console(void);
 extern void ctrl_alt_del(void);
 extern void reset_vc(unsigned int new_console);
 extern void scrollback(int);
 extern void scrollfront(int);
 
 unsigned char kbd_read_mask = 0x01;	/* modified by psaux.c */
+
+struct wait_queue * keypress_wait = NULL;
+
+void keyboard_wait_for_keypress(void)
+{
+	sleep_on(&keypress_wait);
+}
 
 /*
  * global state includes the following, and various static variables
diff -u --recursive --new-file v2.1.30/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v2.1.30/linux/drivers/char/lp.c	Thu Feb 27 10:57:29 1997
+++ linux/drivers/char/lp.c	Wed Apr  2 17:43:21 1997
@@ -485,7 +485,7 @@
 	return 0;
 }
 
-static void lp_release(struct inode * inode, struct file * file)
+static int lp_release(struct inode * inode, struct file * file)
 {
 	unsigned int minor = MINOR(inode->i_rdev);
 	unsigned int irq;
@@ -498,6 +498,7 @@
 
 	LP_F(minor) &= ~LP_BUSY;
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c
--- v2.1.30/linux/drivers/char/lp_m68k.c	Sun Jan 26 02:07:16 1997
+++ linux/drivers/char/lp_m68k.c	Wed Apr  2 17:43:21 1997
@@ -392,13 +392,14 @@
 	return 0;
 }
 
-static void lp_release(struct inode *inode, struct file *file)
+static int lp_release(struct inode *inode, struct file *file)
 {
 	int dev =MINOR(inode->i_rdev);
 
 	lp_table[dev]->flags &= ~LP_BUSY;
 	lp_table[dev]->lp_release();
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/char/misc.c linux/drivers/char/misc.c
--- v2.1.30/linux/drivers/char/misc.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/char/misc.c	Thu Mar 27 14:36:39 1997
@@ -179,10 +179,6 @@
 
 EXPORT_SYMBOL(misc_register);
 EXPORT_SYMBOL(misc_deregister);
-#ifndef MODULE
-EXPORT_SYMBOL(set_selection);   /* used by the kmouse module, can only */
-EXPORT_SYMBOL(paste_selection); /* be exported if misc.c is in linked in */
-#endif
 
 #if defined(CONFIG_PROC_FS) && !defined(MODULE)
 static struct proc_dir_entry *proc_misc;	
diff -u --recursive --new-file v2.1.30/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c
--- v2.1.30/linux/drivers/char/msbusmouse.c	Sun Jan 26 02:07:16 1997
+++ linux/drivers/char/msbusmouse.c	Wed Apr  2 17:43:21 1997
@@ -98,15 +98,16 @@
 	return 0;
 }
 
-static void release_mouse(struct inode * inode, struct file * file)
+static int release_mouse(struct inode * inode, struct file * file)
 {
 	fasync_mouse(inode, file, 0);
 	if (--mouse.active)
-		return;
+		return 0;
 	MS_MSE_INT_OFF();
 	mouse.ready = 0; 
 	free_irq(mouse_irq, NULL);
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 static int open_mouse(struct inode * inode, struct file * file)
diff -u --recursive --new-file v2.1.30/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c
--- v2.1.30/linux/drivers/char/pcwd.c	Sun Jan 19 05:47:24 1997
+++ linux/drivers/char/pcwd.c	Wed Apr  2 17:43:21 1997
@@ -394,9 +394,10 @@
 	}
 }
 
-static void pcwd_close(struct inode *ino, struct file *filep)
+static int pcwd_close(struct inode *ino, struct file *filep)
 {
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 static void get_support(void)
diff -u --recursive --new-file v2.1.30/linux/drivers/char/psaux.c linux/drivers/char/psaux.c
--- v2.1.30/linux/drivers/char/psaux.c	Sat Jan 25 13:46:13 1997
+++ linux/drivers/char/psaux.c	Wed Apr  2 17:54:00 1997
@@ -258,11 +258,11 @@
 #endif
 
 
-static void release_aux(struct inode * inode, struct file * file)
+static int release_aux(struct inode * inode, struct file * file)
 {
 	fasync_aux(inode, file, 0);
 	if (--aux_count)
-		return;
+		return 0;
 	/* disable kbd bh to avoid mixing of cmd bytes */
 	disable_bh(KEYBOARD_BH);
 	aux_write_cmd(AUX_INTS_OFF);		/* disable controller ints */
@@ -277,24 +277,26 @@
 	free_irq(AUX_IRQ, NULL);
 #endif
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 #ifdef CONFIG_82C710_MOUSE
-static void release_qp(struct inode * inode, struct file * file)
+static int release_qp(struct inode * inode, struct file * file)
 {
 	unsigned char status;
 
 	fasync_aux(inode, file, 0);
-	if (--qp_count)
-		return;
-	if (!poll_qp_status())
-		printk("Warning: Mouse device busy in release_qp()\n");
-	status = inb_p(qp_status);
-	outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
-	if (!poll_qp_status())
-		printk("Warning: Mouse device busy in release_qp()\n");
-	free_irq(QP_IRQ, NULL);
-	MOD_DEC_USE_COUNT;
+	if (!--qp_count) {
+		if (!poll_qp_status())
+			printk("Warning: Mouse device busy in release_qp()\n");
+		status = inb_p(qp_status);
+		outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
+		if (!poll_qp_status())
+			printk("Warning: Mouse device busy in release_qp()\n");
+		free_irq(QP_IRQ, NULL);
+		MOD_DEC_USE_COUNT;
+	}
+	return 0;
 }
 #endif
 
@@ -544,7 +546,9 @@
 	if (aux_device_present == 0xaa) {
 		printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n");
 	 	aux_present = 1;
+#ifdef CONFIG_VT
 		kbd_read_mask = AUX_OBUF_FULL;
+#endif
 	} else {
 		return -EIO;
 	}
diff -u --recursive --new-file v2.1.30/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.1.30/linux/drivers/char/rtc.c	Mon Jan 27 01:24:28 1997
+++ linux/drivers/char/rtc.c	Wed Apr  2 17:43:21 1997
@@ -462,7 +462,7 @@
 	return 0;
 }
 
-static void rtc_release(struct inode *inode, struct file *file)
+static int rtc_release(struct inode *inode, struct file *file)
 {
 
 	/*
@@ -490,6 +490,7 @@
 
 	rtc_irq_data = 0;
 	rtc_status &= ~RTC_IS_OPEN;
+	return 0;
 }
 
 static unsigned int rtc_poll(struct file *file, poll_table *wait)
diff -u --recursive --new-file v2.1.30/linux/drivers/char/selection.c linux/drivers/char/selection.c
--- v2.1.30/linux/drivers/char/selection.c	Mon Oct 28 13:49:41 1996
+++ linux/drivers/char/selection.c	Thu Mar 27 14:36:39 1997
@@ -11,6 +11,8 @@
  * Now that /dev/vcs exists, most of this can disappear again.
  */
 
+#include <linux/config.h>
+#include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -306,3 +308,6 @@
 	current->state = TASK_RUNNING;
 	return 0;
 }
+
+EXPORT_SYMBOL(set_selection);
+EXPORT_SYMBOL(paste_selection);
diff -u --recursive --new-file v2.1.30/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.1.30/linux/drivers/char/serial.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/char/serial.c	Thu Mar 27 14:36:39 1997
@@ -3429,3 +3429,137 @@
 }
 #endif /* MODULE */
 
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_CONSOLE
+
+#include <linux/console.h>
+
+/*
+ * this defines the index into rs_table for the port to use
+ */
+#ifndef CONFIG_SERIAL_CONSOLE_PORT
+#define CONFIG_SERIAL_CONSOLE_PORT	0
+#endif
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+/* Wait for transmitter & holding register to empty */
+static inline void wait_for_xmitr(struct serial_state *ser)
+{
+	int lsr;
+	do {
+		lsr = inb(ser->port + UART_LSR);
+	} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
+}
+
+/*
+ * Print a string to the serial port trying not to disturb any possible
+ * real use of the port...
+ */
+static int serial_console_write(const char *s, unsigned count)
+{
+	struct serial_state *ser;
+	int ier;
+	unsigned i;
+
+	ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT;
+	/*
+	 * First save the IER then disable the interrupts
+	 */
+	ier = inb(ser->port + UART_IER);
+	outb(0x00, ser->port + UART_IER);
+
+	/*
+	 * Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(ser);
+
+		/* Send the character out. */
+		outb(*s, ser->port + UART_TX);
+
+		/* if a LF, also do CR... */
+		if (*s == 10) {
+			wait_for_xmitr(ser);
+			outb(13, ser->port + UART_TX);
+		}
+	}
+
+	/*
+	 * Finally, Wait for transmitter & holding register to empty
+	 *  and restore the IER
+	 */
+	wait_for_xmitr(ser);
+	outb(ier, ser->port + UART_IER);
+
+	return (0);
+}
+
+/*
+ * Receive character from the serial port
+ */
+static int serial_console_wait_key(void)
+{
+	struct serial_state *ser;
+	int ier;
+	int lsr;
+	int c;
+
+	ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT;
+
+	/*
+	 * First save the IER then disable the interrupts so
+	 * that the real driver for the port does not get the
+	 * character.
+	 */
+	ier = inb(ser->port + UART_IER);
+	outb(0x00, ser->port + UART_IER);
+
+	do {
+		lsr = inb(ser->port + UART_LSR);
+	} while (!(lsr & UART_LSR_DR));
+	c = inb(ser->port + UART_RX);
+
+	/* Restore the interrupts */
+	outb(ier, ser->port + UART_IER);
+
+	return c;
+}
+
+static int serial_console_device(void)
+{
+	return MKDEV(TTYAUX_MAJOR, 64 + CONFIG_SERIAL_CONSOLE_PORT);
+}
+
+long serial_console_init(long kmem_start, long kmem_end)
+{
+	static struct console console = {
+		serial_console_write, 0,
+                serial_console_wait_key, serial_console_device
+	};
+	struct serial_state *ser;
+
+	ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT;
+
+	/* Disable all interrupts, it works in polled mode */
+	outb(0x00, ser->port + UART_IER); 
+
+	/*
+	 * now do hardwired init
+	 */
+	outb(0x03, ser->port + UART_LCR); /* No parity, 8 data bits, 1 stop */
+	outb(0x83, ser->port + UART_LCR); /* Access divisor latch */
+	outb(0x00, ser->port + UART_DLM); /* 9600 baud */
+	outb(0x0c, ser->port + UART_DLL);
+	outb(0x03, ser->port + UART_LCR); /* Done with divisor */
+
+	register_console(&console);
+	return kmem_start;
+}
+
+#endif
diff -u --recursive --new-file v2.1.30/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v2.1.30/linux/drivers/char/softdog.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/char/softdog.c	Wed Apr  2 17:43:21 1997
@@ -83,7 +83,7 @@
 	return 0;
 }
 
-static void softdog_release(struct inode *inode, struct file *file)
+static int softdog_release(struct inode *inode, struct file *file)
 {
 	/*
 	 *	Shut off the timer.
@@ -94,6 +94,7 @@
 	MOD_DEC_USE_COUNT;
 #endif	
 	timer_alive=0;
+	return 0;
 }
 
 static void softdog_ping(void)
diff -u --recursive --new-file v2.1.30/linux/drivers/char/tga.c linux/drivers/char/tga.c
--- v2.1.30/linux/drivers/char/tga.c	Sun Feb  2 05:51:11 1997
+++ linux/drivers/char/tga.c	Thu Mar 27 14:36:39 1997
@@ -37,8 +37,7 @@
 #include "selection.h"
 #include "console_struct.h"
 
-extern void register_console(void (*proc)(const char *));
-extern void console_print(const char *);
+extern struct console vt_console_driver;
 
 /* TGA hardware description (minimal) */
 /*
@@ -485,7 +484,9 @@
 	/*
 	 * FINALLY, we can register TGA as console (whew!)
 	 */
-	register_console(console_print);
+#ifdef CONFIG_VT_CONSOLE
+	register_console(&vt_console_driver);
+#endif
 }
 
 unsigned char PLLbits[7] = { 0x80, 0x04, 0x00, 0x24, 0x44, 0x80, 0xb8 };
diff -u --recursive --new-file v2.1.30/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- v2.1.30/linux/drivers/char/tpqic02.c	Sun Jan 26 02:07:17 1997
+++ linux/drivers/char/tpqic02.c	Wed Apr  2 17:43:21 1997
@@ -2387,7 +2387,7 @@
 } /* qic02_tape_open */
 
 
-static void qic02_tape_release(struct inode * inode, struct file * filp)
+static int qic02_tape_release(struct inode * inode, struct file * filp)
 {
     kdev_t dev = inode->i_rdev;
 
@@ -2420,7 +2420,7 @@
 #ifdef MODULE
     MOD_DEC_USE_COUNT;
 #endif
-    return;
+    return 0;
 } /* qic02_tape_release */
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v2.1.30/linux/drivers/char/tty_io.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/char/tty_io.c	Wed Apr  2 17:43:21 1997
@@ -56,6 +56,7 @@
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/console.h>
 #include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/kd.h>
@@ -87,28 +88,15 @@
 #define TTY_PARANOIA_CHECK
 #define CHECK_TTY_COUNT
 
-extern void do_blank_screen(int nopowersave);
-extern void set_vesa_blanking(const unsigned long arg);
-
 struct termios tty_std_termios;		/* for the benefit of tty drivers  */
 struct tty_driver *tty_drivers = NULL;	/* linked list of tty drivers */
 struct tty_ldisc ldiscs[NR_LDISCS];	/* line disc dispatch table	*/
 
 /*
- * fg_console is the current virtual console,
- * last_console is the last used one,
- * want_console is the console we want to switch to,
- * kmsg_redirect is the console for kernel messages,
  * redirect is the pseudo-tty that console output
  * is redirected to if asked by TIOCCONS.
  */
-int fg_console = 0;
-int last_console = 0;
-int want_console = -1;
-int kmsg_redirect = 0;
 struct tty_struct * redirect = NULL;
-struct wait_queue * keypress_wait = NULL;
-char vt_dont_switch = 0;
 
 static void initialize_tty_struct(struct tty_struct *tty);
 
@@ -116,14 +104,11 @@
 static long tty_write(struct inode *, struct file *, const char *, unsigned long);
 static unsigned int tty_poll(struct file *, poll_table *);
 static int tty_open(struct inode *, struct file *);
-static void tty_release(struct inode *, struct file *);
+static int tty_release(struct inode *, struct file *);
 static int tty_ioctl(struct inode * inode, struct file * file,
 		     unsigned int cmd, unsigned long arg);
 static int tty_fasync(struct inode * inode, struct file * filp, int on);
 
-extern void reset_palette(int currcons) ;
-extern void set_palette(void) ;
-
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 #endif
@@ -509,221 +494,12 @@
 			p->tty = NULL;
 }
 
-/*
- * Sometimes we want to wait until a particular VT has been activated. We
- * do it in a very simple manner. Everybody waits on a single queue and
- * get woken up at once. Those that are satisfied go on with their business,
- * while those not ready go back to sleep. Seems overkill to add a wait
- * to each vt just for this - usually this does nothing!
- */
-static struct wait_queue *vt_activate_queue = NULL;
-
-/*
- * Sleeps until a vt is activated, or the task is interrupted. Returns
- * 0 if activation, -EINTR if interrupted.
- */
-int vt_waitactive(int vt)
-{
-	int retval;
-	struct wait_queue wait = { current, NULL };
-
-	add_wait_queue(&vt_activate_queue, &wait);
-	for (;;) {
-		current->state = TASK_INTERRUPTIBLE;
-		retval = 0;
-		if (vt == fg_console)
-			break;
-		retval = -EINTR;
-		if (current->signal & ~current->blocked)
-			break;
-		schedule();
-	}
-	remove_wait_queue(&vt_activate_queue, &wait);
-	current->state = TASK_RUNNING;
-	return retval;
-}
-
-#define vt_wake_waitactive() wake_up(&vt_activate_queue)
-
-void reset_vc(unsigned int new_console)
-{
-	vt_cons[new_console]->vc_mode = KD_TEXT;
-	kbd_table[new_console].kbdmode = VC_XLATE;
-	vt_cons[new_console]->vt_mode.mode = VT_AUTO;
-	vt_cons[new_console]->vt_mode.waitv = 0;
-	vt_cons[new_console]->vt_mode.relsig = 0;
-	vt_cons[new_console]->vt_mode.acqsig = 0;
-	vt_cons[new_console]->vt_mode.frsig = 0;
-	vt_cons[new_console]->vt_pid = -1;
-	vt_cons[new_console]->vt_newvt = -1;
-	reset_palette (new_console) ;
-}
-
-/*
- * Performs the back end of a vt switch
- */
-void complete_change_console(unsigned int new_console)
-{
-	unsigned char old_vc_mode;
-
-        if ((new_console == fg_console) || (vt_dont_switch))
-                return;
-        if (!vc_cons_allocated(new_console))
-                return;
-	last_console = fg_console;
-
-	/*
-	 * If we're switching, we could be going from KD_GRAPHICS to
-	 * KD_TEXT mode or vice versa, which means we need to blank or
-	 * unblank the screen later.
-	 */
-	old_vc_mode = vt_cons[fg_console]->vc_mode;
-	update_screen(new_console);
-
-	/*
-	 * If this new console is under process control, send it a signal
-	 * telling it that it has acquired. Also check if it has died and
-	 * clean up (similar to logic employed in change_console())
-	 */
-	if (vt_cons[new_console]->vt_mode.mode == VT_PROCESS)
-	{
-		/*
-		 * Send the signal as privileged - kill_proc() will
-		 * tell us if the process has gone or something else
-		 * is awry
-		 */
-		if (kill_proc(vt_cons[new_console]->vt_pid,
-			      vt_cons[new_console]->vt_mode.acqsig,
-			      1) != 0)
-		{
-		/*
-		 * The controlling process has died, so we revert back to
-		 * normal operation. In this case, we'll also change back
-		 * to KD_TEXT mode. I'm not sure if this is strictly correct
-		 * but it saves the agony when the X server dies and the screen
-		 * remains blanked due to KD_GRAPHICS! It would be nice to do
-		 * this outside of VT_PROCESS but there is no single process
-		 * to account for and tracking tty count may be undesirable.
-		 */
-		        reset_vc(new_console);
-		}
-	}
-
-	/*
-	 * We do this here because the controlling process above may have
-	 * gone, and so there is now a new vc_mode
-	 */
-	if (old_vc_mode != vt_cons[new_console]->vc_mode)
-	{
-		if (vt_cons[new_console]->vc_mode == KD_TEXT)
-			do_unblank_screen();
-		else
-			do_blank_screen(1);
-	}
-
-	/* Set the colour palette for this VT */
-	if (vt_cons[new_console]->vc_mode == KD_TEXT)
-		set_palette() ;
-	
-#ifdef CONFIG_SUN_CONSOLE
-	if (old_vc_mode != vt_cons[new_console]->vc_mode)
-	{
-		extern void set_cursor(int currcons);
-		extern void hide_cursor(void);
-
-	 	if (old_vc_mode == KD_GRAPHICS)
-		{
-			extern void sun_clear_margin(void);
-			extern void render_screen(void);
-			
-			sun_clear_margin();
-			render_screen();
-			set_cursor(fg_console);
-		}
-		else
-			hide_cursor();
-	}
-#endif		
-	/*
-	 * Wake anyone waiting for their VT to activate
-	 */
-	vt_wake_waitactive();
-	return;
-}
-
-/*
- * Performs the front-end of a vt switch
- */
-void change_console(unsigned int new_console)
-{
-        if ((new_console == fg_console) || (vt_dont_switch))
-                return;
-        if (!vc_cons_allocated(new_console))
-		return;
-
-	/*
-	 * If this vt is in process mode, then we need to handshake with
-	 * that process before switching. Essentially, we store where that
-	 * vt wants to switch to and wait for it to tell us when it's done
-	 * (via VT_RELDISP ioctl).
-	 *
-	 * We also check to see if the controlling process still exists.
-	 * If it doesn't, we reset this vt to auto mode and continue.
-	 * This is a cheap way to track process control. The worst thing
-	 * that can happen is: we send a signal to a process, it dies, and
-	 * the switch gets "lost" waiting for a response; hopefully, the
-	 * user will try again, we'll detect the process is gone (unless
-	 * the user waits just the right amount of time :-) and revert the
-	 * vt to auto control.
-	 */
-	if (vt_cons[fg_console]->vt_mode.mode == VT_PROCESS)
-	{
-		/*
-		 * Send the signal as privileged - kill_proc() will
-		 * tell us if the process has gone or something else
-		 * is awry
-		 */
-		if (kill_proc(vt_cons[fg_console]->vt_pid,
-			      vt_cons[fg_console]->vt_mode.relsig,
-			      1) == 0)
-		{
-			/*
-			 * It worked. Mark the vt to switch to and
-			 * return. The process needs to send us a
-			 * VT_RELDISP ioctl to complete the switch.
-			 */
-			vt_cons[fg_console]->vt_newvt = new_console;
-			return;
-		}
-
-		/*
-		 * The controlling process has died, so we revert back to
-		 * normal operation. In this case, we'll also change back
-		 * to KD_TEXT mode. I'm not sure if this is strictly correct
-		 * but it saves the agony when the X server dies and the screen
-		 * remains blanked due to KD_GRAPHICS! It would be nice to do
-		 * this outside of VT_PROCESS but there is no single process
-		 * to account for and tracking tty count may be undesirable.
-		 */
-		reset_vc(fg_console);
-
-		/*
-		 * Fall through to normal (VT_AUTO) handling of the switch...
-		 */
-	}
-
-	/*
-	 * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
-	 */
-	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
-		return;
-
-	complete_change_console(new_console);
-}
-
 void wait_for_keypress(void)
 {
-	sleep_on(&keypress_wait);
+        struct console *c = console_drivers;
+        while(c && !c->wait_key)
+                c = c->next;
+        if (c) c->wait_key();
 }
 
 void stop_tty(struct tty_struct *tty)
@@ -1283,11 +1059,16 @@
 		/* noctty = 1; */
 	}
 	if (device == CONSOLE_DEV) {
-		device = MKDEV(TTY_MAJOR, fg_console+1);
+		struct console *c = console_drivers;
+		while(c && !c->device)
+			c = c->next;
+		if (!c)
+                        return -ENODEV;
+                device = c->device();
 		noctty = 1;
 	}
 	minor = MINOR(device);
-	
+
 	retval = init_dev(device, &tty);
 	if (retval)
 		return retval;
@@ -1342,9 +1123,10 @@
  * we have to make the redirection checks after that and on both
  * sides of a pty.
  */
-static void tty_release(struct inode * inode, struct file * filp)
+static int tty_release(struct inode * inode, struct file * filp)
 {
 	release_dev(filp);
+	return 0;
 }
 
 static unsigned int tty_poll(struct file * filp, poll_table * wait)
@@ -1597,56 +1379,6 @@
 	return 0;
 }
 
-static int tioclinux(struct tty_struct *tty, unsigned long arg)
-{
-	char type, data;
-
-	if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
-		return -EINVAL;
-	if (current->tty != tty && !suser())
-		return -EPERM;
-	if (get_user(type, (char *)arg))
-		return -EFAULT;
-	switch (type)
-	{
-		case 2:
-			return set_selection(arg, tty, 1);
-		case 3:
-			return paste_selection(tty);
-		case 4:
-			do_unblank_screen();
-			return 0;
-		case 5:
-			return sel_loadlut(arg);
-		case 6:
-			
-	/*
-	 * Make it possible to react to Shift+Mousebutton.
-	 * Note that 'shift_state' is an undocumented
-	 * kernel-internal variable; programs not closely
-	 * related to the kernel should not use this.
-	 */
-	 		data = shift_state;
-			return put_user(data, (char *) arg);
-		case 7:
-			data = mouse_reporting();
-			return put_user(data, (char *) arg);
-		case 10:
-			set_vesa_blanking(arg);
-			return 0;
-		case 11:	/* set kmsg redirect */
-			if (!suser())
-				return -EPERM;
-			if (get_user(data, (char *)arg+1))
-					return -EFAULT;
-			kmsg_redirect = data;
-			return 0;
-		case 12:	/* get fg_console */
-			return fg_console;
-	}
-	return -EINVAL;
-}
-
 static int tiocttygstruct(struct tty_struct *tty, struct tty_struct *arg)
 {
 	if (copy_to_user(arg, tty, sizeof(*arg)))
@@ -1718,8 +1450,10 @@
 			return put_user(tty->ldisc.num, (int *) arg);
 		case TIOCSETD:
 			return tiocsetd(tty, (int *) arg);
+#ifdef CONFIG_VT
 		case TIOCLINUX:
 			return tioclinux(tty, arg);
+#endif
 		case TIOCTTYGSTRUCT:
 			return tiocttygstruct(tty, (struct tty_struct *) arg);
 	}
@@ -1951,7 +1685,13 @@
 	 * set up the console device so that later boot sequences can 
 	 * inform about problems etc..
 	 */
-	return con_init(kmem_start);
+#ifdef CONFIG_SERIAL_CONSOLE
+	kmem_start = serial_console_init(kmem_start, kmem_end);
+#endif
+#ifdef CONFIG_VT
+	kmem_start = con_init(kmem_start);
+#endif
+	return kmem_start;
 }
 
 static struct tty_driver dev_tty_driver, dev_console_driver;
@@ -1976,7 +1716,7 @@
 	dev_tty_driver.driver_name = "/dev/tty";
 	dev_tty_driver.name = dev_tty_driver.driver_name + 5;
 	dev_tty_driver.name_base = 0;
-	dev_tty_driver.major = TTY_MAJOR;
+	dev_tty_driver.major = TTYAUX_MAJOR;
 	dev_tty_driver.minor_start = 0;
 	dev_tty_driver.num = 1;
 	dev_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM;
@@ -1988,14 +1728,14 @@
 	dev_console_driver = dev_tty_driver;
 	dev_console_driver.driver_name = "/dev/console";
 	dev_console_driver.name = dev_console_driver.driver_name + 5;
-	dev_console_driver.major = TTYAUX_MAJOR;
+	dev_console_driver.major = TTY_MAJOR;
 	dev_console_driver.type = TTY_DRIVER_TYPE_SYSTEM;
 	dev_console_driver.subtype = SYSTEM_TYPE_CONSOLE;
 
 	if (tty_register_driver(&dev_console_driver))
 		panic("Couldn't register /dev/console driver\n");
-	
-#if !CONFIG_NO_KEYBOARD
+
+#ifdef CONFIG_VT
 	kbd_init();
 #endif
 #ifdef CONFIG_ESPSERIAL  /* init ESP before rs, so rs doesn't see the port */
@@ -2020,7 +1760,9 @@
 	riscom8_init();
 #endif
 	pty_init();
+#ifdef CONFIG_VT
 	vcs_init();
+#endif
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.30/linux/drivers/char/vt.c linux/drivers/char/vt.c
--- v2.1.30/linux/drivers/char/vt.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/char/vt.c	Thu Mar 27 14:36:39 1997
@@ -29,7 +29,7 @@
 #include "diacr.h"
 #include "selection.h"
 
-extern char vt_dont_switch;
+char vt_dont_switch = 0;
 extern struct tty_driver console_driver;
 
 #define VT_IS_IN_USE(i)	(console_driver.table[i] && console_driver.table[i]->count)
@@ -80,6 +80,7 @@
 extern int con_set_cmap(unsigned char *cmap);
 extern int con_get_cmap(unsigned char *cmap);
 extern void reset_palette(int currcons);
+extern void set_palette(void) ;
 extern int con_adjust_height(unsigned long fontheight);
 
 extern int video_mode_512ch;
@@ -1143,3 +1144,216 @@
 		return -ENOIOCTLCMD;
 	}
 }
+
+/*
+ * Sometimes we want to wait until a particular VT has been activated. We
+ * do it in a very simple manner. Everybody waits on a single queue and
+ * get woken up at once. Those that are satisfied go on with their business,
+ * while those not ready go back to sleep. Seems overkill to add a wait
+ * to each vt just for this - usually this does nothing!
+ */
+static struct wait_queue *vt_activate_queue = NULL;
+
+/*
+ * Sleeps until a vt is activated, or the task is interrupted. Returns
+ * 0 if activation, -EINTR if interrupted.
+ */
+int vt_waitactive(int vt)
+{
+	int retval;
+	struct wait_queue wait = { current, NULL };
+
+	add_wait_queue(&vt_activate_queue, &wait);
+	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
+		retval = 0;
+		if (vt == fg_console)
+			break;
+		retval = -EINTR;
+		if (current->signal & ~current->blocked)
+			break;
+		schedule();
+	}
+	remove_wait_queue(&vt_activate_queue, &wait);
+	current->state = TASK_RUNNING;
+	return retval;
+}
+
+#define vt_wake_waitactive() wake_up(&vt_activate_queue)
+
+void reset_vc(unsigned int new_console)
+{
+	vt_cons[new_console]->vc_mode = KD_TEXT;
+	kbd_table[new_console].kbdmode = VC_XLATE;
+	vt_cons[new_console]->vt_mode.mode = VT_AUTO;
+	vt_cons[new_console]->vt_mode.waitv = 0;
+	vt_cons[new_console]->vt_mode.relsig = 0;
+	vt_cons[new_console]->vt_mode.acqsig = 0;
+	vt_cons[new_console]->vt_mode.frsig = 0;
+	vt_cons[new_console]->vt_pid = -1;
+	vt_cons[new_console]->vt_newvt = -1;
+	reset_palette (new_console) ;
+}
+
+/*
+ * Performs the back end of a vt switch
+ */
+void complete_change_console(unsigned int new_console)
+{
+	unsigned char old_vc_mode;
+
+        if ((new_console == fg_console) || (vt_dont_switch))
+                return;
+        if (!vc_cons_allocated(new_console))
+                return;
+	last_console = fg_console;
+
+	/*
+	 * If we're switching, we could be going from KD_GRAPHICS to
+	 * KD_TEXT mode or vice versa, which means we need to blank or
+	 * unblank the screen later.
+	 */
+	old_vc_mode = vt_cons[fg_console]->vc_mode;
+	update_screen(new_console);
+
+	/*
+	 * If this new console is under process control, send it a signal
+	 * telling it that it has acquired. Also check if it has died and
+	 * clean up (similar to logic employed in change_console())
+	 */
+	if (vt_cons[new_console]->vt_mode.mode == VT_PROCESS)
+	{
+		/*
+		 * Send the signal as privileged - kill_proc() will
+		 * tell us if the process has gone or something else
+		 * is awry
+		 */
+		if (kill_proc(vt_cons[new_console]->vt_pid,
+			      vt_cons[new_console]->vt_mode.acqsig,
+			      1) != 0)
+		{
+		/*
+		 * The controlling process has died, so we revert back to
+		 * normal operation. In this case, we'll also change back
+		 * to KD_TEXT mode. I'm not sure if this is strictly correct
+		 * but it saves the agony when the X server dies and the screen
+		 * remains blanked due to KD_GRAPHICS! It would be nice to do
+		 * this outside of VT_PROCESS but there is no single process
+		 * to account for and tracking tty count may be undesirable.
+		 */
+		        reset_vc(new_console);
+		}
+	}
+
+	/*
+	 * We do this here because the controlling process above may have
+	 * gone, and so there is now a new vc_mode
+	 */
+	if (old_vc_mode != vt_cons[new_console]->vc_mode)
+	{
+		if (vt_cons[new_console]->vc_mode == KD_TEXT)
+			do_unblank_screen();
+		else
+			do_blank_screen(1);
+	}
+
+	/* Set the colour palette for this VT */
+	if (vt_cons[new_console]->vc_mode == KD_TEXT)
+		set_palette() ;
+	
+#ifdef CONFIG_SUN_CONSOLE
+	if (old_vc_mode != vt_cons[new_console]->vc_mode)
+	{
+		extern void set_cursor(int currcons);
+		extern void hide_cursor(void);
+
+	 	if (old_vc_mode == KD_GRAPHICS)
+		{
+			extern void sun_clear_margin(void);
+			extern void render_screen(void);
+			
+			sun_clear_margin();
+			render_screen();
+			set_cursor(fg_console);
+		}
+		else
+			hide_cursor();
+	}
+#endif		
+      /*
+	 * Wake anyone waiting for their VT to activate
+	 */
+	vt_wake_waitactive();
+	return;
+}
+
+/*
+ * Performs the front-end of a vt switch
+ */
+void change_console(unsigned int new_console)
+{
+        if ((new_console == fg_console) || (vt_dont_switch))
+                return;
+        if (!vc_cons_allocated(new_console))
+		return;
+
+	/*
+	 * If this vt is in process mode, then we need to handshake with
+	 * that process before switching. Essentially, we store where that
+	 * vt wants to switch to and wait for it to tell us when it's done
+	 * (via VT_RELDISP ioctl).
+	 *
+	 * We also check to see if the controlling process still exists.
+	 * If it doesn't, we reset this vt to auto mode and continue.
+	 * This is a cheap way to track process control. The worst thing
+	 * that can happen is: we send a signal to a process, it dies, and
+	 * the switch gets "lost" waiting for a response; hopefully, the
+	 * user will try again, we'll detect the process is gone (unless
+	 * the user waits just the right amount of time :-) and revert the
+	 * vt to auto control.
+	 */
+	if (vt_cons[fg_console]->vt_mode.mode == VT_PROCESS)
+	{
+		/*
+		 * Send the signal as privileged - kill_proc() will
+		 * tell us if the process has gone or something else
+		 * is awry
+		 */
+		if (kill_proc(vt_cons[fg_console]->vt_pid,
+			      vt_cons[fg_console]->vt_mode.relsig,
+			      1) == 0)
+		{
+			/*
+			 * It worked. Mark the vt to switch to and
+			 * return. The process needs to send us a
+			 * VT_RELDISP ioctl to complete the switch.
+			 */
+			vt_cons[fg_console]->vt_newvt = new_console;
+			return;
+		}
+
+		/*
+		 * The controlling process has died, so we revert back to
+		 * normal operation. In this case, we'll also change back
+		 * to KD_TEXT mode. I'm not sure if this is strictly correct
+		 * but it saves the agony when the X server dies and the screen
+		 * remains blanked due to KD_GRAPHICS! It would be nice to do
+		 * this outside of VT_PROCESS but there is no single process
+		 * to account for and tracking tty count may be undesirable.
+		 */
+		reset_vc(fg_console);
+
+		/*
+		 * Fall through to normal (VT_AUTO) handling of the switch...
+		 */
+	}
+
+	/*
+	 * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
+	 */
+	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+		return;
+
+	complete_change_console(new_console);
+}
+
diff -u --recursive --new-file v2.1.30/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v2.1.30/linux/drivers/char/wdt.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/char/wdt.c	Wed Apr  2 17:43:21 1997
@@ -275,7 +275,7 @@
 	}
 }
 
-static void wdt_release(struct inode *inode, struct file *file)
+static int wdt_release(struct inode *inode, struct file *file)
 {
 	if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
 	{
@@ -286,6 +286,7 @@
 		wdt_is_open=0;
 	}
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- v2.1.30/linux/drivers/isdn/isdn_common.c	Thu Feb 27 10:57:29 1997
+++ linux/drivers/isdn/isdn_common.c	Wed Apr  2 17:43:21 1997
@@ -1790,7 +1790,7 @@
 	return -ENODEV;
 }
 
-static void
+static int
 isdn_close(struct inode *ino, struct file *filep)
 {
 	uint minor = MINOR(ino->i_rdev);
@@ -1807,13 +1807,13 @@
 					q->next = p->next;
 				else
 					dev->infochain = (infostruct *) (p->next);
-				return;
+				return 0;
 			}
 			q = p;
 			p = (infostruct *) (p->next);
 		}
 		printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n");
-		return;
+                return 0;
 	}
 	if (minor < ISDN_MINOR_CTRL) {
 		drvidx = isdn_minor2drv(minor);
@@ -1822,23 +1822,24 @@
 		c.command = ISDN_CMD_UNLOCK;
 		c.driver = drvidx;
 		(void) dev->drv[drvidx]->interface->command(&c);
-		return;
+		return 0;
 	}
 	if (minor <= ISDN_MINOR_CTRLMAX) {
 		drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
 		if (drvidx < 0)
-			return;
+			return 0;
 		if (dev->profd == current)
 			dev->profd = NULL;
 		c.command = ISDN_CMD_UNLOCK;
 		c.driver = drvidx;
 		(void) dev->drv[drvidx]->interface->command(&c);
-		return;
+		return 0;
 	}
 #ifdef CONFIG_ISDN_PPP
 	if (minor <= ISDN_MINOR_PPPMAX)
 		isdn_ppp_release(minor - ISDN_MINOR_PPP, filep);
 #endif
+	return 0;
 }
 
 static struct file_operations isdn_fops =
diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c501.c linux/drivers/net/3c501.c
--- v2.1.30/linux/drivers/net/3c501.c	Sun Feb  2 05:18:35 1997
+++ linux/drivers/net/3c501.c	Mon Mar 31 12:52:29 1997
@@ -714,6 +714,7 @@
 		skb->protocol=eth_type_trans(skb,dev);
 		netif_rx(skb);
 		lp->stats.rx_packets++;
+		lp->stats.rx_bytes+=pkt_len;
 	}
 	return;
 }
diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v2.1.30/linux/drivers/net/3c507.c	Sun Feb  2 05:18:35 1997
+++ linux/drivers/net/3c507.c	Mon Mar 31 10:26:12 1997
@@ -229,7 +229,7 @@
 
   */
 
-unsigned short init_words[] = {
+static unsigned short init_words[] = {
 	/*	System Configuration Pointer (SCP). */
 	0x0000,					/* Set bus size to 16 bits. */
 	0,0,					/* pad words. */
@@ -286,7 +286,7 @@
 static struct net_device_stats *el16_get_stats(struct device *dev);
 
 static void hardware_send_packet(struct device *dev, void *buf, short length);
-void init_82586_mem(struct device *dev);
+static void init_82586_mem(struct device *dev);
 
 
 #ifdef HAVE_DEVLIST
@@ -687,7 +687,7 @@
 
 }
 
-void init_82586_mem(struct device *dev)
+static void init_82586_mem(struct device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
 	short ioaddr = dev->base_addr;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v2.1.30/linux/drivers/net/3c509.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/net/3c509.c	Mon Mar 31 12:52:29 1997
@@ -667,7 +667,9 @@
 				skb->protocol=eth_type_trans(skb,dev);
 				netif_rx(skb);
 				outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
+				lp->stats.rx_bytes+=skb->len;
 				lp->stats.rx_packets++;
+				lp->stats.rx_bytes+=pkt_len;
 				continue;
 			} else if (el3_debug)
 				printk("%s: Couldn't allocate a sk_buff of size %d.\n",
diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c523.c linux/drivers/net/3c523.c
--- v2.1.30/linux/drivers/net/3c523.c	Sun Feb  2 05:18:35 1997
+++ linux/drivers/net/3c523.c	Mon Mar 31 12:52:29 1997
@@ -982,6 +982,7 @@
             skb->protocol=eth_type_trans(skb,dev);
             netif_rx(skb);
             p->stats.rx_packets++;
+            p->stats.rx_bytes+=totlen;
           } else {
             p->stats.rx_dropped++;
 		  }
diff -u --recursive --new-file v2.1.30/linux/drivers/net/8390.c linux/drivers/net/8390.c
--- v2.1.30/linux/drivers/net/8390.c	Sun Feb  2 05:18:35 1997
+++ linux/drivers/net/8390.c	Mon Mar 31 12:52:30 1997
@@ -32,6 +32,7 @@
   Paul Gortmaker	: rewrite Rx overrun handling as per NS specs.
   Alexey Kuznetsov	: use the 8390's six bit hash multicast filter.
   Paul Gortmaker	: tweak ANK's above multicast changes a bit.
+  Paul Gortmaker	: update packet statistics for v2.1.x
 
 
   Sources:
@@ -152,6 +153,7 @@
 		if (tickssofar < TX_TIMEOUT ||	(tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) {
 			return 1;
 		}
+		ei_local->stat.tx_errors++;
 		isr = inb(e8390_base+EN0_ISR);
 		if (dev->start == 0) {
 			printk("%s: xmit on stopped card\n", dev->name);
@@ -160,8 +162,8 @@
 
 		/*
 		 * Note that if the Tx posted a TX_ERR interrupt, then the
-		 * error will have been handled from the interrupt handler.
-		 * and not here.
+		 * error will have been handled from the interrupt handler
+		 * and not here. Error statistics are handled there as well.
 		 */
 
 		printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
@@ -186,13 +188,12 @@
     if (dev->interrupt) {
 	printk("%s: Tx request while isr active.\n",dev->name);
 	outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+	ei_local->stat.tx_errors++;
 	return 1;
     }
     ei_local->irqlock = 1;
 
     send_length = ETH_ZLEN < length ? length : ETH_ZLEN;
-
-    ei_local->stat.tx_bytes+=send_length;
     
 #ifdef EI_PINGPONG
 
@@ -223,6 +224,7 @@
 	ei_local->irqlock = 0;
 	dev->tbusy = 1;
 	outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+	ei_local->stat.tx_errors++;
 	return 1;
     }
 
@@ -270,6 +272,7 @@
     outb_p(ENISR_ALL, e8390_base + EN0_IMR);
 
     dev_kfree_skb (skb, FREE_WRITE);
+    ei_local->stat.tx_bytes += send_length;
     
     return 0;
 }
@@ -393,14 +396,12 @@
 
     if (tx_was_aborted)
 		ei_tx_intr(dev);
-
-    /*
-     * Note: NCR reads zero on 16 collisions so we add them
-     * in by hand. Somebody might care...
-     */
-    if (txsr & ENTSR_ABT)
-	ei_local->stat.collisions += 16;
-	
+    else {
+		ei_local->stat.tx_errors++;
+		if (txsr & ENTSR_CRS) ei_local->stat.tx_carrier_errors++;
+		if (txsr & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++;
+		if (txsr & ENTSR_OWC) ei_local->stat.tx_window_errors++;
+    }
 }
 
 /* We have finished a transmit: check for errors and then trigger the next
@@ -467,7 +468,10 @@
 	ei_local->stat.tx_packets++;
     else {
 	ei_local->stat.tx_errors++;
-	if (status & ENTSR_ABT) ei_local->stat.tx_aborted_errors++;
+	if (status & ENTSR_ABT) {
+		ei_local->stat.tx_aborted_errors++;
+		ei_local->stat.collisions += 16;
+	}
 	if (status & ENTSR_CRS) ei_local->stat.tx_carrier_errors++;
 	if (status & ENTSR_FU)  ei_local->stat.tx_fifo_errors++;
 	if (status & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++;
@@ -490,7 +494,7 @@
     int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page;
     
     while (++rx_pkt_count < 10) {
-		int pkt_len;
+		int pkt_len, pkt_stat;
 		
 		/* Get the rx page (incoming packet pointer). */
 		outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD);
@@ -515,6 +519,7 @@
 		ei_get_8390_hdr(dev, &rx_frame, this_frame);
 		
 		pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr);
+		pkt_stat = rx_frame.status;
 		
 		next_frame = this_frame + 1 + ((pkt_len+4)>>8);
 		
@@ -537,7 +542,8 @@
 					   dev->name, rx_frame.count, rx_frame.status,
 					   rx_frame.next);
 			ei_local->stat.rx_errors++;
-		} else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) {
+			ei_local->stat.rx_length_errors++;
+		} else if ((pkt_stat & 0x0F) == ENRSR_RXOK) {
 			struct sk_buff *skb;
 			
 			skb = dev_alloc_skb(pkt_len+2);
@@ -552,18 +558,21 @@
 				skb->dev = dev;
 				skb_put(skb, pkt_len);	/* Make room */
 				ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
-				ei_local->stat.rx_bytes+=skb->len;
 				skb->protocol=eth_type_trans(skb,dev);
 				netif_rx(skb);
 				ei_local->stat.rx_packets++;
+				ei_local->stat.rx_bytes += pkt_len;
+				if (pkt_stat & ENRSR_PHY)
+					ei_local->stat.multicast++;
 			}
 		} else {
-			int errs = rx_frame.status;
 			if (ei_debug)
 				printk("%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
 					   dev->name, rx_frame.status, rx_frame.next,
 					   rx_frame.count);
-			if (errs & ENRSR_FO)
+			ei_local->stat.rx_errors++;
+			/* NB: The NIC counts CRC, frame and missed errors. */
+			if (pkt_stat & ENRSR_FO)
 				ei_local->stat.rx_fifo_errors++;
 		}
 		next_frame = rx_frame.next;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.1.30/linux/drivers/net/Config.in	Thu Mar 27 14:40:03 1997
+++ linux/drivers/net/Config.in	Mon Mar 31 12:52:30 1997
@@ -180,5 +180,6 @@
 
 if [ "$CONFIG_X25" != "n" ]; then
   tristate 'LAPB over Ethernet driver' CONFIG_LAPBETHER
+  tristate 'X.25 async driver' CONFIG_X25_ASY
 fi
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.1.30/linux/drivers/net/Makefile	Thu Mar 27 14:40:03 1997
+++ linux/drivers/net/Makefile	Mon Mar 31 12:52:30 1997
@@ -690,6 +690,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_X25_ASY),y)
+L_OBJS += x25_asy.o
+else
+  ifeq ($(CONFIG_X25_ASY),m)
+  M_OBJS += x25_asy.o
+  endif
+endif
+
 include $(TOPDIR)/Rules.make
 
 clean:
diff -u --recursive --new-file v2.1.30/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.1.30/linux/drivers/net/Space.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/net/Space.c	Mon Mar 31 12:52:30 1997
@@ -348,6 +348,16 @@
 #undef NEXT_DEV
 #define NEXT_DEV (&slip_bootstrap)
 #endif	/* SLIP */
+
+#if defined(X25_ASY) || defined(CONFIG_X25_ASY)
+	/* To be exact, this node just hooks the initialization
+	   routines to the device structures.			*/
+extern int x25_asy_init_ctrl_dev(struct device *);
+static struct device x25_asy_bootstrap = {
+  "x25_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, x25_asy_init_ctrl_dev, };
+#undef NEXT_DEV
+#define NEXT_DEV (&x25_asy_bootstrap)
+#endif	/* X25_ASY */
   
 #if defined(CONFIG_MKISS)
 	/* To be exact, this node just hooks the initialization
diff -u --recursive --new-file v2.1.30/linux/drivers/net/a2065.c linux/drivers/net/a2065.c
--- v2.1.30/linux/drivers/net/a2065.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/a2065.c	Mon Mar 31 12:52:30 1997
@@ -582,16 +582,6 @@
 		return status;
 	}
 
-	if (skb == NULL) {
-		dev_tint (dev);
-		printk ("skb is NULL\n");
-		return 0;
-	}
-
-	if (skb->len <= 0) {
-		printk ("skb len is %id\n", skb->len);
-		return 0;
-	}
 	/* Block a timer-based transmit from overlapping. */
 #ifdef OLD_METHOD
 	dev->tbusy = 1;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/apricot.c linux/drivers/net/apricot.c
--- v2.1.30/linux/drivers/net/apricot.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/apricot.c	Mon Mar 31 12:52:30 1997
@@ -240,7 +240,7 @@
     do
     {
         lp->scb.rfd = rfd->next;
-        kfree_s(rfd, sizeof(struct i596_rfd));
+        kfree(rfd);
         rfd = lp->scb.rfd;
     }
     while (rfd != lp->rx_tail);
@@ -354,6 +354,7 @@
 	    skb->protocol=eth_type_trans(skb,dev);
 	    netif_rx(skb);
 	    lp->stats.rx_packets++;
+	    lp->stats.rx_bytes+=pkt_len;
 
 	    if (i596_debug > 4) print_eth(skb->data);
 	}
@@ -411,15 +412,13 @@
 		lp->stats.tx_aborted_errors++;
 
 		ptr->next = (struct i596_cmd * ) I596_NULL;
-		kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
+		kfree(tx_cmd);
 		break;
 	    }
 	    case CmdMulticastList:
 	    {
-		unsigned short count = *((unsigned short *) (ptr + 1));
-
 		ptr->next = (struct i596_cmd * ) I596_NULL;
-		kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
+		kfree(ptr);
 		break;
 	    }
 	    default:
@@ -650,6 +649,7 @@
 	    i596_add_cmd(dev, (struct i596_cmd *)tx_cmd);
 
 	    lp->stats.tx_packets++;
+	    lp->stats.tx_bytes+=length;
 	}
     }
 
@@ -821,7 +821,7 @@
 
 
 		    ptr->next = (struct i596_cmd * ) I596_NULL;
-		    kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
+		    kfree(tx_cmd);
 		    break;
 		}
 		case CmdMulticastList:
@@ -829,7 +829,7 @@
 		    unsigned short count = *((unsigned short *) (ptr + 1));
 
 		    ptr->next = (struct i596_cmd * ) I596_NULL;
-		    kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
+		    kfree(ptr);
 		    break;
 		}
 		case CmdTDR:
@@ -1032,7 +1032,7 @@
 cleanup_module(void)
 {
     unregister_netdev(&dev_apricot);
-    kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf);
+    kfree(dev_apricot.mem_start);
     dev_apricot.priv = NULL;
 
     /* If we don't do this, we can't re-insmod it later. */
diff -u --recursive --new-file v2.1.30/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- v2.1.30/linux/drivers/net/arcnet.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/arcnet.c	Mon Mar 31 12:52:30 1997
@@ -1568,17 +1568,6 @@
 		return 1;
 	}
 
-	/* If some higher layer thinks we've missed a tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		BUGMSG(D_NORMAL,"tx passed null skb (status=%Xh, inTX=%d, tickssofar=%ld)\n",
-			ARCSTATUS,lp->intx,jiffies-dev->trans_start);
-		lp->stats.tx_errors++;
-		dev_tint(dev);
-		return 0;
-	}
-
 	if (lp->txready)	/* transmit already in progress! */
 	{
 		BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n",
diff -u --recursive --new-file v2.1.30/linux/drivers/net/ariadne.c linux/drivers/net/ariadne.c
--- v2.1.30/linux/drivers/net/ariadne.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/ariadne.c	Mon Mar 31 12:52:30 1997
@@ -581,14 +581,6 @@
 	return(0);
     }
 
-    if (skb == NULL) {
-	dev_tint(dev);
-	return(0);
-    }
-
-    if (skb->len <= 0)
-	return(0);
-
 #if 0
     if (ariadne_debug > 3) {
 	board->Lance.RAP = CSR0;	/* PCnet-ISA Controller Status */
diff -u --recursive --new-file v2.1.30/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v2.1.30/linux/drivers/net/at1700.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/at1700.c	Mon Mar 31 12:52:30 1997
@@ -265,8 +265,8 @@
 
 	dev->open		= net_open;
 	dev->stop		= net_close;
-	dev->hard_start_xmit = net_send_packet;
-	dev->get_stats	= net_get_stats;
+	dev->hard_start_xmit	= net_send_packet;
+	dev->get_stats		= net_get_stats;
 	dev->set_multicast_list = &set_multicast_list;
 
 	/* Fill in the fields of 'dev' with ethernet-generic values. */
@@ -390,14 +390,6 @@
 		lp->tx_started = 0;
 		lp->tx_queue = 0;
 		lp->tx_queue_len = 0;
-	}
-
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
 	}
 
 	/* Block a timer-based transmit from overlapping.  This could better be
diff -u --recursive --new-file v2.1.30/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c
--- v2.1.30/linux/drivers/net/atari_bionet.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/atari_bionet.c	Mon Mar 31 12:52:30 1997
@@ -436,13 +436,6 @@
 	struct net_local *lp = (struct net_local *)dev->priv;
 	unsigned long flags;
 
-	/* If some higher layer thinks we've missed an tx-done interrupt we
-	 * are passed NULL. Caution: dev_tint() handles the cli()/sti() itself.
-	 */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
 	/* Block a timer-based transmit from overlapping.  This could better be
 	 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
 	 */
@@ -473,12 +466,11 @@
 
 		dev->trans_start = jiffies;
 		dev->tbusy	 = 0;
+		lp->stats.tx_packets++;
+		lp->stats.tx_bytes+=length;
 	}
 	dev_kfree_skb(skb, FREE_WRITE);
 
-	/* You might need to clean up and record Tx statistics here.
-	 */
-	lp->stats.tx_packets++;
 	return 0;
 }
 
@@ -539,6 +531,7 @@
 			memcpy(skb->data, nic_packet->buffer, pkt_len);
 			netif_rx(skb);
 			lp->stats.rx_packets++;
+			lp->stats.rx_bytes+=pkt_len;
 		}
 	}
 
@@ -612,9 +605,10 @@
 #undef	NEXT_DEV
 #define NEXT_DEV	(&bio_dev)
 
+static char bio_name[16];
 static struct device bio_dev =
 	{
-		"        ",	/* filled in by register_netdev() */
+		bio_name,	/* filled in by register_netdev() */
 		0, 0, 0, 0,	/* memory */
 		0, 0,		/* base, irq */
 		0, 0, 0, NEXT_DEV, bionet_probe,
diff -u --recursive --new-file v2.1.30/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c
--- v2.1.30/linux/drivers/net/atari_pamsnet.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/atari_pamsnet.c	Mon Mar 31 12:52:30 1997
@@ -699,13 +699,6 @@
 	struct net_local *lp = (struct net_local *)dev->priv;
 	unsigned long flags;
 
-	/* If some higher layer thinks we've missed an tx-done interrupt we
-	 * are passed NULL. Caution: dev_tint() handles the cli()/sti() itself.
-	 */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
 	/* Block a timer-based transmit from overlapping.  This could better be
 	 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
 	 */
@@ -738,12 +731,11 @@
 
 		dev->trans_start = jiffies;
 		dev->tbusy	 = 0;
+		lp->stats.tx_packets++;
+		lp->stats.tx_bytes+=length;
 	}
 	dev_kfree_skb(skb, FREE_WRITE);
 
-	/* You might need to clean up and record Tx statistics here.
-	 */
-	lp->stats.tx_packets++;
 	return 0;
 }
 
@@ -806,6 +798,7 @@
 			memcpy(skb->data, nic_packet->buffer, pkt_len);
 			netif_rx(skb);
 			lp->stats.rx_packets++;
+			lp->stats.rx_bytes+=pkt_len;
 		}
 	}
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v2.1.30/linux/drivers/net/atp.c	Sun Feb  2 05:18:36 1997
+++ linux/drivers/net/atp.c	Mon Mar 31 12:52:30 1997
@@ -434,14 +434,6 @@
 		dev->trans_start = jiffies;
 	}
 
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	/* Block a timer-based transmit from overlapping.  This could better be
 	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 	if (set_bit(0, (void*)&dev->tbusy) != 0)
diff -u --recursive --new-file v2.1.30/linux/drivers/net/bpqether.c linux/drivers/net/bpqether.c
--- v2.1.30/linux/drivers/net/bpqether.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/net/bpqether.c	Mon Mar 31 12:52:30 1997
@@ -241,13 +241,14 @@
 		return 0;
 	}
 
-	((struct bpqdev *)dev->priv)->stats.rx_packets++;
-
 	len = skb->data[0] + skb->data[1] * 256 - 5;
 
 	skb_pull(skb, 2);	/* Remove the length bytes */
 	skb_trim(skb, len);	/* Set the length of the data */
 
+	((struct bpqdev *)dev->priv)->stats.rx_packets++;
+	((struct bpqdev *)dev->priv)->stats.rx_bytes+=len;
+
 	ptr = skb_push(skb, 1);
 	*ptr = 0;
 
@@ -314,7 +315,6 @@
 	*ptr++ = (size + 5) / 256;
 
 	bpq = (struct bpqdev *)dev->priv;
-	bpq->stats.tx_packets++;
 
 	if ((dev = bpq_get_ether_dev(dev)) == NULL) {
 		bpq->stats.tx_dropped++;
@@ -324,7 +324,9 @@
 
 	skb->dev = dev;
 	dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
-
+	bpq->stats.tx_packets++;
+	bpq->stats.tx_bytes+=skb->len;
+  
 	dev_queue_xmit(skb);
 
 	return 0;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- v2.1.30/linux/drivers/net/cs89x0.c	Thu Feb 27 10:57:30 1997
+++ linux/drivers/net/cs89x0.c	Mon Mar 31 12:52:30 1997
@@ -25,6 +25,8 @@
                     : as an example. Disabled autoprobing in init_module(),
                     : not a good thing to do to other devices while Linux
                     : is running from all accounts.
+                    
+  Alan Cox          : Removed 1.2 support, added 2.1 extra counters.
 */
 
 static char *version =
@@ -32,10 +34,6 @@
 
 /* ======================= configure the driver here ======================= */
 
-/* we also support 1.2.13 */
-#define SUPPORTS_1_2_13 0
-
-
 /* use 0 for production, 1 for verification, >2 for debug */
 #ifndef NET_DEBUG
 #define NET_DEBUG 2
@@ -120,13 +118,8 @@
 static int cs89x0_probe1(struct device *dev, int ioaddr);
 static int net_open(struct device *dev);
 static int	net_send_packet(struct sk_buff *skb, struct device *dev);
-#if SUPPORTS_1_2_13
-static void net_interrupt(int irq, struct pt_regs *regs);
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
-#else
 static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void set_multicast_list(struct device *dev);
-#endif
 static void net_rx(struct device *dev);
 static int net_close(struct device *dev);
 static struct net_device_stats *net_get_stats(struct device *dev);
@@ -175,14 +168,14 @@
 }
 #endif
 
-int inline
+static int inline
 readreg(struct device *dev, int portno)
 {
 	outw(portno, dev->base_addr + ADD_PORT);
 	return inw(dev->base_addr + DATA_PORT);
 }
 
-void inline
+static void inline
 writereg(struct device *dev, int portno, int value)
 {
 	outw(portno, dev->base_addr + ADD_PORT);
@@ -190,19 +183,19 @@
 }
 
 
-int inline
+static int inline
 readword(struct device *dev, int portno)
 {
 	return inw(dev->base_addr + portno);
 }
 
-void inline
+static void inline
 writeword(struct device *dev, int portno, int value)
 {
 	outw(value, dev->base_addr + portno);
 }
 
-int
+static int
 wait_eeprom_ready(struct device *dev)
 {
 	int timeout = jiffies;
@@ -430,7 +423,7 @@
 }
 
 
-void
+static void
 control_dc_dc(struct device *dev, int on_not_off)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
@@ -496,7 +489,7 @@
 }
 
 /* send a test packet - return true if carrier bits are ok */
-int
+static int
 send_test_pkt(struct device *dev)
 {
 	int ioaddr = dev->base_addr;
@@ -541,7 +534,7 @@
 }
 
 
-int
+static int
 detect_aui(struct device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
@@ -557,7 +550,7 @@
 		return 0;
 }
 
-int
+static int
 detect_bnc(struct device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
@@ -574,7 +567,7 @@
 }
 
 
-void
+static void
 write_irq(struct device *dev, int chip_type, int irq)
 {
 	int i;
@@ -611,29 +604,11 @@
 		/* Allow interrupts to be generated by the chip */
 		writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
 		for (i = 2; i < CS8920_NO_INTS; i++) if ((1 << dev->irq) & lp->irq_map) {
-#if SUPPORTS_1_2_13
-			if (request_irq (i, NULL, 0, "bogus") != -EBUSY) {
-#else
-			if (request_irq (i, NULL, 0, "bogus", NULL) != -EBUSY) {
-#endif
-#if 0
-				/* Twinkle the interrupt, and check if it's seen. */
-				autoirq_setup(0);
-				write_irq(dev, lp->chip_type, i);
-				writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT);
-				if (i == autoirq_report(0)	 /* It's a good IRQ line! */
-				    && request_irq (dev->irq = i, &net_interrupt, 0, "cs89x0") == 0)
-					break;
-#else
+			if (request_irq (i, NULL, 0, "cs8920", NULL) != -EBUSY) {
 				write_irq(dev, lp->chip_type, i);
 				writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT);
-#if SUPPORTS_1_2_13
-				if (request_irq (dev->irq = i, &net_interrupt, 0, "cs89x0") == 0)
-#else
 				if (request_irq (dev->irq = i, &net_interrupt, 0, "cs89x0", NULL) == 0)
-#endif
 					break;
-#endif
 			}
 		}
 
@@ -650,11 +625,7 @@
 		}
 		writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
 		write_irq(dev, lp->chip_type, dev->irq);
-#if SUPPORTS_1_2_13
-		if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0")) {
-#else
 		if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0", NULL)) {
-#endif
 			return -EAGAIN;
 		}
 	}
@@ -685,11 +656,7 @@
                 printk("%s: EEPROM is configured for unavailable media\n", dev->name);
         release_irq:
                 writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
-#if SUPPORTS_1_2_13
-                free_irq(dev->irq);
-#else
                 free_irq(dev->irq, NULL);
-#endif
                 irq2dev_map[dev->irq] = 0;
 		return -EAGAIN;
 	}
@@ -782,14 +749,6 @@
 		dev->trans_start = jiffies;
 	}
 
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	/* Block a timer-based transmit from overlapping.  This could better be
 	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 	if (set_bit(0, (void*)&dev->tbusy) != 0)
@@ -832,12 +791,7 @@
 
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
-static void
-#if SUPPORTS_1_2_13
-net_interrupt(int irq, struct pt_regs * regs)
-#else
-net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-#endif
+static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -946,11 +900,11 @@
 	if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
                                  dev->name, length,
                                  (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
-#if !SUPPORTS_1_2_13
+
         skb->protocol=eth_type_trans(skb,dev);
-#endif
 	netif_rx(skb);
 	lp->stats.rx_packets++;
+	lp->stats.rx_bytes+=skb->len;
 	return;
 }
 
@@ -966,11 +920,7 @@
 
 	dev->start = 0;
 
-#if SUPPORTS_1_2_13
-	free_irq(dev->irq);
-#else
 	free_irq(dev->irq, NULL);
-#endif
 
 	irq2dev_map[dev->irq] = 0;
 
@@ -997,33 +947,6 @@
 	return &lp->stats;
 }
 
-#if SUPPORTS_1_2_13
-/* Set or clear the multicast filter for this adaptor.
-   num_addrs == -1	Promiscuous mode, receive all packets
-   num_addrs == 0	Normal mode, clear multicast list
-   num_addrs > 0	Multicast mode, receive normal and MC packets, and do
-			best-effort filtering.
- */
-static void
-set_multicast_list(struct device *dev, int num_addrs, void *addrs)
-{
-	struct net_local *lp = (struct net_local *)dev->priv;
-
-	if (num_addrs == 0)
-		lp->rx_mode = 0;
-	else if (num_addrs > 0)
-		lp->rx_mode = RX_MULTCAST_ACCEPT;
-	else if (num_addrs == -1)
-		lp->rx_mode = RX_ALL_ACCEPT;
-
-	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
-
-	/* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
-	writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
-	     (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
-
-}
-#else
 static void set_multicast_list(struct device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
@@ -1047,11 +970,9 @@
 	writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
 	     (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
 }
-#endif
 
 
-static int
-set_mac_address(struct device *dev, void *addr)
+static int set_mac_address(struct device *dev, void *addr)
 {
 	int i;
 	if (dev->start)
@@ -1066,10 +987,9 @@
 
 	return 0;
 }
+
 #ifdef MODULE
-#if SUPPORTS_1_2_13
-char kernel_version[] = UTS_RELEASE;
-#endif
+
 static char namespace[16] = "";
 static struct device dev_cs89x0 = {
         NULL,
diff -u --recursive --new-file v2.1.30/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.1.30/linux/drivers/net/de4x5.c	Thu Mar 27 14:40:03 1997
+++ linux/drivers/net/de4x5.c	Mon Mar 31 12:52:30 1997
@@ -353,6 +353,7 @@
      0x00,0x18,}
 };
 
+#undef DE4X5_VERBOSE     /* define to get more verbose startup messages */
 
 #ifdef DE4X5_DEBUG
 static int de4x5_debug = DE4X5_DEBUG;
@@ -645,7 +646,7 @@
 ** Also have to save the irq for those cards whose hardware designers
 ** can't follow the PCI to PCI Bridge Architecture spec.
 */
-struct {
+static struct {
     int chipset;
     int bus;
     int irq;
@@ -768,7 +769,9 @@
 static void    yawn(struct device *dev, int state);
 static int     de4x5_dev_index(char *s);
 static void    link_modules(struct device *dev, struct device *tmp);
+#ifdef MODULE
 static struct  device *unlink_modules(struct device *p);
+#endif
 static void    de4x5_dbg_open(struct device *dev);
 static void    de4x5_dbg_mii(struct device *dev, int k);
 static void    de4x5_dbg_media(struct device *dev);
@@ -807,7 +810,7 @@
     int chipset;
     int (*fn)(struct device *);
 };
-struct InfoLeaf infoleaf_array[] = {
+static struct InfoLeaf infoleaf_array[] = {
     {DC21041, dc21041_infoleaf},
     {DC21140, dc21140_infoleaf},
     {DC21142, dc21142_infoleaf},
@@ -1068,7 +1071,10 @@
 	printk("      and requires IRQ%d (provided by %s).\n", dev->irq,
 	       ((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG"));
 
-	printk("INFOLEAF_SIZE: %d\nCOMPACT: %d\n", INFOLEAF_SIZE, COMPACT);
+#ifdef DE4X5_VERBOSE
+	printk("%s: INFOLEAF_SIZE: %ld, COMPACT: %ld\n", dev->name, 
+	       INFOLEAF_SIZE, COMPACT);
+#endif
     }
     
     if (de4x5_debug & DEBUG_VERSION) {
@@ -1293,6 +1299,9 @@
 	    printk("%s: transmit busy, lost media or stale skb found:\n  STS:%08x\n  tbusy:%ld\n  IMR:%08x\n  OMR:%08x\n Stale skb: %s\n",dev->name, inl(DE4X5_STS), dev->tbusy, inl(DE4X5_IMR), inl(DE4X5_OMR), (lp->tx_skb[lp->tx_new] ? "YES" : "NO"));
 	}
     } else if (skb->len > 0) {
+	/* Update the byte counter */
+	lp->stats.tx_bytes += skb->len;
+
 	/* If we already have stuff queued locally, use that first */
 	if (lp->cache.skb && !dev->interrupt) {
 	    de4x5_put_cache(dev, skb);
@@ -1316,7 +1325,7 @@
 	}
 	if (skb) de4x5_putb_cache(dev, skb);
     }
-    
+
     lp->cache.lock = 0;
 
     return status;
@@ -1452,6 +1461,7 @@
 		    
 		/* Update stats */
 		lp->stats.rx_packets++;
+		lp->stats.rx_bytes += pkt_len;
 		de4x5_local_stats(dev, skb->data, pkt_len);
 	    }
 	    
@@ -2081,6 +2091,7 @@
     return;
 }
 
+#ifdef MODULE
 static struct device *
 unlink_modules(struct device *p)
 {
@@ -2103,6 +2114,7 @@
     
     return next;
 }
+#endif
 
 /*
 ** Auto configure the media here rather than setting the port at compile
@@ -4660,12 +4672,18 @@
     u_long iobase = dev->base_addr;
     int i, j, status = 0;
     s32 omr;
-    union {
-	u8  addr[(HASH_TABLE_LEN * ETH_ALEN)];
-	u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
-	u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
+    struct {
+	u8  *addr;
+	u16 *sval;
+	u32 *lval;
     } tmp;
-    
+
+    tmp.addr = tmp.sval = tmp.lval = kmalloc(HASH_TABLE_LEN * ETH_ALEN, GFP_KERNEL);
+    if (!tmp.addr){ 
+      printk("%s ioctl: memory squeeze.\n", dev->name);
+      return -ENOMEM;
+    }
+
     switch(ioc->cmd) {
       case DE4X5_GET_HWADDR:           /* Get the hardware address */
 	ioc->len = ETH_ALEN;
@@ -4916,7 +4934,9 @@
       default:
 	status = -EOPNOTSUPP;
     }
-    
+
+    kfree(tmp.addr);
+
     return status;
 }
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v2.1.30/linux/drivers/net/de600.c	Sun Feb  2 05:18:37 1997
+++ linux/drivers/net/de600.c	Mon Mar 31 12:52:30 1997
@@ -109,7 +109,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-unsigned int de600_debug = DE600_DEBUG;
+static unsigned int de600_debug = DE600_DEBUG;
 MODULE_PARM(de600_debug, "i");
 
 #ifdef FAKE_SMALL_MAX
@@ -401,17 +401,6 @@
 	int	len;
 	int	tickssofar;
 	byte	*buffer = skb->data;
-
-	/*
-	 * If some higher layer thinks we've missed a
-	 * tx-done interrupt we are passed NULL.
-	 * Caution: dev_tint() handles the cli()/sti() itself.
-	 */
-
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
 
 	if (free_tx_pages <= 0) {	/* Do timeouts, to avoid hangs. */
 		tickssofar = jiffies - dev->trans_start;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v2.1.30/linux/drivers/net/de620.c	Sun Feb  2 05:18:38 1997
+++ linux/drivers/net/de620.c	Mon Mar 31 12:52:30 1997
@@ -521,17 +521,6 @@
 	byte *buffer = skb->data;
 	byte using_txbuf;
 
-	/*
-	 * If some higher layer thinks we've missed a
-	 * tx-done interrupt we are passed NULL.
-	 * Caution: dev_tint() handles the cli()/sti() itself.
-	 */
-
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
 	dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/dummy.c linux/drivers/net/dummy.c
--- v2.1.30/linux/drivers/net/dummy.c	Sun Feb  2 05:18:39 1997
+++ linux/drivers/net/dummy.c	Mon Mar 31 12:52:30 1997
@@ -29,7 +29,6 @@
 */
 
 /* To have statistics (just packets sent) define this */
-#undef DUMMY_STATS
 
 #include <linux/module.h>
 
@@ -54,9 +53,7 @@
 #include <linux/skbuff.h>
 
 static int dummy_xmit(struct sk_buff *skb, struct device *dev);
-#ifdef DUMMY_STATS
 static struct net_device_stats *dummy_get_stats(struct device *dev);
-#endif
 
 static int dummy_open(struct device *dev)
 {
@@ -70,26 +67,25 @@
 	return 0;
 }
 
+/* fake multicast ability */
+static void set_multicast_list(struct device *dev)
+{
+}
 
 int dummy_init(struct device *dev)
 {
-/* I commented this out as bootup is noisy enough anyway and this driver
-   seems pretty reliable 8) 8) 8) */
-/*	printk ( KERN_INFO "Dummy net driver (94/05/27 v1.0)\n" ); */
-
 	/* Initialize the device structure. */
 	dev->hard_start_xmit	= dummy_xmit;
 
-#if DUMMY_STATS
 	dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
 	if (dev->priv == NULL)
 		return -ENOMEM;
 	memset(dev->priv, 0, sizeof(struct net_device_stats));
 	dev->get_stats		= dummy_get_stats;
-#endif
 
 	dev->open = dummy_open;
 	dev->stop = dummy_close;
+	dev->set_multicast_list = set_multicast_list;
 
 	/* Fill in the fields of the device structure with ethernet-generic values. */
 	ether_setup(dev);
@@ -99,29 +95,23 @@
 	return 0;
 }
 
-static int
-dummy_xmit(struct sk_buff *skb, struct device *dev)
+static int dummy_xmit(struct sk_buff *skb, struct device *dev)
 {
-#if DUMMY_STATS
 	struct net_device_stats *stats;
-#endif
 	dev_kfree_skb(skb, FREE_WRITE);
 
-#if DUMMY_STATS
 	stats = (struct net_device_stats *)dev->priv;
 	stats->tx_packets++;
-#endif
+	stats->tx_bytes+=skb->len;
 
 	return 0;
 }
 
-#if DUMMY_STATS
 static struct net_device_stats *dummy_get_stats(struct device *dev)
 {
 	struct net_device_stats *stats = (struct net_device_stats *) dev->priv;
 	return stats;
 }
-#endif
 
 #ifdef MODULE
 
@@ -131,8 +121,10 @@
 	return 0;
 }
 
+static char dummy_name[16];
+
 static struct device dev_dummy = {
-	"dummy0\0   ", 
+		dummy_name, 	/* Needs to be writeable */
 		0, 0, 0, 0,
 	 	0x0, 0,
 	 	0, 0, 0, NULL, dummy_probe };
@@ -140,16 +132,9 @@
 int init_module(void)
 {
 	/* Find a name for this unit */
-	int ct= 1;
-	
-	while(dev_get(dev_dummy.name)!=NULL && ct<100)
-	{
-		sprintf(dev_dummy.name,"dummy%d",ct);
-		ct++;
-	}
-	if(ct==100)
-		return -ENFILE;
-	
+	int err=dev_alloc_name(&dev_dummy,"dummy%d");
+	if(err)
+		return err;
 	if (register_netdev(&dev_dummy) != 0)
 		return -EIO;
 	return 0;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/eepro.c linux/drivers/net/eepro.c
--- v2.1.30/linux/drivers/net/eepro.c	Sun Feb  2 05:18:39 1997
+++ linux/drivers/net/eepro.c	Mon Mar 31 12:52:30 1997
@@ -712,14 +712,6 @@
 
 	}
 
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	/* Block a timer-based transmit from overlapping. */
 	if (set_bit(0, (void*)&dev->tbusy) != 0)
 		printk("%s: Transmitter access conflict.\n", dev->name);
diff -u --recursive --new-file v2.1.30/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.1.30/linux/drivers/net/eexpress.c	Sun Feb  2 05:18:39 1997
+++ linux/drivers/net/eexpress.c	Mon Mar 31 12:52:30 1997
@@ -467,25 +467,6 @@
 	if (dev->tbusy)
 		unstick_cu(dev);
 
-	if (buf==NULL)
-	{
-		/* Some higher layer thinks we might have missed a
-		 * tx-done interrupt.  Does this ever actually happen?
-		 */
-		unsigned short status = scb_status(dev);
-		unsigned short txstatus = eexp_hw_lasttxstat(dev);
-		if (SCB_CUdead(status))
-		{
-			printk(KERN_WARNING "%s: CU has died! status %04x %04x, attempting to restart...\n",
-				dev->name, status, txstatus);
-			lp->stats.tx_errors++;
-			eexp_hw_txrestart(dev);
-		}
-		dev_tint(dev);
-		outb(SIRQ_en|irqrmap[dev->irq],dev->base_addr+SET_IRQ);
-		return 0;
-	}
-
 	if (set_bit(0,(void *)&dev->tbusy))
 	{
 		lp->stats.tx_dropped++;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c
--- v2.1.30/linux/drivers/net/fmv18x.c	Sun Feb  2 05:18:40 1997
+++ linux/drivers/net/fmv18x.c	Mon Mar 31 12:52:30 1997
@@ -345,14 +345,6 @@
 		sti();
 	}
 
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	/* Block a timer-based transmit from overlapping.  This could better be
 	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 	if (set_bit(0, (void*)&dev->tbusy) != 0)
diff -u --recursive --new-file v2.1.30/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v2.1.30/linux/drivers/net/hp100.c	Sun Feb  2 05:18:40 1997
+++ linux/drivers/net/hp100.c	Mon Mar 31 10:26:12 1997
@@ -180,8 +180,8 @@
   { 0x01030103c, "HP J2585", 	   HP100_BUS_PCI },
 };
 
-int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
-int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
+static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
+static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
 
 /*
  *  prototypes
diff -u --recursive --new-file v2.1.30/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v2.1.30/linux/drivers/net/ibmtr.c	Fri Feb  7 05:54:54 1997
+++ linux/drivers/net/ibmtr.c	Mon Mar 31 12:52:30 1997
@@ -53,7 +53,9 @@
  *	  from being rudely overwritten before the transmit cycle is
  *	  complete. (August 15 1996)
  *	+ completed multiple adapter support. (November 20 1996)
- */
+ *	+ implemented csum_partial_copy in tr_rx and increased receive 
+ *        buffer size and count. Minor fixes. (March 15, 1997)
+*/
 
 #ifdef PCMCIA
 #define MODULE
@@ -79,13 +81,10 @@
 /* some 95 OS send many non UI frame; this allow removing the warning */
 #define TR_FILTERNONUI	1
 
-/* use memcpy to read/write frame data instead of for-loop */
-#define USE_MEMCPY 1
-
 /* version and credits */
 static char *version =
 "ibmtr.c: v1.3.57  8/ 7/94 Peter De Schrijver and Mark Swanson\n"
-"         v2.1.10 11/20/96 Paul Norton <pnorton@cts.com>\n";
+"         v2.1.29  3/15/97 Paul Norton <pnorton@cts.com>\n";
 
 static char pcchannelid[] = {
 	0x05, 0x00, 0x04, 0x09,
@@ -120,6 +119,7 @@
 #include <linux/netdevice.h>
 #include <linux/trdevice.h>
 #include <linux/stddef.h>
+#include <net/checksum.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -178,8 +178,6 @@
 void		ibmtr_readlog(struct device *dev);
 void		ibmtr_reset_timer(struct timer_list *tmr, struct device *dev);
 
-static struct timer_list tr_timer;
-
 static unsigned int ibmtr_portlist[] = {
 	0xa20, 0xa24, 0
 };
@@ -858,7 +856,7 @@
 							      open_ret_code);
 
 					      if (ti->open_status != FAILURE) {
-						      ibmtr_reset_timer(&tr_timer, dev);
+						      ibmtr_reset_timer(&(ti->tr_timer), dev);
 					      }
 
 				      }
@@ -872,7 +870,7 @@
 					if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
 						DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
 							(int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));
-						ibmtr_reset_timer(&tr_timer, dev);
+						ibmtr_reset_timer(&(ti->tr_timer), dev);
 					} else {
 						ti->exsap_station_id=
 							readw(ti->srb+offsetof(struct dlc_open_sap, station_id));
@@ -983,7 +981,7 @@
 
 						      DPRINTK("Signal loss/Lobe fault\n");
 						      DPRINTK("We try to reopen the adapter.\n");
-						      ibmtr_reset_timer(&tr_timer, dev);
+						      ibmtr_reset_timer(&(ti->tr_timer), dev);
 					      } else if (ring_status & (HARD_ERROR | XMIT_BEACON
 											| AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
 						      DPRINTK("New ring status: %02X\n", ring_status);
@@ -1297,27 +1295,16 @@
 
 	/* header length including rif is computed above, now move the data
 	   and set fields appropriately. */
-#if USE_MEMCPY
 	memcpy_toio(dhb, ti->current_skb->data, hdr_len);
-#else
-	for (i=0; i<hdr_len; i++)
-		writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
-#endif
 
 	writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
 	writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
 	       ti->asb + offsetof(struct asb_xmit_resp, frame_length));
 
 	/*  now copy the actual packet data next to hdr */
-#if USE_MEMCPY
 	memcpy_toio(dhb + hdr_len,
 		    ti->current_skb->data + sizeof(struct trh_hdr),
 		    ti->current_skb->len - sizeof(struct trh_hdr));
-#else
-	for (i=0; i<ti->current_skb->len-sizeof(struct trh_hdr); i++)
-		writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i),
-		       dhb+i);
-#endif
 
 	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 	dev->tbusy=0;
@@ -1329,20 +1316,20 @@
 
 static void tr_rx(struct device *dev)
 {
-	int i;
 	struct tok_info *ti=(struct tok_info *) dev->priv;
-	__u32 rbuffer;
+	__u32 rbuffer, rbufdata;
 	__u32 llc;
 	unsigned char *data;
-	unsigned int rbuffer_len, lan_hdr_len;
+	unsigned int rbuffer_len, lan_hdr_len, hdr_len;
 	unsigned int arb_frame_len;
 	struct sk_buff *skb;
 	unsigned int skb_size = 0;
 	int	is8022 = 0;
+	unsigned int chksum = 0;
 
 	rbuffer=(ti->sram
-		 +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))));
-
+		 +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))))+2;
+ 
 	if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
 		DPRINTK("ASB not free !!!\n");
 
@@ -1354,7 +1341,7 @@
 	       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
@@ -1367,128 +1354,123 @@
 		"ethertype: %04X\n",
 		(int)readb(llc + offsetof(struct trllc, dsap)),
 		(int)readb(llc + offsetof(struct trllc, ssap)),
+		(int)readb(llc + offsetof(struct trllc, llc)),
 		(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 (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 ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
-		    (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
-			is8022 = 1;
-		}
-
-#if TR_VERBOSE
-		if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
-		    (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
-
-			__u32 trhhdr;
-
-			trhhdr=(rbuffer+offsetof(struct rec_buf,data));
-
-			DPRINTK("Probably non-IP frame received.\n");
-			DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
-				"daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
-				(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
-
-		arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
-		skb_size = arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr);
-		if (is8022) {
-			skb_size += sizeof(struct trllc);
-		}
-
-		if (!(skb=dev_alloc_skb(skb_size))) {
-			DPRINTK("out of memory. frame dropped.\n");
-			ti->tr_stats.rx_dropped++;
-			writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
-			writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-			return;
-		}
-
-		skb_put(skb, skb_size);
-		skb->dev=dev;
-
-		data=skb->data;
-#if USE_MEMCPY
-		memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data), lan_hdr_len);
-#else
-		for (i=0; i<lan_hdr_len; i++)
-			data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
-#endif
-		if (lan_hdr_len<sizeof(struct trh_hdr))
-			memset(data+lan_hdr_len, 0, sizeof(struct trh_hdr)-lan_hdr_len);
+	}
 
-		data+=sizeof(struct trh_hdr);
-		rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))
-			-lan_hdr_len;
-		if (is8022) {
-			struct trllc	*local_llc = (struct trllc *)data;
-			memset(local_llc, 0, sizeof(*local_llc));
-			local_llc->ethertype = htons(ETH_P_TR_802_2);
-			data += sizeof(struct trllc);
-		}
+       	if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
+       	    (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
+       		is8022 = 1;
+       	}
 
 #if TR_VERBOSE
-		DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
-#endif
-#if USE_MEMCPY
-		memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len, rbuffer_len);
-#else
-		for (i=0; i<rbuffer_len; i++)
-			data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
-#endif
-		data+=rbuffer_len;
+       	if (is8022){
 
-		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;
+       		__u32 trhhdr;
 
-#if TR_VERBOSE
-			DPRINTK("buf_ptr: %d, data =%p\n",
-				ntohs((rbuffer + offsetof(struct rec_buf, buf_ptr))), data);
-#endif
-		}
+       		trhhdr=(rbuffer+offsetof(struct rec_buf,data));
 
-		writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
+       		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
+
+       	arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
+       	skb_size = arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr);
+       	if (is8022) {
+       		skb_size += sizeof(struct trllc);
+       	}
+
+       	if (!(skb=dev_alloc_skb(skb_size))) {
+       		DPRINTK("out of memory. frame dropped.\n");
+       		ti->tr_stats.rx_dropped++;
+       		writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+       		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+       		return;
+       	}
+
+       	skb_put(skb, skb_size);
+       	skb->dev=dev;
+
+       	data=skb->data;
+
+	/* Copy the 802.5 MAC header */
+	memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, 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(readw(rbuffer + offsetof(struct rec_buf, buf_len)))-lan_hdr_len;
+
+	if (is8022) {
+		/* create whitewashed LLC header in skb buffer (why not the real one?) */
+		struct trllc	*local_llc = (struct trllc *)data;
+		memset(local_llc, 0, sizeof(*local_llc));
+		local_llc->ethertype = htons(ETH_P_TR_802_2);
+		hdr_len = sizeof(struct trllc);
+	} else {
+                /* Copy the LLC header and the IPv4 header */
+		hdr_len = sizeof(struct trllc) + sizeof(struct iphdr);
+		memcpy_fromio(data, rbuffer+offsetof(struct rec_buf, data)+lan_hdr_len,hdr_len);
+        }
+	data        += hdr_len;
+       	lan_hdr_len += hdr_len;
+	rbuffer_len -= hdr_len;
+	rbufdata     = rbuffer + offsetof(struct rec_buf,data) + lan_hdr_len;
+
+	/* Copy the payload... */
+	for (;;) {
+		if (is8022)
+			memcpy_fromio(data, rbufdata, rbuffer_len);
+		else
+			chksum = csum_partial_copy(bus_to_virt(rbufdata), data, rbuffer_len, chksum);
+		rbuffer = ntohs(readw(rbuffer));
+		if (!rbuffer)
+			break;
+		data += rbuffer_len;
+		rbuffer += ti->sram;
+		rbuffer_len = ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+		rbufdata = rbuffer + offsetof(struct rec_buf, data);
+	}
 
-		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+       	writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
 
-		ti->tr_stats.rx_packets++;
+       	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 
-		skb->protocol=tr_type_trans(skb,dev);
-		netif_rx(skb);
+       	ti->tr_stats.rx_packets++;
 
+	skb->protocol  = tr_type_trans(skb,dev);
+	if (!is8022){
+		skb->csum      = chksum;
+		skb->ip_summed = 1;
 	}
+	netif_rx(skb);
+}
 
 static int tok_send_packet(struct sk_buff *skb, struct device *dev)
 {
diff -u --recursive --new-file v2.1.30/linux/drivers/net/ibmtr.h linux/drivers/net/ibmtr.h
--- v2.1.30/linux/drivers/net/ibmtr.h	Sat Dec 21 03:16:57 1996
+++ linux/drivers/net/ibmtr.h	Mon Mar 31 12:52:30 1997
@@ -200,11 +200,13 @@
 	unsigned short exsap_station_id;
 	unsigned short global_int_enable;
 	struct sk_buff *current_skb;
-	struct tr_statistics tr_stats;
+	struct net_device_stats tr_stats;
 	unsigned char auto_ringspeedsave;
 	open_state open_status;
 	unsigned char readlog_pending;
 	unsigned short adapter_int_enable; /* Adapter-specific int enable */
+        struct timer_list tr_timer;
+	__u32 func_addr;
 };
 
 /* token ring adapter commands */
@@ -213,7 +215,7 @@
 #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_SET_FUNC_ADDR   	0x07 /* struct srb_set_funct_addr */
 #define DIR_READ_LOG 		0x08 /* struct srb_read_log */
 #define DLC_OPEN_SAP 		0x15 /* struct dlc_open_sap */
 #define DLC_CLOSE_SAP       	0x16
@@ -225,8 +227,8 @@
 
 /* DIR_OPEN_ADAPTER options */
 #define OPEN_PASS_BCON_MAC 0x0100
-#define NUM_RCV_BUF 16
-#define RCV_BUF_LEN 136
+#define NUM_RCV_BUF 3
+#define RCV_BUF_LEN 1024
 #define DHB_LENGTH 2048
 #define NUM_DHB 2
 #define DLC_MAX_SAP 2
@@ -396,7 +398,7 @@
 };
 
 struct rec_buf {
-	unsigned char reserved1[2];
+  /*	unsigned char reserved1[2]; */
 	__u16 buf_ptr;
 	unsigned char reserved2;
 	__u16 buf_len;
@@ -424,5 +426,13 @@
 	unsigned char command;
 	unsigned char reserved1;
 	unsigned char ret_code;
+};
+
+struct srb_set_funct_addr {
+	unsigned char command;
+	unsigned char reserved1;
+	unsigned char ret_code;
+	unsigned char reserved2[3];
+	__u32 funct_address;
 };
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- v2.1.30/linux/drivers/net/loopback.c	Sun Feb  2 05:18:40 1997
+++ linux/drivers/net/loopback.c	Mon Mar 31 12:52:30 1997
@@ -93,7 +93,9 @@
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 #endif
 	netif_rx(skb);
-  
+
+	stats->rx_bytes+=skb->len;
+	stats->tx_bytes+=skb->len;
 	stats->rx_packets++;
 	stats->tx_packets++;
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c
--- v2.1.30/linux/drivers/net/ltpc.c	Thu Mar 27 14:40:04 1997
+++ linux/drivers/net/ltpc.c	Mon Mar 31 12:52:30 1997
@@ -690,7 +690,7 @@
 	int dnode, snode, llaptype, len; 
 	int sklen;
 	struct sk_buff *skb;
-	struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
+	struct net_device_stats *stats = (struct enet_statistics *)dev->priv;
 	struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf;
 
 	if (ltc->command != LT_RCVLAP) {
@@ -742,9 +742,11 @@
 
 	skb->h.raw = skb->data;
 
+	stats->rx_packets++;
+	stats->rx_bytes+=skb->len;
+
 	/* toss it onwards */
 	netif_rx(skb);
-	stats->rx_packets++;
 	return 0;
 }
 
@@ -939,16 +941,16 @@
 		printk("\n");
 	}
 
-	dev_kfree_skb(skb, FREE_WRITE);
-
 	stats->tx_packets++;
+	stats->tx_bytes+=skb->len;
 
+	dev_kfree_skb(skb, FREE_WRITE);
 	return 0;
 }
 
 static struct net_device_stats *ltpc_get_stats(struct device *dev)
 {
-	struct enet_statistics *stats = (struct enet_statistics*) dev->priv;
+	struct net_device_stats *stats = (struct net_device_stats *) dev->priv;
 	return stats;
 }
 
@@ -1211,8 +1213,11 @@
 }
 
 #ifdef MODULE
+
+static char dev_name[8];
+
 static struct device dev_ltpc = {
-	"ltalk0\0   ", 
+		dev_name, 
 		0, 0, 0, 0,
 	 	0x0, 0,
 	 	0, 0, 0, NULL, ltpc_probe };
@@ -1220,16 +1225,11 @@
 int init_module(void)
 {
 	/* Find a name for this unit */
-	int ct= 1;
-	
-	while(dev_get(dev_ltpc.name)!=NULL && ct<100)
-	{
-		sprintf(dev_ltpc.name,"ltpc%d",ct);
-		ct++;
-	}
-	if(ct==100)
-		return -ENFILE;
+	int err=dev_alloc_name(&dev_ltpc,"lt%d");
 	
+	if(err<0)
+		return err;
+
 	if (register_netdev(&dev_ltpc) != 0) {
 		if(debug&DEBUG_VERBOSE) printk("EIO from register_netdev\n");
 		return -EIO;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- v2.1.30/linux/drivers/net/pcnet32.c	Thu Mar 27 14:40:04 1997
+++ linux/drivers/net/pcnet32.c	Mon Mar 31 10:26:12 1997
@@ -37,9 +37,9 @@
 static unsigned int pcnet32_portlist[] = {0x300, 0x320, 0x340, 0x360, 0};
 
 #ifdef PCNET32_DEBUG
-int pcnet32_debug = PCNET32_DEBUG;
+static int pcnet32_debug = PCNET32_DEBUG;
 #else
-int pcnet32_debug = 1;
+static int pcnet32_debug = 1;
 #endif
 
 /*
diff -u --recursive --new-file v2.1.30/linux/drivers/net/pi2.c linux/drivers/net/pi2.c
--- v2.1.30/linux/drivers/net/pi2.c	Thu Mar 27 14:40:04 1997
+++ linux/drivers/net/pi2.c	Mon Mar 31 12:52:30 1997
@@ -1482,13 +1482,6 @@
 {
     struct pi_local *lp = (struct pi_local *) dev->priv;
 
-    /* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-    if (skb == NULL) {
-	dev_tint(dev);
-	return 0;
-    }
     hardware_send_packet(lp, skb);
     dev->trans_start = jiffies;
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v2.1.30/linux/drivers/net/plip.c	Sun Feb  2 05:18:41 1997
+++ linux/drivers/net/plip.c	Mon Mar 31 12:52:30 1997
@@ -885,14 +885,6 @@
 	if (dev->tbusy)
 		return 1;
 
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	if (set_bit(0, (void*)&dev->tbusy) != 0) {
 		printk("%s: Transmitter access conflict.\n", dev->name);
 		return 1;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/pt.c linux/drivers/net/pt.c
--- v2.1.30/linux/drivers/net/pt.c	Thu Mar 27 14:40:04 1997
+++ linux/drivers/net/pt.c	Mon Mar 31 12:52:31 1997
@@ -947,13 +947,6 @@
 #ifdef PT_DEBUG
 	printk(KERN_DEBUG "PT: pt_send_packet(): (%d)\n", lp->base & CHANA);
 #endif
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself.*/
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
 	hardware_send_packet(lp, skb);
 	dev->trans_start = jiffies;
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c
--- v2.1.30/linux/drivers/net/sdla_fr.c	Sun Feb  2 06:42:57 1997
+++ linux/drivers/net/sdla_fr.c	Mon Mar 31 12:52:31 1997
@@ -573,20 +573,6 @@
 	sdla_t* card = chan->card;
 	int retry = 0;
 
-	if (skb == NULL)
-	{
-		/* If we get here, some higher layer thinks we've missed an
-		 * tx-done interrupt.
-		 */
-#ifdef _DEBUG_
-		printk(KERN_INFO "%s: interface %s got kicked!\n",
-			card->devname, dev->name)
-		;
-#endif
-		dev_tint(dev);
-		return 0;
-	}
-
 	if (set_bit(0, (void*)&card->wandev.critical))
 	{
 #ifdef _DEBUG_
diff -u --recursive --new-file v2.1.30/linux/drivers/net/sdla_ppp.c linux/drivers/net/sdla_ppp.c
--- v2.1.30/linux/drivers/net/sdla_ppp.c	Sun Feb  2 06:43:08 1997
+++ linux/drivers/net/sdla_ppp.c	Mon Mar 31 12:52:31 1997
@@ -440,20 +440,6 @@
 	sdla_t* card = dev->priv;
 	int retry = 0;
 
-	if (skb == NULL)
-	{
-		/* If we get here, some higher layer thinks we've missed an
-		 * tx-done interrupt.
-		 */
-#ifdef _DEBUG_
-		printk(KERN_INFO "%s: interface %s got kicked!\n",
-			card->devname, dev->name)
-		;
-#endif
-		dev_tint(dev);
-		return 0;
-	}
-
 	if (set_bit(0, (void*)&card->wandev.critical))
 	{
 #ifdef _DEBUG_
diff -u --recursive --new-file v2.1.30/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c
--- v2.1.30/linux/drivers/net/sdla_x25.c	Sun Feb  2 06:43:19 1997
+++ linux/drivers/net/sdla_x25.c	Mon Mar 31 12:52:31 1997
@@ -589,20 +589,6 @@
 	sdla_t* card = chan->card;
 	int retry = 0, queued = 0;
 
-	if (skb == NULL)
-	{
-		/* If we get here, some higher layer thinks we've missed a
-		 * tx-done interrupt.
-		 */
-#ifdef _DEBUG_
-		printk(KERN_INFO "%s: interface %s got kicked!\n",
-			card->devname, dev->name)
-		;
-#endif
-		dev_tint(dev);
-		return 0;
-	}
-
 	if (set_bit(0, (void*)&card->wandev.critical))
 	{
 #ifdef _DEBUG_
diff -u --recursive --new-file v2.1.30/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- v2.1.30/linux/drivers/net/seeq8005.c	Fri Feb  7 05:54:54 1997
+++ linux/drivers/net/seeq8005.c	Mon Mar 31 12:52:31 1997
@@ -89,9 +89,9 @@
 
 /* Example routines you must write ;->. */
 #define tx_done(dev)	(inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
-extern void hardware_send_packet(struct device *dev, char *buf, int length);
+static void hardware_send_packet(struct device *dev, char *buf, int length);
 extern void seeq8005_init(struct device *dev, int startp);
-inline void wait_for_buffer(struct device *dev);
+static inline void wait_for_buffer(struct device *dev);
 
 
 /* Check for a network adaptor of this type, and return '0' iff one exists.
@@ -389,14 +389,6 @@
 		dev->trans_start = jiffies;
 	}
 
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	/* Block a timer-based transmit from overlapping.  This could better be
 	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 	if (set_bit(0, (void*)&dev->tbusy) != 0)
@@ -689,7 +681,7 @@
 }	
 
 
-void hardware_send_packet(struct device * dev, char *buf, int length)
+static void hardware_send_packet(struct device * dev, char *buf, int length)
 {
 	int ioaddr = dev->base_addr;
 	int status = inw(SEEQ_STATUS);
diff -u --recursive --new-file v2.1.30/linux/drivers/net/shaper.c linux/drivers/net/shaper.c
--- v2.1.30/linux/drivers/net/shaper.c	Sun Feb  2 05:18:41 1997
+++ linux/drivers/net/shaper.c	Mon Mar 31 12:52:31 1997
@@ -610,18 +610,11 @@
 
 int init_module(void)
 {
-	int i;
-	for(i=0;i<99;i++)
-	{
-		sprintf(devicename,"shaper%d",i);
-		if(dev_get(devicename)==NULL)
-			break;
-	}
-	if(i==100)
-		return -ENFILE;
-	
+	int err=dev_alloc_name(&dev_shape,"shaper%d");
+	if(err<0)
+		return err;
 	printk(SHAPER_BANNER);	
-	if (register_netdev(&dev_shape) != 0)
+	if (register_netdev(dev) != 0)
 		return -EIO;
 	printk("Traffic shaper initialised.\n");
 	return 0;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v2.1.30/linux/drivers/net/sk_g16.c	Thu Mar 27 14:40:04 1997
+++ linux/drivers/net/sk_g16.c	Mon Mar 31 12:52:31 1997
@@ -40,9 +40,6 @@
  *                 M. Hipp (mhipp@student.uni-tuebingen.de)
  *                 R. Bolz (Schneider & Koch, Germany)
  *
- * See README.sk_g16 for details about limitations and bugs for the
- * current version.
- *
  * To Do: 
  *        - Support of SK_G8 and other SK Network Cards.
  *        - Autoset memory mapped RAM. Check for free memory and then
@@ -322,20 +319,6 @@
 #define ETHERCARD_TOTAL_SIZE    SK_POS_SIZE
 
 /* 
- * Portreserve is there to mark the Card I/O Port region as used. 
- * Check_region is to check if the region at ioaddr with the size "size" 
- * is free or not.
- * Snarf_region allocates the I/O Port region.
- */
-
-#ifndef HAVE_PORTRESERVE
-
-#define check_region(ioaddr, size)              0
-#define request_region(ioaddr, size,name)       do ; while (0)
-
-#endif
-
-/* 
  * SK_DEBUG
  *
  * Here you can choose what level of debugging wanted.
@@ -1028,6 +1011,7 @@
 static int SK_lance_init(struct device *dev, unsigned short mode)
 {
     int i;
+    unsigned long flags;
     struct priv *p = (struct priv *) dev->priv; 
     struct tmd  *tmdp;
     struct rmd  *rmdp;
@@ -1046,10 +1030,10 @@
     {
 	tmdp = p->tmdhead + i; 
    
-	tmdp->u.buffer = (unsigned long) p->tmdbufs[i]; /* assign buffer */
+	writel((unsigned long) p->tmdbufs[i], tmdp->u.buffer); /* assign buffer */
 	
 	/* Mark TMD as start and end of packet */
-	tmdp->u.s.status = TX_STP | TX_ENP;
+	writeb(TX_STP | TX_ENP, tmdp->u.s.status);
     }
 
 
@@ -1062,42 +1046,43 @@
 	rmdp = p->rmdhead + i;
 
 	
-	rmdp->u.buffer = (unsigned long) p->rmdbufs[i]; /* assign buffer */
+	writel((unsigned long) p->rmdbufs[i], rmdp->u.buffer); /* assign buffer */
 	
 	/* 
          * LANCE must be owner at beginning so that he can fill in 
 	 * receiving packets, set status and release RMD 
 	 */
 
-	rmdp->u.s.status = RX_OWN;  
+	writeb(RX_OWN, rmdp->u.s.status);
 
-	rmdp->blen = -PKT_BUF_SZ;    /* Buffer Size in a two's complement */
+	writew(-PKT_BUF_SZ, rmdp->blen); /* Buffer Size (two's complement) */
 
-	rmdp->mlen = 0;              /* init message length */       
+	writeb(0, rmdp->mlen);           /* init message length */       
 	
     }
 
     /* Fill LANCE Initialize Block */
 
-    (p->ram)->ib.mode = mode;        /* Set operation mode */
+    writew(mode, (p->ram)->ib.mode); /* Set operation mode */
 
     for (i = 0; i < ETH_ALEN; i++)   /* Set physical address */
     {
-	(p->ram)->ib.paddr[i] = dev->dev_addr[i]; 
+	writeb(dev->dev_addr[i], (p->ram)->ib.paddr[i]); 
     }
 
     for (i = 0; i < 8; i++)          /* Set multicast, logical address */
     {
-	(p->ram)->ib.laddr[i] = 0;   /* We do not use logical addressing */
+	writeb(0, (p->ram)->ib.laddr[i]); /* We do not use logical addressing */
     } 
 
     /* Set ring descriptor pointers and set number of descriptors */
 
-    (p->ram)->ib.rdrp = (int)  p->rmdhead | RMDNUMMASK;
-    (p->ram)->ib.tdrp = (int)  p->tmdhead | TMDNUMMASK;
+    writel((int)p->rmdhead | RMDNUMMASK, (p->ram)->ib.rdrp);
+    writel((int)p->tmdhead | TMDNUMMASK, (p->ram)->ib.tdrp);
 
     /* Prepare LANCE Control and Status Registers */
 
+    save_flags(flags);
     cli();
 
     SK_write_reg(CSR3, CSR3_ACON);   /* Ale Control !!!THIS MUST BE SET!!!! */
@@ -1133,7 +1118,7 @@
 
     SK_write_reg(CSR0, CSR0_INIT); 
 
-    sti();
+    restore_flags(flags);
 
     /* Wait until LANCE finished initialization */
     
@@ -1216,22 +1201,6 @@
 
     }
 
-    /* 
-     * If some upper Layer thinks we missed a transmit done interrupt
-     * we are passed NULL.
-     * (dev_queue_xmit net/inet/dev.c 
-     */
-
-    if (skb == NULL)
-    {
-        /* 
-         * Dequeue packets from transmit queue and send them.
-         */
-	dev_tint(dev); 
-                    
-	return 0;
-    }
-    
     PRINTK2(("## %s: SK_send_packet() called, CSR0 %#04x.\n", 
 	    SK_NAME, SK_read_reg(CSR0)));
 
@@ -1258,7 +1227,7 @@
 
 	memcpy_toio((tmdp->u.buffer & 0x00ffffff), skb->data, skb->len);
 
-	tmdp->blen = -len;            /* set length to transmit */
+	writew(-len, tmdp->blen);            /* set length to transmit */
 
 	/* 
 	 * Packet start and end is always set because we use the maximum
@@ -1266,7 +1235,7 @@
 	 * Relinquish ownership to LANCE
 	 */
 
-	tmdp->u.s.status = TX_OWN | TX_STP | TX_ENP;
+	writeb(TX_OWN | TX_STP | TX_ENP, tmdp->u.s.status);
 	
 	/* Start Demand Transmission */
 	SK_write_reg(CSR0, CSR0_TDMD | CSR0_INEA);
@@ -1278,7 +1247,7 @@
 	p->tmdnum &= TMDNUM-1; 
 
 	/* Do we own the next transmit buffer ? */
-	if (! ((p->tmdhead + p->tmdnum)->u.s.status & TX_OWN) )
+	if (! (readb((p->tmdhead + p->tmdnum)->u.s.status) & TX_OWN) )
 	{
 	   /* 
 	    * We own next buffer and are ready to transmit, so
@@ -1400,7 +1369,7 @@
     p->tmdlast++;
     p->tmdlast &= TMDNUM-1;
 
-    tmdstat = tmdp->u.s.status & 0xff00; /* filter out status bits 15:08 */
+    tmdstat = readb(tmdp->u.s.status);
 
     /* 
      * We check status of transmitted packet.
@@ -1408,21 +1377,22 @@
      */
     if (tmdstat & TX_ERR) /* Error occurred */
     {
-	printk("%s: TX error: %04x %04x\n", dev->name, (int) tmdstat,
-		(int) tmdp->status2);
+	int stat2 = readw(tmdp->status2);
+
+	printk("%s: TX error: %04x %04x\n", dev->name, tmdstat, stat2);
 
-	if (tmdp->status2 & TX_TDR)    /* TDR problems? */
+	if (stat2 & TX_TDR)    /* TDR problems? */
 	{
 	    printk("%s: tdr-problems \n", dev->name);
 	}
 
-	if (tmdp->status2 & TX_RTRY)   /* Failed in 16 attempts to transmit ? */
+	if (stat2 & TX_RTRY)   /* Failed in 16 attempts to transmit ? */
             p->stats.tx_aborted_errors++;   
-        if (tmdp->status2 & TX_LCOL)   /* Late collision ? */
+        if (stat2 & TX_LCOL)   /* Late collision ? */
             p->stats.tx_window_errors++; 
-	if (tmdp->status2 & TX_LCAR)   /* Loss of Carrier ? */  
+	if (stat2 & TX_LCAR)   /* Loss of Carrier ? */  
             p->stats.tx_carrier_errors++;
-        if (tmdp->status2 & TX_UFLO)   /* Underflow error ? */
+        if (stat2 & TX_UFLO)   /* Underflow error ? */
         {
             p->stats.tx_fifo_errors++;
 
@@ -1436,7 +1406,7 @@
 	
 	p->stats.tx_errors++;
 
-	tmdp->status2 = 0;             /* Clear error flags */
+	writew(0, tmdp->status2);             /* Clear error flags */
     }
     else if (tmdstat & TX_MORE)        /* Collisions occurred ? */
     {
@@ -1449,7 +1419,7 @@
          * First I did not have this in but then I thought at minimum
          * we see that something was not ok.
          * If anyone knows something better than this to handle this
-         * please report it. (see Email addresses in the README file)
+         * please report it.
          */ 
 
         p->stats.collisions++; 
@@ -1519,7 +1489,7 @@
      * it up to higher layer 
      */
 
-    while (!( (rmdstat = rmdp->u.s.status) & RX_OWN))
+    while (!( (rmdstat = readb(rmdp->u.s.status)) & RX_OWN))
     {
 	/* 
          * Start and end of packet must be set, because we use 
@@ -1549,7 +1519,7 @@
 	     * packets. 
 	     */
 
-	    rmdp->u.s.status = RX_OWN;      /* Relinquish ownership to LANCE */ 
+	    writeb(RX_OWN, rmdp->u.s.status); /* Relinquish ownership to LANCE */ 
 
 	}
 	else if (rmdstat & RX_ERR)          /* Receive Error ? */
@@ -1561,13 +1531,13 @@
 	    if (rmdstat & RX_FRAM) p->stats.rx_frame_errors++;
 	    if (rmdstat & RX_CRC)  p->stats.rx_crc_errors++;
 
-	    rmdp->u.s.status = RX_OWN;      /* Relinquish ownership to LANCE */
+	    writeb(RX_OWN, rmdp->u.s.status); /* Relinquish ownership to LANCE */
 
 	}
 	else /* We have a packet which can be queued for the upper layers */
 	{
 
-	    int len = (rmdp->mlen & 0x0fff);  /* extract message length from receive buffer */
+	    int len = readw(rmdp->mlen) & 0x0fff;  /* extract message length from receive buffer */
 	    struct sk_buff *skb;
 
 	    skb = dev_alloc_skb(len+2); /* allocate socket buffer */ 
@@ -1580,7 +1550,7 @@
 		 * to Lance, update statistics and go ahead.
 		 */
 
-		rmdp->u.s.status = RX_OWN;  /* Relinquish ownership to LANCE */
+		writeb(RX_OWN, rmdp->u.s.status); /* Relinquish ownership to LANCE */
 		printk("%s: Couldn't allocate sk_buff, deferring packet.\n",
 		       dev->name);
 		p->stats.rx_dropped++;
@@ -1618,7 +1588,7 @@
 	     * free our descriptor and update statistics 
 	     */
 
-	    rmdp->u.s.status = RX_OWN;
+	    writeb(RX_OWN, rmdp->u.s.status);
 	    p->stats.rx_packets++;
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v2.1.30/linux/drivers/net/slip.c	Tue Mar  4 10:25:23 1997
+++ linux/drivers/net/slip.c	Mon Mar 31 12:52:31 1997
@@ -312,7 +312,7 @@
 }
 
 
-/* Set the "sending" flag.  This must be atomic, hence the ASM. */
+/* Set the "sending" flag.  This must be atomic hence the set_bit. */
 static inline void
 sl_lock(struct slip *sl)
 {
diff -u --recursive --new-file v2.1.30/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- v2.1.30/linux/drivers/net/smc9194.c	Fri Feb  7 05:54:54 1997
+++ linux/drivers/net/smc9194.c	Mon Mar 31 12:52:31 1997
@@ -1242,14 +1242,6 @@
 		((struct smc_local *)dev->priv)->saved_skb = NULL;
 	}
 
-	/* If some higher layer thinks we've missed an tx-done interrupt
-	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-	   itself. */
-	if (skb == NULL) {
-		dev_tint(dev);
-		return 0;
-	}
-
 	/* Block a timer-based transmit from overlapping.  This could better be
 	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 	if (set_bit(0, (void*)&dev->tbusy) != 0) {
diff -u --recursive --new-file v2.1.30/linux/drivers/net/soundmodem/sm.c linux/drivers/net/soundmodem/sm.c
--- v2.1.30/linux/drivers/net/soundmodem/sm.c	Thu Mar 27 14:40:04 1997
+++ linux/drivers/net/soundmodem/sm.c	Mon Mar 31 12:52:31 1997
@@ -235,6 +235,11 @@
  * the same behaviour as par96_check_lpt in baycom.c
  */
 
+/*
+ * returns 0 if ok and != 0 on error;
+ * the same behaviour as par96_check_lpt in baycom.c
+ */
+
 static int check_lpt(unsigned int iobase)
 {
 	unsigned char b1,b2;
diff -u --recursive --new-file v2.1.30/linux/drivers/net/tunnel.c linux/drivers/net/tunnel.c
--- v2.1.30/linux/drivers/net/tunnel.c	Sun Feb  2 05:18:42 1997
+++ linux/drivers/net/tunnel.c	Mon Mar 31 12:52:31 1997
@@ -268,30 +268,23 @@
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 #ifdef MODULE
 
-static int tunnel_probe(struct device *dev)
-{
-	tunnel_init(dev);
-	return 0;
-}
+
+static char tunnel_name[16];
 
 static struct device dev_tunnel = 
 {
-	"tunl0\0   ", 
+	tunnel_name, 
 	0, 0, 0, 0,
  	0x0, 0,
- 	0, 0, 0, NULL, tunnel_probe 
+ 	0, 0, 0, NULL, tunnel_init
  };
 
 int init_module(void)
 {
 	/* Find a name for this unit */
-	int ct= 1;
-	
-	while(dev_get(dev_tunnel.name)!=NULL && ct<100)
-	{
-		sprintf(dev_tunnel.name,"tunl%d",ct);
-		ct++;
-	}
+	int err=dev_alloc_name(&dev_tunnel, "tunl%d");
+	if(err<0)
+		return err;
 	
 #ifdef TUNNEL_DEBUG
 	printk("tunnel: registering device %s\n", dev_tunnel.name);
diff -u --recursive --new-file v2.1.30/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v2.1.30/linux/drivers/net/wavelan.c	Mon Mar 17 14:54:26 1997
+++ linux/drivers/net/wavelan.c	Mon Mar 31 12:52:31 1997
@@ -2354,6 +2354,7 @@
   netif_rx(skb);
 
   lp->stats.rx_packets++;
+  lp->stats.rx_bytes+=sksize;
 
 #ifdef DEBUG_RX_TRACE
   printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
diff -u --recursive --new-file v2.1.30/linux/drivers/net/x25_asy.c linux/drivers/net/x25_asy.c
--- v2.1.30/linux/drivers/net/x25_asy.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/x25_asy.c	Mon Mar 31 12:52:31 1997
@@ -0,0 +1,940 @@
+/*
+ *	Things to sort out:
+ *
+ *	o	tbusy handling
+ *	o	allow users to set the parameters
+ *	o	sync/async switching ?
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/x25.h>
+#include <linux/lapb.h>
+#include "x25_asy.h"
+
+typedef struct x25_ctrl {
+	char		if_name[8];	/* "xasy0\0" .. "xasy99999\0"	*/
+	struct x25_asy	ctrl;		/* X.25 things			*/
+	struct device	dev;		/* the device			*/
+} x25_asy_ctrl_t;
+
+static x25_asy_ctrl_t	**x25_asy_ctrls = NULL;
+
+int x25_asy_maxdev = SL_NRUNIT;		/* Can be overridden with insmod! */
+MODULE_PARM(x25_asy_maxdev, "i");
+
+static struct tty_ldisc	x25_ldisc;
+
+static int x25_asy_esc(unsigned char *p, unsigned char *d, int len);
+static void x25_asy_unesc(struct x25_asy *sl, unsigned char c);
+
+/* Find a free X.25 channel, and link in this `tty' line. */
+static inline struct x25_asy *x25_asy_alloc(void)
+{
+	x25_asy_ctrl_t *slp = NULL;
+	int i;
+
+	if (x25_asy_ctrls == NULL)
+		return NULL;	/* Master array missing ! */
+
+	for (i = 0; i < x25_asy_maxdev; i++) 
+	{
+		slp = x25_asy_ctrls[i];
+		/* Not allocated ? */
+		if (slp == NULL)
+			break;
+		/* Not in use ? */
+		if (!set_bit(SLF_INUSE, &slp->ctrl.flags))
+			break;
+	}
+	/* SLP is set.. */
+
+	/* Sorry, too many, all slots in use */
+	if (i >= x25_asy_maxdev)
+		return NULL;
+
+	/* If no channels are available, allocate one */
+	if (!slp &&
+	    (x25_asy_ctrls[i] = (x25_asy_ctrl_t *)kmalloc(sizeof(x25_asy_ctrl_t),
+						    GFP_KERNEL)) != NULL) {
+		slp = x25_asy_ctrls[i];
+		memset(slp, 0, sizeof(x25_asy_ctrl_t));
+
+		/* Initialize channel control data */
+		set_bit(SLF_INUSE, &slp->ctrl.flags);
+		slp->ctrl.tty         = NULL;
+		sprintf(slp->if_name, "x25asy%d", i);
+		slp->dev.name         = slp->if_name;
+		slp->dev.base_addr    = i;
+		slp->dev.priv         = (void*)&(slp->ctrl);
+		slp->dev.next         = NULL;
+		slp->dev.init         = x25_asy_init;
+	}
+	if (slp != NULL) 
+	{
+
+		/* register device so that it can be ifconfig'ed       */
+		/* x25_asy_init() will be called as a side-effect      */
+		/* SIDE-EFFECT WARNING: x25_asy_init() CLEARS slp->ctrl ! */
+
+		if (register_netdev(&(slp->dev)) == 0) 
+		{
+			/* (Re-)Set the INUSE bit.   Very Important! */
+			set_bit(SLF_INUSE, &slp->ctrl.flags);
+			slp->ctrl.dev = &(slp->dev);
+			slp->dev.priv = (void*)&(slp->ctrl);
+			return (&(slp->ctrl));
+		}
+		else
+		{
+			clear_bit(SLF_INUSE,&(slp->ctrl.flags));
+			printk("x25_asy_alloc() - register_netdev() failure.\n");
+		}
+	}
+	return NULL;
+}
+
+
+/* Free an X.25 channel. */
+
+static inline void x25_asy_free(struct x25_asy *sl)
+{
+	/* Free all X.25 frame buffers. */
+	if (sl->rbuff)  {
+		kfree(sl->rbuff);
+	}
+	sl->rbuff = NULL;
+	if (sl->xbuff)  {
+		kfree(sl->xbuff);
+	}
+	sl->xbuff = NULL;
+
+	if (!clear_bit(SLF_INUSE, &sl->flags)) {
+		printk("%s: x25_asy_free for already free unit.\n", sl->dev->name);
+	}
+}
+
+/* MTU has been changed by the IP layer. Unfortunately we are not told
+   about this, but we spot it ourselves and fix things up. We could be
+   in an upcall from the tty driver, or in an ip packet queue. */
+
+static void x25_asy_changed_mtu(struct x25_asy *sl)
+{
+	struct device *dev = sl->dev;
+	unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
+	int len;
+	unsigned long flags;
+
+	len = dev->mtu * 2;
+
+	xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+	rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+
+	if (xbuff == NULL || rbuff == NULL)  
+	{
+		printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n",
+		       sl->dev->name);
+		dev->mtu = sl->mtu;
+		if (xbuff != NULL)  
+			kfree(xbuff);
+		if (rbuff != NULL)  
+			kfree(rbuff);
+		return;
+	}
+
+	save_flags(flags); 
+	cli();
+
+	oxbuff    = sl->xbuff;
+	sl->xbuff = xbuff;
+	orbuff    = sl->rbuff;
+	sl->rbuff = rbuff;
+
+	if (sl->xleft)  {
+		if (sl->xleft <= len)  {
+			memcpy(sl->xbuff, sl->xhead, sl->xleft);
+		} else  {
+			sl->xleft = 0;
+			sl->tx_dropped++;
+		}
+	}
+	sl->xhead = sl->xbuff;
+
+	if (sl->rcount)  {
+		if (sl->rcount <= len) {
+			memcpy(sl->rbuff, orbuff, sl->rcount);
+		} else  {
+			sl->rcount = 0;
+			sl->rx_over_errors++;
+			set_bit(SLF_ERROR, &sl->flags);
+		}
+	}
+	sl->mtu      = dev->mtu;
+
+	sl->buffsize = len;
+
+	restore_flags(flags);
+
+	if (oxbuff != NULL) 
+		kfree(oxbuff);
+	if (orbuff != NULL)
+		kfree(orbuff);
+}
+
+
+/* Set the "sending" flag.  This must be atomic, hence the ASM. */
+
+static inline void x25_asy_lock(struct x25_asy *sl)
+{
+	if (set_bit(0, (void *) &sl->dev->tbusy))
+		printk("%s: trying to lock already locked device!\n", sl->dev->name);
+}
+
+
+/* Clear the "sending" flag.  This must be atomic, hence the ASM. */
+
+static inline void x25_asy_unlock(struct x25_asy *sl)
+{
+	if (!clear_bit(0, (void *)&sl->dev->tbusy))
+		printk("%s: trying to unlock already unlocked device!\n", sl->dev->name);
+}
+
+/* Send one completely decapsulated IP datagram to the IP layer. */
+
+static void x25_asy_bump(struct x25_asy *sl)
+{
+	struct sk_buff *skb;
+	int count;
+	int err;
+
+	count = sl->rcount;
+	sl->rx_bytes+=count;
+	
+	skb = dev_alloc_skb(count+1);
+	if (skb == NULL)  
+	{
+		printk("%s: memory squeeze, dropping packet.\n", sl->dev->name);
+		sl->rx_dropped++;
+		return;
+	}
+	skb_push(skb,1);	/* LAPB internal control */
+	skb->dev = sl->dev;
+	memcpy(skb_put(skb,count), sl->rbuff, count);
+	skb->mac.raw=skb->data;
+	skb->protocol=htons(ETH_P_X25);
+	if((err=lapb_data_received(sl,skb))!=LAPB_OK)
+	{
+		kfree_skb(skb, FREE_READ);
+		printk(KERN_DEBUG "x25_asy: data received err - %d\n",err);
+	}
+	else
+	{
+		netif_rx(skb);
+		sl->rx_packets++;
+	}
+}
+
+/* Encapsulate one IP datagram and stuff into a TTY queue. */
+static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
+{
+	unsigned char *p;
+	int actual, count;
+
+
+	if (sl->mtu != sl->dev->mtu) {	/* Someone has been ifconfigging */
+
+		x25_asy_changed_mtu(sl);
+	}
+
+	if (len > sl->mtu) 
+	{		/* Sigh, shouldn't occur BUT ... */
+		len = sl->mtu;
+		printk ("%s: truncating oversized transmit packet!\n", sl->dev->name);
+		sl->tx_dropped++;
+		x25_asy_unlock(sl);
+		return;
+	}
+
+	p = icp;
+	count = x25_asy_esc(p, (unsigned char *) sl->xbuff, len);
+
+	/* Order of next two lines is *very* important.
+	 * When we are sending a little amount of data,
+	 * the transfer may be completed inside driver.write()
+	 * routine, because it's running with interrupts enabled.
+	 * In this case we *never* got WRITE_WAKEUP event,
+	 * if we did not request it before write operation.
+	 *       14 Oct 1994  Dmitry Gorodchanin.
+	 */
+	sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+	actual = sl->tty->driver.write(sl->tty, 0, sl->xbuff, count);
+	sl->xleft = count - actual;
+	sl->xhead = sl->xbuff + actual;
+	/* VSV */
+	clear_bit(SLF_OUTWAIT, &sl->flags);	/* reset outfill flag */
+}
+
+/*
+ * Called by the driver when there's room for more data.  If we have
+ * more packets to send, we send them here.
+ */
+static void x25_asy_write_wakeup(struct tty_struct *tty)
+{
+	int actual;
+	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
+
+	/* First make sure we're connected. */
+	if (!sl || sl->magic != X25_ASY_MAGIC || !sl->dev->start)
+		return;
+
+	if (sl->xleft <= 0)  
+	{
+		/* Now serial buffer is almost free & we can start
+		 * transmission of another packet */
+		sl->tx_packets++;
+		tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+		x25_asy_unlock(sl);
+		mark_bh(NET_BH);
+		return;
+	}
+
+	actual = tty->driver.write(tty, 0, sl->xhead, sl->xleft);
+	sl->xleft -= actual;
+	sl->xhead += actual;
+}
+
+/* Encapsulate an IP datagram and kick it into a TTY queue. */
+
+static int x25_asy_xmit(struct sk_buff *skb, struct device *dev)
+{
+	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+	int err;
+
+	if (!dev->start)  
+	{
+		printk("%s: xmit call when iface is down\n", dev->name);
+		return 1;
+	}
+	
+	switch(skb->data[0])
+	{
+		case 0x00:break;
+		case 0x01: /* Connection request .. do nothing */
+			if((err=lapb_connect_request(sl))!=LAPB_OK)
+				printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err);
+			kfree_skb(skb, FREE_WRITE);
+			return 0;
+		case 0x02: /* Disconnect request .. do nothing - hang up ?? */
+			if((err=lapb_disconnect_request(sl))!=LAPB_OK)
+				printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err);
+		default:
+			kfree_skb(skb, FREE_WRITE);
+			return  0;
+	}
+	skb_pull(skb,1);	/* Remove control byte */
+	/*
+	 * If we are busy already- too bad.  We ought to be able
+	 * to queue things at this point, to allow for a little
+	 * frame buffer.  Oh well...
+	 * -----------------------------------------------------
+	 * I hate queues in X.25 driver. May be it's efficient,
+	 * but for me latency is more important. ;)
+	 * So, no queues !
+	 *        14 Oct 1994  Dmitry Gorodchanin.
+	 */
+	if (dev->tbusy) {
+		/* May be we must check transmitter timeout here ?
+		 *      14 Oct 1994 Dmitry Gorodchanin.
+		 */
+#ifdef SL_CHECK_TRANSMIT
+		if (jiffies - dev->trans_start  < 20 * HZ)  {
+			/* 20 sec timeout not reached */
+			return 1;
+		}
+		printk("%s: transmit timed out, %s?\n", dev->name,
+		       (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ?
+		       "bad line quality" : "driver error");
+		sl->xleft = 0;
+		sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+		x25_asy_unlock(sl);
+#else
+		return 1;
+#endif
+	}
+	
+	if((err=lapb_data_request(sl,skb))!=LAPB_OK)
+	{
+		printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err);
+		kfree_skb(skb, FREE_WRITE);
+		return 0;
+	}
+	return 0;
+}
+
+
+/*
+ *	LAPB interface boilerplate
+ */
+
+/*
+ *	Called when I frame data arrives. We did the work above - throw it
+ *	at the net layer.
+ */
+  
+static void x25_asy_data_indication(void *token, struct sk_buff *skb)
+{
+	netif_rx(skb);
+}
+
+/*
+ *	Data has emerged from the LAPB protocol machine. We don't handle
+ *	busy cases too well. Its tricky to see how to do this nicely -
+ *	perhaps lapb should allow us to bounce this ?
+ */
+ 
+static void x25_asy_data_transmit(void *token, struct sk_buff *skb)
+{
+	struct x25_asy *sl=token;
+	if(sl->dev->tbusy)
+	{
+		printk(KERN_ERR "x25_asy: tbusy drop\n");
+		kfree_skb(skb, FREE_WRITE);
+		return;
+	}
+	/* We were not busy, so we are now... :-) */
+	if (skb != NULL) 
+	{
+		x25_asy_lock(sl);
+		sl->tx_bytes+=skb->len;
+		x25_asy_encaps(sl, skb->data, skb->len);
+		dev_kfree_skb(skb, FREE_WRITE);
+	}
+}
+
+/*
+ *	LAPB connection establish/down information.
+ */
+ 
+static void x25_asy_connected(void *token, int reason)
+{
+	struct x25_asy *sl = token;
+	struct sk_buff *skb;
+	unsigned char *ptr;
+
+	if ((skb = dev_alloc_skb(1)) == NULL) {
+		printk(KERN_ERR "lapbeth: out of memory\n");
+		return;
+	}
+
+	ptr  = skb_put(skb, 1);
+	*ptr = 0x01;
+
+	skb->dev      = sl->dev;
+	skb->protocol = htons(ETH_P_X25);
+	skb->mac.raw  = skb->data;
+	skb->pkt_type = PACKET_HOST;
+
+	netif_rx(skb);
+}
+
+static void x25_asy_disconnected(void *token, int reason)
+{
+	struct x25_asy *sl = token;
+	struct sk_buff *skb;
+	unsigned char *ptr;
+
+	if ((skb = dev_alloc_skb(1)) == NULL) {
+		printk(KERN_ERR "x25_asy: out of memory\n");
+		return;
+	}
+
+	ptr  = skb_put(skb, 1);
+	*ptr = 0x02;
+
+	skb->dev      = sl->dev;
+	skb->protocol = htons(ETH_P_X25);
+	skb->mac.raw  = skb->data;
+	skb->pkt_type = PACKET_HOST;
+
+	netif_rx(skb);
+}
+
+
+/* Open the low-level part of the X.25 channel. Easy! */
+
+static int x25_asy_open(struct device *dev)
+{
+	struct lapb_register_struct x25_asy_callbacks;
+	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+	unsigned long len;
+	int err;
+
+	if (sl->tty == NULL)
+		return -ENODEV;
+
+	/*
+	 * Allocate the X.25 frame buffers:
+	 *
+	 * rbuff	Receive buffer.
+	 * xbuff	Transmit buffer.
+	 */
+
+	len = dev->mtu * 2;
+
+	sl->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
+	if (sl->rbuff == NULL)   {
+		goto norbuff;
+	}
+	sl->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
+	if (sl->xbuff == NULL)   {
+		goto noxbuff;
+	}
+	sl->mtu	     = dev->mtu;
+	sl->buffsize = len;
+	sl->rcount   = 0;
+	sl->xleft    = 0;
+	sl->flags   &= (1 << SLF_INUSE);      /* Clear ESCAPE & ERROR flags */
+
+	dev->tbusy  = 0;
+/*	dev->flags |= IFF_UP; */
+	dev->start  = 1;
+	
+	/*
+	 *	Now attach LAPB
+	 */
+	 
+	x25_asy_callbacks.connect_confirmation=x25_asy_connected;
+	x25_asy_callbacks.connect_indication=x25_asy_connected;
+	x25_asy_callbacks.disconnect_confirmation=x25_asy_disconnected;
+	x25_asy_callbacks.disconnect_indication=x25_asy_disconnected;
+	x25_asy_callbacks.data_indication=x25_asy_data_indication;
+	x25_asy_callbacks.data_transmit=x25_asy_data_transmit;
+
+	if((err=lapb_register(sl, &x25_asy_callbacks))==LAPB_OK)
+		return 0;
+
+	/* Cleanup */
+	kfree(sl->xbuff);
+noxbuff:
+	kfree(sl->rbuff);
+norbuff:
+	return -ENOMEM;
+}
+
+
+/* Close the low-level part of the X.25 channel. Easy! */
+static int x25_asy_close(struct device *dev)
+{
+	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+	int err;
+
+	if (sl->tty == NULL)
+		return -EBUSY;
+
+	sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+	dev->tbusy = 1;
+	dev->start = 0;
+	if((err=lapb_unregister(sl))!=LAPB_OK)
+		printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err);
+
+/*	dev->flags &= ~IFF_UP; */
+	return 0;
+}
+
+static int x25_asy_receive_room(struct tty_struct *tty)
+{
+	return 65536;  /* We can handle an infinite amount of data. :-) */
+}
+
+/*
+ * Handle the 'receiver data ready' interrupt.
+ * This function is called by the 'tty_io' module in the kernel when
+ * a block of X.25 data has been received, which can now be decapsulated
+ * and sent on to some IP layer for further processing.
+ */
+ 
+static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
+{
+	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
+
+	if (!sl || sl->magic != X25_ASY_MAGIC || !sl->dev->start)
+		return;
+
+	/*
+	 * Argh! mtu change time! - costs us the packet part received
+	 * at the change
+	 */
+	if (sl->mtu != sl->dev->mtu)  {
+
+		x25_asy_changed_mtu(sl);
+	}
+
+	/* Read the characters out of the buffer */
+	while (count--) {
+		if (fp && *fp++) {
+			if (!set_bit(SLF_ERROR, &sl->flags))  {
+				sl->rx_errors++;
+			}
+			cp++;
+			continue;
+		}
+		x25_asy_unesc(sl, *cp++);
+	}
+}
+
+/*
+ * Open the high-level part of the X.25 channel.
+ * This function is called by the TTY module when the
+ * X.25 line discipline is called for.  Because we are
+ * sure the tty line exists, we only have to link it to
+ * a free X.25 channel...
+ */
+
+static int x25_asy_open_tty(struct tty_struct *tty)
+{
+	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
+	int err;
+
+	/* First make sure we're not already connected. */
+	if (sl && sl->magic == X25_ASY_MAGIC) {
+		return -EEXIST;
+	}
+
+	/* OK.  Find a free X.25 channel to use. */
+	if ((sl = x25_asy_alloc()) == NULL) {
+		return -ENFILE;
+	}
+
+	sl->tty = tty;
+	tty->disc_data = sl;
+	if (tty->driver.flush_buffer)  {
+		tty->driver.flush_buffer(tty);
+	}
+	if (tty->ldisc.flush_buffer)  {
+		tty->ldisc.flush_buffer(tty);
+	}
+
+	/* Restore default settings */
+	sl->dev->type = ARPHRD_X25;
+	
+	/* Perform the low-level X.25 async init */
+	if ((err = x25_asy_open(sl->dev)))
+		return err;
+
+	MOD_INC_USE_COUNT;
+
+	/* Done.  We have linked the TTY line to a channel. */
+	return sl->dev->base_addr;
+}
+
+
+/*
+ * Close down an X.25 channel.
+ * This means flushing out any pending queues, and then restoring the
+ * TTY line discipline to what it was before it got hooked to X.25
+ * (which usually is TTY again).
+ */
+static void x25_asy_close_tty(struct tty_struct *tty)
+{
+	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
+
+	/* First make sure we're connected. */
+	if (!sl || sl->magic != X25_ASY_MAGIC)
+		return;
+
+	(void) dev_close(sl->dev);
+
+	tty->disc_data = 0;
+	sl->tty = NULL;
+	x25_asy_free(sl);
+	unregister_netdev(sl->dev);
+	MOD_DEC_USE_COUNT;
+}
+
+
+static struct net_device_stats *x25_asy_get_stats(struct device *dev)
+{
+	static struct net_device_stats stats;
+	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+
+	memset(&stats, 0, sizeof(struct net_device_stats));
+
+	stats.rx_packets     = sl->rx_packets;
+	stats.tx_packets     = sl->tx_packets;
+	stats.rx_bytes	     = sl->rx_bytes;
+	stats.tx_bytes	     = sl->tx_bytes;
+	stats.rx_dropped     = sl->rx_dropped;
+	stats.tx_dropped     = sl->tx_dropped;
+	stats.tx_errors      = sl->tx_errors;
+	stats.rx_errors      = sl->rx_errors;
+	stats.rx_over_errors = sl->rx_over_errors;
+	return (&stats);
+}
+
+
+ /************************************************************************
+  *			STANDARD X.25 ENCAPSULATION		  	 *
+  ************************************************************************/
+
+int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
+{
+	unsigned char *ptr = d;
+	unsigned char c;
+
+	/*
+	 * Send an initial END character to flush out any
+	 * data that may have accumulated in the receiver
+	 * due to line noise.
+	 */
+
+	*ptr++ = X25_END;	/* Send 10111110 bit seq */
+
+	/*
+	 * For each byte in the packet, send the appropriate
+	 * character sequence, according to the X.25 protocol.
+	 */
+
+	while (len-- > 0) 
+	{
+		switch(c = *s++) 
+		{
+			case X25_END:
+				*ptr++ = X25_ESC;
+				*ptr++ = X25_ESCAPE(X25_END);
+				break;
+			case X25_ESC:
+				*ptr++ = X25_ESC;
+				*ptr++ = X25_ESCAPE(X25_ESC);
+				break;
+			 default:
+				*ptr++ = c;
+				break;
+		}
+	}
+	*ptr++ = X25_END;
+	return (ptr - d);
+}
+
+static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
+{
+
+	switch(s) 
+	{
+		case X25_END:
+			if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))  
+			{
+				x25_asy_bump(sl);
+			}
+			clear_bit(SLF_ESCAPE, &sl->flags);
+			sl->rcount = 0;
+			return;
+
+		case X25_ESC:
+			set_bit(SLF_ESCAPE, &sl->flags);
+			return;
+			
+		case X25_ESCAPE(X25_ESC):
+		case X25_ESCAPE(X25_END):
+			if (clear_bit(SLF_ESCAPE, &sl->flags))
+				s = X25_UNESCAPE(s);
+			break;
+	}
+	if (!test_bit(SLF_ERROR, &sl->flags))  
+	{
+		if (sl->rcount < sl->buffsize)  
+		{
+			sl->rbuff[sl->rcount++] = s;
+			return;
+		}
+		sl->rx_over_errors++;
+		set_bit(SLF_ERROR, &sl->flags);
+	}
+}
+
+
+/* Perform I/O control on an active X.25 channel. */
+static int x25_asy_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
+{
+	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
+
+	/* First make sure we're connected. */
+	if (!sl || sl->magic != X25_ASY_MAGIC) {
+		return -EINVAL;
+	}
+
+	switch(cmd) 
+	{
+		case SIOCGIFNAME:
+			if(copy_to_user(arg, sl->dev->name, strlen(sl->dev->name) + 1))
+				return -EFAULT;
+			return 0;
+
+		case SIOCSIFHWADDR:
+			return -EINVAL;
+
+		/* Allow stty to read, but not set, the serial port */
+		case TCGETS:
+		case TCGETA:
+			return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg);
+
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+static int x25_asy_open_dev(struct device *dev)
+{
+	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+	if(sl->tty==NULL)
+		return -ENODEV;
+	return 0;
+}
+
+/* Initialize X.25 control device -- register X.25 line discipline */
+#ifdef MODULE
+static int x25_asy_init_ctrl_dev(void)
+#else	/* !MODULE */
+int x25_asy_init_ctrl_dev(struct device *dummy)
+#endif	/* !MODULE */
+{
+	int status;
+
+	if (x25_asy_maxdev < 4) x25_asy_maxdev = 4; /* Sanity */
+
+	printk(KERN_INFO "X.25 async: version 0.00 ALPHA (dynamic channels, max=%d).\n",
+		x25_asy_maxdev );
+	x25_asy_ctrls = (x25_asy_ctrl_t **) kmalloc(sizeof(void*)*x25_asy_maxdev, GFP_KERNEL);
+	if (x25_asy_ctrls == NULL)
+	{
+		printk("X25 async: Can't allocate x25_asy_ctrls[] array!  Uaargh! (-> No X.25 available)\n");
+		return -ENOMEM;
+	}
+
+	/* Clear the pointer array, we allocate devices when we need them */
+	memset(x25_asy_ctrls, 0, sizeof(void*)*x25_asy_maxdev); /* Pointers */
+
+	/* Fill in our line protocol discipline, and register it */
+	memset(&x25_ldisc, 0, sizeof(x25_ldisc));
+	x25_ldisc.magic  = TTY_LDISC_MAGIC;
+	x25_ldisc.name   = "X.25";
+	x25_ldisc.flags  = 0;
+	x25_ldisc.open   = x25_asy_open_tty;
+	x25_ldisc.close  = x25_asy_close_tty;
+	x25_ldisc.read   = NULL;
+	x25_ldisc.write  = NULL;
+	x25_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
+				   unsigned int, unsigned long)) x25_asy_ioctl;
+	x25_ldisc.poll   = NULL;
+	x25_ldisc.receive_buf = x25_asy_receive_buf;
+	x25_ldisc.receive_room = x25_asy_receive_room;
+	x25_ldisc.write_wakeup = x25_asy_write_wakeup;
+	if ((status = tty_register_ldisc(N_X25, &x25_ldisc)) != 0)  {
+		printk("X.25 async: can't register line discipline (err = %d)\n", status);
+	}
+
+#ifdef MODULE
+	return status;
+#else
+	/* Return "not found", so that dev_init() will unlink
+	 * the placeholder device entry for us.
+	 */
+	return ENODEV;
+#endif
+      }
+
+
+/* Initialise the X.25 driver.  Called by the device init code */
+
+int x25_asy_init(struct device *dev)
+{
+	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+
+	if (sl == NULL)		/* Allocation failed ?? */
+		return -ENODEV;
+
+	/* Set up the control block. (And clear statistics) */
+
+	memset(sl, 0, sizeof (struct x25_asy));
+	sl->magic  = X25_ASY_MAGIC;
+	sl->dev	   = dev;
+
+	/*
+	 *	Finish setting up the DEVICE info. 
+	 */
+	 
+	dev->mtu		= SL_MTU;
+	dev->hard_start_xmit	= x25_asy_xmit;
+	dev->open		= x25_asy_open_dev;
+	dev->stop		= x25_asy_close;
+	dev->get_stats	        = x25_asy_get_stats;
+	dev->hard_header_len	= 0;
+	dev->addr_len		= 0;
+	dev->type		= ARPHRD_X25;
+	dev->tx_queue_len	= 10;
+
+	dev_init_buffers(dev);
+	
+	/* New-style flags. */
+	dev->flags		= IFF_NOARP;
+	dev->family		= AF_X25;
+	dev->pa_addr		= 0;
+	dev->pa_brdaddr	        = 0;
+	dev->pa_mask		= 0;
+	dev->pa_alen		= 4;
+
+	return 0;
+}
+#ifdef MODULE
+
+int
+init_module(void)
+{
+	return x25_asy_init_ctrl_dev();
+}
+
+void
+cleanup_module(void)
+{
+	int i;
+
+	if (x25_asy_ctrls != NULL)
+	{
+		for (i = 0; i < x25_asy_maxdev; i++)
+		{
+			if (x25_asy_ctrls[i])
+			{
+				/*
+				 * VSV = if dev->start==0, then device
+				 * unregistered while close proc.
+				 */
+				if (x25_asy_ctrls[i]->dev.start)
+					unregister_netdev(&(x25_asy_ctrls[i]->dev));
+
+				kfree(x25_asy_ctrls[i]);
+				x25_asy_ctrls[i] = NULL;
+			}
+		}
+		kfree(x25_asy_ctrls);
+		x25_asy_ctrls = NULL;
+	}
+	if ((i = tty_register_ldisc(N_X25, NULL)))
+	{
+		printk("X.25 async: can't unregister line discipline (err = %d)\n", i);
+	}
+}
+#endif /* MODULE */
+
diff -u --recursive --new-file v2.1.30/linux/drivers/net/x25_asy.h linux/drivers/net/x25_asy.h
--- v2.1.30/linux/drivers/net/x25_asy.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/x25_asy.h	Mon Mar 31 12:52:31 1997
@@ -0,0 +1,58 @@
+#ifndef _LINUX_X25_ASY_H
+#define _LINUX_X25_ASY_H
+
+/* X.25 asy configuration. */
+#define SL_NRUNIT	256		/* MAX number of X.25 channels;
+					   This can be overridden with
+					   insmod -ox25_asy_maxdev=nnn	*/
+#define SL_MTU		256	
+
+/* X25 async protocol characters. */
+#define X25_END         0x7E		/* indicates end of frame	*/
+#define X25_ESC         0x7D		/* indicates byte stuffing	*/
+#define X25_ESCAPE(x)	((x)^0x20)
+#define X25_UNESCAPE(x)	((x)^0x20)
+
+
+struct x25_asy {
+  int			magic;
+
+  /* Various fields. */
+  struct tty_struct	*tty;		/* ptr to TTY structure		*/
+  struct device		*dev;		/* easy for intr handling	*/
+
+  /* These are pointers to the malloc()ed frame buffers. */
+  unsigned char		*rbuff;		/* receiver buffer		*/
+  int                   rcount;         /* received chars counter       */
+  unsigned char		*xbuff;		/* transmitter buffer		*/
+  unsigned char         *xhead;         /* pointer to next byte to XMIT */
+  int                   xleft;          /* bytes left in XMIT queue     */
+
+  /* X.25 interface statistics. */
+  unsigned long		rx_packets;	/* inbound frames counter	*/
+  unsigned long         tx_packets;     /* outbound frames counter      */
+  unsigned long		rx_bytes;	/* inbound byte counte		*/
+  unsigned long         tx_bytes;       /* outbound byte counter	*/
+  unsigned long         rx_errors;      /* Parity, etc. errors          */
+  unsigned long         tx_errors;      /* Planned stuff                */
+  unsigned long         rx_dropped;     /* No memory for skb            */
+  unsigned long         tx_dropped;     /* When MTU change              */
+  unsigned long         rx_over_errors; /* Frame bigger then X.25 buf.  */
+
+  int			mtu;		/* Our mtu (to spot changes!)   */
+  int                   buffsize;       /* Max buffers sizes            */
+
+  unsigned int		flags;		/* Flag values/ mode etc	*/
+#define SLF_INUSE	0		/* Channel in use               */
+#define SLF_ESCAPE	1               /* ESC received                 */
+#define SLF_ERROR	2               /* Parity, etc. error           */
+#define SLF_OUTWAIT	4		/* Waiting for output		*/
+};
+
+
+
+#define X25_ASY_MAGIC 0x5303
+
+extern int x25_asy_init(struct device *dev);
+
+#endif	/* _LINUX_X25_ASY.H */
diff -u --recursive --new-file v2.1.30/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.1.30/linux/drivers/pci/pci.c	Mon Mar 17 14:54:27 1997
+++ linux/drivers/pci/pci.c	Mon Mar 31 12:52:31 1997
@@ -94,7 +94,8 @@
 	DEVICE( TRIDENT,	TRIDENT_9660,	"TG 9660"),
 	DEVICE( AI,		AI_M1435,	"M1435"),
 	DEVICE( MATROX,		MATROX_MGA_2,	"Atlas PX2085"),
-	DEVICE( MATROX,		MATROX_MIL     ,"Millennium"),
+	DEVICE( MATROX,		MATROX_MIL,	"Millennium"),
+	DEVICE( MATROX,		MATROX_MYS,	"Mystique"),
 	DEVICE( MATROX,		MATROX_MGA_IMP,	"MGA Impression"),
 	DEVICE( CT,		CT_65545,	"65545"),
 	DEVICE( CT,		CT_65548,	"65548"),
diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/openprom.c linux/drivers/sbus/char/openprom.c
--- v2.1.30/linux/drivers/sbus/char/openprom.c	Mon Mar 17 14:54:28 1997
+++ linux/drivers/sbus/char/openprom.c	Wed Apr  2 17:43:21 1997
@@ -549,10 +549,11 @@
 	return 0;
 }
 
-static void openprom_release(struct inode * inode, struct file * file)
+static int openprom_release(struct inode * inode, struct file * file)
 {
 	kfree_s(file->private_data, sizeof(DATA));
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 static struct file_operations openprom_fops = {
diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/rtc.c linux/drivers/sbus/char/rtc.c
--- v2.1.30/linux/drivers/sbus/char/rtc.c	Sun Jan 26 02:07:18 1997
+++ linux/drivers/sbus/char/rtc.c	Wed Apr  2 17:43:21 1997
@@ -118,10 +118,11 @@
 	return 0;
 }
 
-static void rtc_release(struct inode *inode, struct file *file)
+static int rtc_release(struct inode *inode, struct file *file)
 {
 	MOD_DEC_USE_COUNT;
 	rtc_busy = 0;
+	return 0;
 }
 
 static struct file_operations rtc_fops = {
diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/sunfb.c linux/drivers/sbus/char/sunfb.c
--- v2.1.30/linux/drivers/sbus/char/sunfb.c	Thu Mar 27 14:40:05 1997
+++ linux/drivers/sbus/char/sunfb.c	Wed Apr  2 17:43:21 1997
@@ -301,7 +301,6 @@
 	fb_ioctl,
 	fb_mmap,
 	fb_open,		/* open */
-	(void(*)(struct inode *, struct file *))
 	fb_close,		/* close */
 };
 
diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c
--- v2.1.30/linux/drivers/sbus/char/sunkbd.c	Thu Mar 27 14:40:05 1997
+++ linux/drivers/sbus/char/sunkbd.c	Wed Apr  2 17:43:21 1997
@@ -66,6 +66,13 @@
 unsigned char kbd_read_mask = 0x01;	  /* modified by psaux.c */
 unsigned char aux_device_present = 0x00;  /* To make kernel/ksyms.c happy */
 
+struct wait_queue * keypress_wait = NULL;
+
+void keyboard_wait_for_keypress(void)
+{
+	sleep_on(&keypress_wait);
+}
+
 /*
  * global state includes the following, and various static variables
  * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
@@ -1382,7 +1389,7 @@
 	return 0;
 }
 
-static void
+static int
 kbd_close (struct inode *i, struct file *f)
 {
 	if (--kbd_active)
@@ -1395,6 +1402,7 @@
 	kbd_opened = 0;
 
 	kbd_fasync (i, f, 0);
+	return 0;
 }
 
 static struct
diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/sunmouse.c linux/drivers/sbus/char/sunmouse.c
--- v2.1.30/linux/drivers/sbus/char/sunmouse.c	Mon Mar 17 14:54:28 1997
+++ linux/drivers/sbus/char/sunmouse.c	Wed Apr  2 17:43:21 1997
@@ -337,13 +337,14 @@
 	return 0;
 }
 
-static void
+static int
 sun_mouse_close(struct inode *inode, struct file *file)
 {
 	sun_mouse_fasync (inode, file, 0);
 	if (--sunmouse.active)
-		return;
+		return 0;
 	sunmouse.ready = 0;
+	return 0;
 }
 
 static long
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- v2.1.30/linux/drivers/scsi/BusLogic.c	Thu Mar 27 14:40:05 1997
+++ linux/drivers/scsi/BusLogic.c	Sat Mar 29 09:01:00 1997
@@ -27,8 +27,8 @@
 */
 
 
-#define BusLogic_DriverVersion		"2.0.8"
-#define BusLogic_DriverDate		"17 March 1997"
+#define BusLogic_DriverVersion		"2.0.9"
+#define BusLogic_DriverDate		"29 March 1997"
 
 
 #include <linux/module.h>
@@ -295,15 +295,16 @@
   CCB->NextAll = HostAdapter->All_CCBs;
   HostAdapter->Free_CCBs = CCB;
   HostAdapter->All_CCBs = CCB;
+  HostAdapter->AllocatedCCBs++;
   return true;
 }
 
 
 /*
-  BusLogic_CreateCCBs allocates the initial CCBs for Host Adapter.
+  BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
 */
 
-static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter)
+static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
 {
   int Allocated;
   for (Allocated = 0; Allocated < HostAdapter->InitialCCBs; Allocated++)
@@ -335,6 +336,32 @@
 
 
 /*
+  BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter.  If
+  allocation fails and there are no remaining CCBs available, the Driver Queue
+  Depth is decreased to a known safe value to avoid potential deadlocks when
+  multiple host adapters share the same IRQ Channel.
+*/
+
+static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
+					  int AdditionalCCBs,
+					  boolean SuccessMessageP)
+{
+  int Allocated;
+  if (AdditionalCCBs <= 0) return;
+  for (Allocated = 0; Allocated < AdditionalCCBs; Allocated++)
+    if (!BusLogic_CreateCCB(HostAdapter)) break;
+  if (Allocated > 0 && SuccessMessageP)
+    BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
+		    HostAdapter, Allocated, HostAdapter->AllocatedCCBs);
+  if (Allocated > 0) return;
+  BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
+  HostAdapter->DriverQueueDepth =
+    HostAdapter->AllocatedCCBs - (HostAdapter->MaxTargetDevices - 1);
+  HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
+}
+
+
+/*
   BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
   allocating more memory from the Kernel if necessary.  The Host Adapter's
   Lock should already have been acquired by the caller.
@@ -345,24 +372,23 @@
 {
   static unsigned long SerialNumber = 0;
   BusLogic_CCB_T *CCB;
-  int Allocated;
   CCB = HostAdapter->Free_CCBs;
   if (CCB != NULL)
     {
       CCB->SerialNumber = ++SerialNumber;
       HostAdapter->Free_CCBs = CCB->Next;
       CCB->Next = NULL;
+      if (HostAdapter->Free_CCBs == NULL)
+	BusLogic_CreateAdditionalCCBs(HostAdapter,
+				      HostAdapter->IncrementalCCBs,
+				      true);
       return CCB;
     }
-  for (Allocated = 0; Allocated < HostAdapter->IncrementalCCBs; Allocated++)
-    if (!BusLogic_CreateCCB(HostAdapter)) break;
+  BusLogic_CreateAdditionalCCBs(HostAdapter,
+				HostAdapter->IncrementalCCBs,
+				true);
   CCB = HostAdapter->Free_CCBs;
-  if (CCB == NULL)
-    {
-      BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
-      return NULL;
-    }
-  BusLogic_Notice("Allocated %d additional CCBs\n", HostAdapter, Allocated);
+  if (CCB == NULL) return NULL;
   CCB->SerialNumber = ++SerialNumber;
   HostAdapter->Free_CCBs = CCB->Next;
   CCB->Next = NULL;
@@ -1514,7 +1540,7 @@
       HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
       HostAdapter->MaxLogicalUnits = 32;
       HostAdapter->InitialCCBs = 64;
-      HostAdapter->IncrementalCCBs = 32;
+      HostAdapter->IncrementalCCBs = 16;
       HostAdapter->DriverQueueDepth = 255;
       HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
       HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
@@ -1833,14 +1859,14 @@
       HostAdapter->StrictRoundRobinModeSupport = true;
       HostAdapter->MailboxCount = 255;
       HostAdapter->InitialCCBs = 64;
-      HostAdapter->IncrementalCCBs = 32;
+      HostAdapter->IncrementalCCBs = 16;
     }
   else
     {
       HostAdapter->StrictRoundRobinModeSupport = false;
       HostAdapter->MailboxCount = 32;
       HostAdapter->InitialCCBs = 32;
-      HostAdapter->IncrementalCCBs = 4;
+      HostAdapter->IncrementalCCBs = 8;
     }
   HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
   /*
@@ -2604,6 +2630,7 @@
   int TaggedQueueDepth = HostAdapter->TaggedQueueDepth;
   int UntaggedQueueDepth = HostAdapter->UntaggedQueueDepth;
   int TaggedDeviceCount = 0, UntaggedDeviceCount = 0;
+  int DesiredCCBs = HostAdapter->MaxTargetDevices - 1;
   SCSI_Device_T *Device;
   for (Device = DeviceList; Device != NULL; Device = Device->next)
     if (Device->host == Host)
@@ -2630,7 +2657,11 @@
 	  Device->queue_depth = TaggedQueueDepth;
 	else Device->queue_depth = UntaggedQueueDepth;
 	HostAdapter->QueueDepth[Device->id] = Device->queue_depth;
+	DesiredCCBs += Device->queue_depth;
       }
+  BusLogic_CreateAdditionalCCBs(HostAdapter,
+				DesiredCCBs - HostAdapter->AllocatedCCBs,
+				false);
 }
 
 
@@ -2744,16 +2775,16 @@
       /*
 	Read the Host Adapter Configuration, Configure the Host Adapter,
 	Acquire the System Resources necessary to use the Host Adapter,
-	then Test Interrupts, Create the Mailboxes, CCBs, and Target
-	Device Statistics, Initialize the Host Adapter, and finally
-	perform Target Device Inquiry.
+	then Test Interrupts, Create the Mailboxes, Initial CCBs, and
+	Target Device Statistics, Initialize the Host Adapter, and
+	finally perform Target Device Inquiry.
       */
       if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
 	  BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
 	  BusLogic_AcquireResources(HostAdapter) &&
 	  BusLogic_TestInterrupts(HostAdapter) &&
 	  BusLogic_CreateMailboxes(HostAdapter) &&
-	  BusLogic_CreateCCBs(HostAdapter) &&
+	  BusLogic_CreateInitialCCBs(HostAdapter) &&
 	  BusLogic_CreateTargetDeviceStatistics(HostAdapter) &&
 	  BusLogic_InitializeHostAdapter(HostAdapter) &&
 	  BusLogic_TargetDeviceInquiry(HostAdapter))
@@ -4133,6 +4164,11 @@
   TargetDeviceStatistics = HostAdapter->TargetDeviceStatistics;
   Buffer = HostAdapter->MessageBuffer;
   Length = HostAdapter->MessageBufferLength;
+  Length += sprintf(&Buffer[Length], "\n\
+Current Driver Queue Depth:	%d\n\
+Currently Allocated CCBs:	%d\n",
+		    HostAdapter->DriverQueueDepth,
+		    HostAdapter->AllocatedCCBs);
   Length += sprintf(&Buffer[Length], "\n\n\
 			   DATA TRANSFER STATISTICS\n\
 \n\
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/BusLogic.h linux/drivers/scsi/BusLogic.h
--- v2.1.30/linux/drivers/scsi/BusLogic.h	Thu Mar 27 14:40:05 1997
+++ linux/drivers/scsi/BusLogic.h	Sat Mar 29 09:01:00 1997
@@ -145,7 +145,7 @@
 */
 
 #define BusLogic_LineBufferSize			100
-#define BusLogic_MessageBufferSize		8900
+#define BusLogic_MessageBufferSize		9900
 
 
 /*
@@ -1311,6 +1311,7 @@
   unsigned short MailboxCount;
   unsigned short InitialCCBs;
   unsigned short IncrementalCCBs;
+  unsigned short AllocatedCCBs;
   unsigned short DriverQueueDepth;
   unsigned short HostAdapterQueueDepth;
   unsigned short TaggedQueueDepth;
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.1.30/linux/drivers/scsi/Config.in	Mon Mar 17 14:54:29 1997
+++ linux/drivers/scsi/Config.in	Mon Mar 31 13:25:24 1997
@@ -71,7 +71,7 @@
   fi
 fi
 if [ "$CONFIG_MCA" = "y" ]; then
-  bool 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA
+  dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI
 fi
 dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI
 dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/README.BusLogic linux/drivers/scsi/README.BusLogic
--- v2.1.30/linux/drivers/scsi/README.BusLogic	Thu Mar 27 14:40:05 1997
+++ linux/drivers/scsi/README.BusLogic	Sat Mar 29 09:01:00 1997
@@ -1,10 +1,10 @@
 	   BusLogic MultiMaster and FlashPoint SCSI Driver for Linux
 
-			  Version 2.0.8 for Linux 2.0
+			  Version 2.0.9 for Linux 2.0
 
 			      PRODUCTION RELEASE
 
-				 17 March 1997
+				 29 March 1997
 
 			       Leonard N. Zubkoff
 			       Dandelion Digital
@@ -37,11 +37,10 @@
 Linux kernel command line, allowing individual installations to tune driver
 performance and error recovery to their particular needs.
 
-The most recent versions of this driver will always be available from my Linux
-Home Page at URL "http://www.dandelion.com/Linux/" and by anonymous FTP from
-ftp.dandelion.com.  While only limited FTP directory listings are permitted,
-the introductory banner displayed on anonymous FTP login will provide a list of
-the driver versions and any other files that are available for retrieval.
+The latest information on Linux support for BusLogic SCSI Host Adapters, as
+well as the most recent release of this driver and the latest firmware for the
+BT-948/958/958D, will always be available from my Linux Home Page at URL
+"http://www.dandelion.com/Linux/".
 
 Bug reports should be sent via electronic mail to "lnz@dandelion.com".  Please
 include with the bug report the complete configuration messages reported by the
@@ -189,45 +188,45 @@
 
 FlashPoint Series PCI Host Adapters:
 
-FlashPoint LT (BT-930)	Ultra Fast Single-ended SCSI-2
-FlashPoint DL (BT-932)	Dual Channel Ultra Fast Single-ended SCSI-2
-FlashPoint LW (BT-950)	Ultra Wide Single-ended SCSI-2
-FlashPoint DW (BT-952)	Dual Channel Ultra Wide Single-ended SCSI-2
+FlashPoint LT (BT-930)	Ultra SCSI-2
+FlashPoint DL (BT-932)	Dual Channel Ultra SCSI-2
+FlashPoint LW (BT-950)	Wide Ultra SCSI-2
+FlashPoint DW (BT-952)	Dual Channel Wide Ultra SCSI-2
 
 MultiMaster "W" Series Host Adapters:
 
-BT-948	    PCI		Ultra Fast Single-ended SCSI-2
-BT-958	    PCI		Ultra Wide Single-ended SCSI-2
-BT-958D	    PCI		Ultra Wide Differential SCSI-2
+BT-948	    PCI		Ultra SCSI-2
+BT-958	    PCI		Wide Ultra SCSI-2
+BT-958D	    PCI		Wide Differential Ultra SCSI-2
 
 MultiMaster "C" Series Host Adapters:
 
-BT-946C	    PCI		Fast Single-ended SCSI-2
-BT-956C	    PCI		Fast Wide Single-ended SCSI-2
-BT-956CD    PCI		Fast Wide Differential SCSI-2
-BT-445C	    VLB		Fast Single-ended SCSI-2
-BT-747C	    EISA	Fast Single-ended SCSI-2
-BT-757C	    EISA	Fast Wide Single-ended SCSI-2
-BT-757CD    EISA	Fast Wide Differential SCSI-2
-BT-545C	    ISA		Fast Single-ended SCSI-2
-BT-540CF    ISA		Fast Single-ended SCSI-2
+BT-946C	    PCI		Fast SCSI-2
+BT-956C	    PCI		Wide Fast SCSI-2
+BT-956CD    PCI		Wide Differential Fast SCSI-2
+BT-445C	    VLB		Fast SCSI-2
+BT-747C	    EISA	Fast SCSI-2
+BT-757C	    EISA	Wide Fast SCSI-2
+BT-757CD    EISA	Wide Differential Fast SCSI-2
+BT-545C	    ISA		Fast SCSI-2
+BT-540CF    ISA		Fast SCSI-2
 
 MultiMaster "S" Series Host Adapters:
 
-BT-445S	    VLB		Fast Single-ended SCSI-2
-BT-747S	    EISA	Fast Single-ended SCSI-2
-BT-747D	    EISA	Fast Differential SCSI-2
-BT-757S	    EISA	Fast Wide Single-ended SCSI-2
-BT-757D	    EISA	Fast Wide Differential SCSI-2
-BT-545S	    ISA		Fast Single-ended SCSI-2
-BT-542D	    ISA		Fast Differential SCSI-2
-BT-742A	    EISA	Single-ended SCSI-2 (742A revision H)
-BT-542B	    ISA		Single-ended SCSI-2 (542B revision H)
+BT-445S	    VLB		Fast SCSI-2
+BT-747S	    EISA	Fast SCSI-2
+BT-747D	    EISA	Differential Fast SCSI-2
+BT-757S	    EISA	Wide Fast SCSI-2
+BT-757D	    EISA	Wide Differential Fast SCSI-2
+BT-545S	    ISA		Fast SCSI-2
+BT-542D	    ISA		Differential Fast SCSI-2
+BT-742A	    EISA	SCSI-2 (742A revision H)
+BT-542B	    ISA		SCSI-2 (542B revision H)
 
 MultiMaster "A" Series Host Adapters:
 
-BT-742A	    EISA	Single-ended SCSI-2 (742A revisions A - G)
-BT-542B	    ISA		Single-ended SCSI-2 (542B revisions A - G)
+BT-742A	    EISA	SCSI-2 (742A revisions A - G)
+BT-542B	    ISA		SCSI-2 (542B revisions A - G)
 
 AMI FastDisk Host Adapters that are true BusLogic MultiMaster clones are also
 supported by this driver.
@@ -380,7 +379,7 @@
 replacing "/usr/src" with wherever you keep your Linux kernel source tree:
 
   cd /usr/src
-  tar -xvzf BusLogic-2.0.8.tar.gz
+  tar -xvzf BusLogic-2.0.9.tar.gz
   mv README.* LICENSE.* BusLogic.[ch] FlashPoint.c linux/drivers/scsi
   patch -p < BusLogic.patch
   cd linux
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/README.FlashPoint linux/drivers/scsi/README.FlashPoint
--- v2.1.30/linux/drivers/scsi/README.FlashPoint	Tue Mar  4 10:25:24 1997
+++ linux/drivers/scsi/README.FlashPoint	Sat Mar 29 09:01:00 1997
@@ -1,5 +1,6 @@
-The BusLogic FlashPoint SCSI Host Adapters are now supported on Linux.  The
-upgrade program described below will remain available through March 1997.
+The BusLogic FlashPoint SCSI Host Adapters are now fully supported on Linux.
+The upgrade program described below has been officially terminated effective
+31 March 1997 since it is no longer needed.
 
 
 
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.1.30/linux/drivers/scsi/aha152x.c	Sat Sep 28 01:37:41 1996
+++ linux/drivers/scsi/aha152x.c	Mon Mar 31 12:52:31 1997
@@ -432,9 +432,13 @@
 #if defined(DEBUG_AHA152X)
 int aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT };
 int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT };
+MODULE_PARM(aha152x, "1-9i");
+MODULE_PARM(aha152x1, "1-9i");
 #else
 int aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 };
 int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 };
+MODULE_PARM(aha152x, "1-8i");
+MODULE_PARM(aha152x1, "1-8i");
 #endif
 #endif
 
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- v2.1.30/linux/drivers/scsi/g_NCR5380.c	Fri Nov 22 02:06:21 1996
+++ linux/drivers/scsi/g_NCR5380.c	Mon Mar 31 10:26:12 1997
@@ -330,7 +330,6 @@
 {
     int blocks = len / 128;
     int start = 0;
-    int i;
     int bl;
     NCR5380_local_declare();
 
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/ibmmca.c linux/drivers/scsi/ibmmca.c
--- v2.1.30/linux/drivers/scsi/ibmmca.c	Wed Dec 18 01:48:52 1996
+++ linux/drivers/scsi/ibmmca.c	Mon Mar 31 13:25:25 1997
@@ -38,8 +38,14 @@
    Aug 21 1996:  Modified the code which maps ldns to (pun,0).  It was
    insufficient for those of us with CD-ROM changers.
    - Chris Beauregard
+
+   Mar 16 1997: Modified driver to run as a module and to support
+   multiple adapters.
+   - Klaus Kudielka
  */
 
+#include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/head.h>
 #include <linux/types.h>
@@ -64,16 +70,10 @@
    Driver Description
 
    (A) Subsystem Detection
-   This is done in find_adapter() function and is easy, since
+   This is done in the ibmmca_detect() function and is easy, since
    the information about MCA integrated subsystems and plug-in 
    adapters is readily available in structure *mca_info.
 
-   In case you have more than one SCSI subsystem, only one can be used,
-   and its I/O port addresses should be standard 0x3540-7. To use more
-   than one adapter, the sharing of interrupt 14 would have to be 
-   supported in Linux (it is not at present, but could be, since MCA 
-   interrupts are level-triggered).
-
    (B) Physical Units, Logical Units, and Logical Devices
    There can be up to 56 devices on SCSI bus (besides the adapter):
    there are up to 7 "physical units" (each identified by physical unit 
@@ -136,7 +136,7 @@
    100% sure that it is correct for larger disks.
 
    (F) Kernel Boot Option 
-   The function ibmmca_scsi_setup() is called if option ibmmcascsi=n 
+   The function ibmmca_scsi_setup() is called if option ibmmcascsi=... 
    is passed to the kernel. See file linux/init/main.c for details.
  */
 
@@ -153,12 +153,25 @@
  * keyboard controller, serial port controller, VGA, and XGA.
  */
 
-/*addresses of hardware registers on the subsystem */
-#define IM_CMD_REG   0x3540	/*Command Interface, (4 bytes long) */
-#define IM_ATTN_REG  0x3544	/*Attention (1 byte) */
-#define IM_CTR_REG   0x3545	/*Basic Control (1 byte) */
-#define IM_INTR_REG  0x3546	/*Interrupt Status (1 byte, read only) */
-#define IM_STAT_REG  0x3547	/*Basic Status (1 byte, read only) */
+/* driver configuration */
+#define IM_MAX_HOSTS      8             /* maximum number of host adapters */
+#define IM_RESET_DELAY    10            /* seconds allowed for a reset */
+
+/* driver debugging - #undef all for normal operation */
+#undef  IM_DEBUG_TIMEOUT  50            /* if defined: count interrupts
+					   and ignore this special one */
+#undef  IM_DEBUG_INT                    /* verbose interrupt */
+#undef  IM_DEBUG_CMD                    /* verbose queuecommand */
+
+/* addresses of hardware registers on the subsystem */
+#define IM_CMD_REG   (shpnt->io_port)	/*Command Interface, (4 bytes long) */
+#define IM_ATTN_REG  (shpnt->io_port+4)	/*Attention (1 byte) */
+#define IM_CTR_REG   (shpnt->io_port+5)	/*Basic Control (1 byte) */
+#define IM_INTR_REG  (shpnt->io_port+6)	/*Interrupt Status (1 byte, r/o) */
+#define IM_STAT_REG  (shpnt->io_port+7)	/*Basic Status (1 byte, read only) */
+
+#define IM_IO_PORT   0x3540
+#define IM_N_IO_PORT 8
 
 /*requests going into the upper nibble of the Attention register */
 /*note: the lower nibble specifies the device(0-14), or subsystem(15) */
@@ -314,40 +327,67 @@
     int is_disk;
     int block_length;
   };
-static struct logical_device ld[MAX_LOG_DEV];
 
-/*if this is nonzero, ibmmcascsi option has been passed to the kernel */
-static int setup_called = 0;
+/* data structure for each host adapter */
+struct ibmmca_hostdata
+  {
+    /* array of logical devices */
+    struct logical_device _ld[MAX_LOG_DEV];
+    /* array to convert (pun, lun) into logical device number */
+    unsigned char _get_ldn[8][8];
+    /* used only when checking logical devices */
+    int _local_checking_phase_flag;
+    int _got_interrupt;
+    int _stat_result;
+    /* reset status (used only when doing reset) */
+    int _reset_status;
+  };
 
-/*scsi id (physical unit number) of subsystem (set during detect) */
-static int subsystem_pun;
+/* reset status values */
+#define IM_RESET_NOT_IN_PROGRESS   0
+#define IM_RESET_IN_PROGRESS       1
+#define IM_RESET_FINISHED_OK       2
+#define IM_RESET_FINISHED_FAIL     3
 
-/*array to convert (pun, lun) into logical device number */
-static unsigned char get_ldn[8][8];
+/* macros to access host data structure */
+#define HOSTDATA(shpnt) ((struct ibmmca_hostdata *) shpnt->hostdata)
+#define subsystem_pun (shpnt->this_id)
+#define ld (HOSTDATA(shpnt)->_ld)
+#define get_ldn (HOSTDATA(shpnt)->_get_ldn)
+#define local_checking_phase_flag (HOSTDATA(shpnt)->_local_checking_phase_flag)
+#define got_interrupt (HOSTDATA(shpnt)->_got_interrupt)
+#define stat_result (HOSTDATA(shpnt)->_stat_result)
+#define reset_status (HOSTDATA(shpnt)->_reset_status)
+
+/*--------------------------------------------------------------------*/
+
+/* if this is nonzero, ibmmcascsi option has been passed to the kernel */
+static int io_port[IM_MAX_HOSTS] = { 0 };
+static int scsi_id[IM_MAX_HOSTS] = { 7 };
+
+MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
+MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
 
 /*counter of concurrent disk read/writes, to turn on/off disk led */
-static int disk_rw_in_progress;
+static int disk_rw_in_progress = 0;
 
-/*used only when checking logical devices */
-static int local_checking_phase_flag;
-static int got_interrupt;
-static int stat_result;
+/* host information */
+static int found = 0;
+static struct Scsi_Host *hosts[IM_MAX_HOSTS+1] = { NULL };
 
-/*reset status and its values (used only when doing reset) */
-static int reset_status;
-#define IM_RESET_NOT_IN_PROGRESS   0
-#define IM_RESET_IN_PROGRESS       1
-#define IM_RESET_FINISHED_OK       2
-#define IM_RESET_FINISHED_FAIL     3
+/*--------------------------------------------------------------------*/
 
 /*local functions */
 static void interrupt_handler (int irq, void *dev_id,
 			       struct pt_regs *regs);
-static void issue_cmd (unsigned long cmd_reg, unsigned char attn_reg);
+static void issue_cmd (struct Scsi_Host *shpnt, unsigned long cmd_reg,
+		       unsigned char attn_reg);
 static void internal_done (Scsi_Cmnd * cmd);
-static int find_subsystem (void);
-static void check_devices (void);
-static int device_exists (int ldn, int *is_disk, int *block_length);
+static void check_devices (struct Scsi_Host *shpnt);
+static int device_exists (struct Scsi_Host *shpnt, int ldn, int *is_disk,
+			  int *block_length);
+static struct Scsi_Host *ibmmca_register(Scsi_Host_Template * template,
+					 int port, int id);
 
 /*--------------------------------------------------------------------*/
 
@@ -355,16 +395,20 @@
 interrupt_handler (int irq, void *dev_id,
 		   struct pt_regs *regs)
 {
-  /*get command result and logical device */
-  unsigned int intr_reg = inb (IM_INTR_REG);
-  unsigned int cmd_result = intr_reg & 0xf0;
-  unsigned int ldn = intr_reg & 0x0f;
+  int i = 0;
+  struct Scsi_Host *shpnt;
+  unsigned int intr_reg;
+  unsigned int cmd_result;
+  unsigned int ldn;
 
-  if (!inb (IM_STAT_REG) & IM_INTR_REQUEST)
-    {
-      printk ("ibmmca SCSI: spurious/shared interrupt?\n");
-      return;
-    }
+  do shpnt = hosts[i++];
+  while (shpnt && !(inb(IM_STAT_REG) & IM_INTR_REQUEST));
+  if (!shpnt) return;
+
+  /*get command result and logical device */
+  intr_reg = inb(IM_INTR_REG);
+  cmd_result = intr_reg & 0xf0;
+  ldn = intr_reg & 0x0f;
 
   /*must wait for attention reg not busy, then send EOI to subsystem */
   while (1)
@@ -409,9 +453,6 @@
 		}
 	      else
 		{
-		  /*reset disk led counter, turn of disk led */
-		  disk_rw_in_progress = 0;
-		  PS2_DISK_LED_OFF ();
 		  reset_status = IM_RESET_FINISHED_OK;
 		}
 	      return;
@@ -420,16 +461,29 @@
 	    panic ("IBM MCA SCSI: invalid logical device number.\n");
 	}
 
+#ifdef IM_DEBUG_TIMEOUT
+      {
+	static int count = 0;
+
+	if (++count == IM_DEBUG_TIMEOUT) {
+	  printk("IBM MCA SCSI: Ignoring interrupt.\n");
+	  return;
+	}
+      }
+#endif
+
       /*if no command structure, just return, else clear cmd */
       cmd = ld[ldn].cmd;
       if (!cmd)
 	return;
       ld[ldn].cmd = 0;
 
-      /* printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", 
-         cmd->cmnd[0], intr_reg, 
-         ld[ldn].tsb.dev_status, ld[ldn].tsb.cmd_status, 
-         ld[ldn].tsb.dev_error, ld[ldn].tsb.cmd_error); */
+#ifdef IM_DEBUG_INT
+      printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", 
+	     cmd->cmnd[0], intr_reg, 
+	     ld[ldn].tsb.dev_status, ld[ldn].tsb.cmd_status, 
+	     ld[ldn].tsb.dev_error, ld[ldn].tsb.cmd_error);
+#endif
 
       /*if this is end of disk read/write, may turn off PS/2 disk led */
       if (ld[ldn].is_disk)
@@ -457,7 +511,8 @@
 /*--------------------------------------------------------------------*/
 
 static void 
-issue_cmd (unsigned long cmd_reg, unsigned char attn_reg)
+issue_cmd (struct Scsi_Host *shpnt, unsigned long cmd_reg,
+	   unsigned char attn_reg)
 {
   /*must wait for attention reg not busy */
   while (1)
@@ -487,83 +542,29 @@
 static int
 ibmmca_getinfo (char *buf, int slot, void *dev)
 {
+  struct Scsi_Host *shpnt = dev;
   int len = 0;
 
   len += sprintf (buf + len, "Subsystem PUN: %d\n", subsystem_pun);
-  len += sprintf (buf + len, "Detected at boot: %s\n",
-		  setup_called ? "No" : "Yes");
+  len += sprintf (buf + len, "I/O base address: 0x%x\n", shpnt->io_port);
   return len;
 }
 
-static int 
-find_subsystem (void)
-{
-  int j, list_size, slot;
-  unsigned char pos2, pos3;
-
-  /*if this is not MCA machine, return "nothing found" */
-  if (!MCA_bus)
-    return 0;
-
-  /*if ibmmcascsi setup option was passed to kernel, return "found" */
-  if (setup_called)
-    {
-      printk ("IBM MCA SCSI: forced detection, scsi id=%d.\n",
-	      subsystem_pun);
-      return 1;
-    }
-
-  /*first look for the SCSI integrated on the motherboard */
-  pos2 = mca_read_stored_pos (MCA_INTEGSCSI, 2);
-  if ((pos2 & 1) == 0)
-    {
-      pos3 = mca_read_stored_pos (MCA_INTEGSCSI, 3);
-      subsystem_pun = (pos3 & 0xe0) >> 5;
-      printk ("IBM MCA SCSI: integrated SCSI found, scsi id=%d.\n",
-	      subsystem_pun);
-      mca_set_adapter_name (MCA_INTEGSCSI, "PS/2 Integrated SCSI");
-      mca_set_adapter_procfn (MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
-			      NULL);
-      return 1;
-    }
-
-  list_size = sizeof (subsys_list) / sizeof (struct subsys_list_struct);
-  for (j = 0; j < list_size; j += 1)
-    {
-      if ((slot = mca_find_adapter (subsys_list[j].mca_id, 0)) != MCA_NOTFOUND)
-	{
-	  pos3 = mca_read_stored_pos (slot, 3);
-	  subsystem_pun = (pos3 & 0xe0) >> 5;
-	  printk ("IBM MCA SCSI: %s found in slot %d, scsi id=%d.\n",
-		  subsys_list[j].description, slot + 1, subsystem_pun);
-
-	  mca_set_adapter_name (slot, subsys_list[j].description);
-	  mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
-				  NULL);
-
-	  return 1;
-	}
-    }
-
-  /*return "nothing found" */
-  return 0;
-}
-
 /*--------------------------------------------------------------------*/
 
 static void 
-check_devices (void)
+check_devices(struct Scsi_Host *shpnt)
 {
   int is_disk, block_length;
   int ldn;
   int num_ldn = 0;
 
-  /*check ldn's from 0 to MAX_LOG_DEV to find which devices exist */
+  /* check ldn's from 0 to MAX_LOG_DEV to find which devices exist */
   for (ldn = 0; ldn < MAX_LOG_DEV; ldn++)
     {
-      if (device_exists (ldn, &is_disk, &block_length))
+      if (device_exists(shpnt, ldn, &is_disk, &block_length))
 	{
-	  printk ("IBM MCA SCSI: logical device found at ldn=%d.\n", ldn);
+	  printk("IBM MCA SCSI: logical device found at ldn=%d.\n", ldn);
 	  ld[ldn].is_disk = is_disk;
 	  ld[ldn].block_length = block_length;
 	  get_ldn[num_ldn / 8][num_ldn % 8] = ldn;
@@ -577,7 +578,8 @@
 /*--------------------------------------------------------------------*/
 
 static int 
-device_exists (int ldn, int *is_disk, int *block_length)
+device_exists(struct Scsi_Host *shpnt, int ldn, int *is_disk,
+	      int *block_length)
 {
   struct im_scb scb;
   struct im_tsb tsb;
@@ -596,7 +598,7 @@
 
       /*issue scb to passed ldn, and busy wait for interrupt */
       got_interrupt = 0;
-      issue_cmd (virt_to_bus(&scb), IM_SCB | ldn);
+      issue_cmd (shpnt, virt_to_bus(&scb), IM_SCB | ldn);
       while (!got_interrupt)
 	barrier ();
 
@@ -633,7 +635,7 @@
 
 	  /*issue scb to passed ldn, and busy wait for interrupt */
 	  got_interrupt = 0;
-	  issue_cmd (virt_to_bus(&scb), IM_SCB | ldn);
+	  issue_cmd (shpnt, virt_to_bus(&scb), IM_SCB | ldn);
 	  while (!got_interrupt)
 	    barrier ();
 
@@ -656,47 +658,154 @@
 
 /*--------------------------------------------------------------------*/
 
+#ifdef CONFIG_SCSI_IBMMCA
+
 void 
 ibmmca_scsi_setup (char *str, int *ints)
 {
-  /*verify that one value (between 0 and 7) was specified */
-  if (setup_called++ || ints[0] != 1 || ints[1] < 0 || ints[1] >= 8)
+  int i;
+
+  for (i = 0; i < IM_MAX_HOSTS && i < ints[0]; i++)
     {
-      printk ("IBM MCA SCSI: usage: ibmmcascsi=<ADAPTER_SCSI_ID>\n");
-      return;
+      io_port[i] = ints[i+1];
     }
-  subsystem_pun = ints[1];
 }
 
+#endif
+
 /*--------------------------------------------------------------------*/
 
 int 
 ibmmca_detect (Scsi_Host_Template * template)
 {
-  /*initialize local data */
-  memset (ld, 0, sizeof ld);
-  memset (get_ldn, 0xff, sizeof get_ldn);
-  disk_rw_in_progress = 0;
-  reset_status = IM_RESET_NOT_IN_PROGRESS;
+  struct Scsi_Host *shpnt;
+  int port, id, i, list_size, slot;
+  unsigned pos2, pos3;
 
-  /*search for the subsystem, return 0 if not found */
-  if (!find_subsystem ())
+  /* if this is not MCA machine, return "nothing found" */
+  if (!MCA_bus)
     return 0;
 
-  /*get interrupt request level */
-  if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmca", 0))
+  /* get interrupt request level */
+  if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmca", hosts))
     {
-      printk ("IBM MCA SCSI: Unable to get IRQ %d.\n", IM_IRQ);
+      printk("IBM MCA SCSI: Unable to get IRQ %d.\n", IM_IRQ);
       return 0;
     }
 
-  /*check which logical devices exist */
+  /* if ibmmcascsi setup option was passed to kernel, return "found" */
+  for (i = 0; i < IM_MAX_HOSTS; i++)
+    if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8)
+    {
+      printk("IBM MCA SCSI: forced detection, io=0x%x, scsi id=%d.\n",
+	      io_port[i], scsi_id[i]);
+      ibmmca_register(template, io_port[i], scsi_id[i]);
+    }
+  if (found) return found;
+
+  /* first look for the SCSI integrated on the motherboard */
+  pos2 = mca_read_stored_pos(MCA_INTEGSCSI, 2);
+  if ((pos2 & 1) == 0)
+    {
+      pos3 = mca_read_stored_pos(MCA_INTEGSCSI, 3);
+      port = IM_IO_PORT + ((pos2 & 0x0e) << 2);
+      id = (pos3 & 0xe0) >> 5;
+      printk("IBM MCA SCSI: integrated SCSI found, io=0x%x, scsi id=%d.\n",
+	      port, id);
+      if ((shpnt = ibmmca_register(template, port, id)))
+	{
+	  mca_set_adapter_name(MCA_INTEGSCSI, "PS/2 Integrated SCSI");
+	  mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
+				 shpnt);
+	}
+    }
+
+  /* now look for other adapters */
+  list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
+  for (i = 0; i < list_size; i++)
+    {
+      slot = 0;
+      while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
+	     != MCA_NOTFOUND)
+	{
+	  pos2 = mca_read_stored_pos(slot, 2);
+	  pos3 = mca_read_stored_pos(slot, 3);
+	  port = IM_IO_PORT + ((pos2 & 0x0e) << 2);
+	  id = (pos3 & 0xe0) >> 5;
+	  printk ("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d.\n",
+		  subsys_list[i].description, slot + 1, port, id);
+	  if ((shpnt = ibmmca_register(template, port, id)))
+	    {
+	      mca_set_adapter_name (slot, subsys_list[i].description);
+	      mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
+				      shpnt);
+	    }
+	  slot++;
+	}
+    }
+
+  if (!found) {
+    free_irq (IM_IRQ, hosts);
+    printk("IBM MCA SCSI: No adapter attached.\n");
+  }
+
+  return found;
+}
+
+/*--------------------------------------------------------------------*/
+
+static struct Scsi_Host *
+ibmmca_register(Scsi_Host_Template * template, int port, int id)
+{
+  struct Scsi_Host *shpnt;
+  int i, j;
+
+  /* check I/O region */
+  if (check_region(port, IM_N_IO_PORT))
+    {
+      printk("IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x.\n",
+	port, port + IM_N_IO_PORT);
+      return NULL;
+    }
+
+  /* register host */
+  shpnt = scsi_register(template, sizeof(struct ibmmca_hostdata));
+  if (!shpnt)
+    {
+      printk("IBM MCA SCSI: Unable to register host.\n");
+      return NULL;
+    }
+
+  /* request I/O region */
+  request_region(port, IM_N_IO_PORT, "ibmmca");
+
+  hosts[found++] = shpnt;
+  shpnt->irq = IM_IRQ;
+  shpnt->io_port = port;
+  shpnt->n_io_port = IM_N_IO_PORT;
+  shpnt->this_id = id;
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      get_ldn[i][j] = MAX_LOG_DEV;
+
+  /* check which logical devices exist */
   local_checking_phase_flag = 1;
-  check_devices ();
+  check_devices(shpnt);
   local_checking_phase_flag = 0;
 
-  /*if got here, one ibm mca subsystem has been detected */
-  return 1;
+  /* an ibm mca subsystem has been detected */
+  return shpnt;
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+ibmmca_release(struct Scsi_Host *shpnt)
+{
+  release_region(shpnt->io_port, shpnt->n_io_port);
+  if (!(--found))
+    free_irq(shpnt->irq, hosts);
+  return 0;
 }
 
 /*--------------------------------------------------------------------*/
@@ -719,6 +828,7 @@
   unsigned int ldn;
   unsigned int scsi_cmd;
   struct im_scb *scb;
+  struct Scsi_Host *shpnt = cmd->host;
 
   /*if (target,lun) unassigned, return error */
   ldn = get_ldn[cmd->target][cmd->lun];
@@ -764,7 +874,9 @@
 
   /*fill scb information dependent on scsi command */
   scsi_cmd = cmd->cmnd[0];
-  /* printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn); */
+#ifdef IM_DEBUG_CMD
+  printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
+#endif
   switch (scsi_cmd)
     {
     case READ_6:
@@ -833,7 +945,7 @@
     }
 
   /*issue scb command, and return */
-  issue_cmd (virt_to_bus(scb), IM_SCB | ldn);
+  issue_cmd (shpnt, virt_to_bus(scb), IM_SCB | ldn);
   return 0;
 }
 
@@ -842,10 +954,13 @@
 int 
 ibmmca_abort (Scsi_Cmnd * cmd)
 {
-/*do a reset instead, since abort does not work well for me at present */
-  return ibmmca_reset (cmd);
+  /* The code below doesn't work right now, so we tell the upper layer
+     that we can't abort. This eventually causes a reset.
+     */
+  return SCSI_ABORT_SNOOZE;
 
 #if 0
+  struct Scsi_Host *shpnt = cmd->host;
   unsigned int ldn;
   void (*saved_done) (Scsi_Cmnd *);
 
@@ -870,7 +985,7 @@
   saved_done = cmd->scsi_done;
   cmd->scsi_done = internal_done;
   cmd->SCp.Status = 0;
-  issue_cmd (IM_ABORT_IMM_CMD, IM_IMM_CMD | ldn);
+  issue_cmd (shpnt, IM_ABORT_IMM_CMD, IM_IMM_CMD | ldn);
   while (!cmd->SCp.Status)
     barrier ();
 
@@ -889,22 +1004,42 @@
 /*--------------------------------------------------------------------*/
 
 int 
-ibmmca_reset (Scsi_Cmnd * cmd)
+ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
 {
-  /*issue reset immediate command to subsystem, and wait for interrupt */
-  printk ("IBM MCA SCSI: resetting all devices.\n");
+  struct Scsi_Host *shpnt = cmd->host;
+  int ticks = IM_RESET_DELAY*HZ;
+
+  if (local_checking_phase_flag) {
+    printk("IBM MCA SCSI: unable to reset while checking devices.\n");
+    return SCSI_RESET_SNOOZE;
+  }
+
+  /* issue reset immediate command to subsystem, and wait for interrupt */
+  printk("IBM MCA SCSI: resetting all devices.\n");
   cli ();
   reset_status = IM_RESET_IN_PROGRESS;
-  issue_cmd (IM_RESET_IMM_CMD, IM_IMM_CMD | 0xf);
-  while (reset_status == IM_RESET_IN_PROGRESS)
-    barrier ();
+  issue_cmd (shpnt, IM_RESET_IMM_CMD, IM_IMM_CMD | 0xf);
+  while (reset_status == IM_RESET_IN_PROGRESS && --ticks) {
+    udelay(1000000/HZ);
+    barrier();
+  }
 
-  /*if reset failed, just return error */
-  if (reset_status == IM_RESET_FINISHED_FAIL)
+  /* if reset did not complete, just return an error*/
+  if (!ticks) {
+    printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
+	   IM_RESET_DELAY);
+    reset_status = IM_RESET_FINISHED_FAIL;
     return SCSI_RESET_ERROR;
+  }
+  
+  /* if reset failed, just return an error */
+  if (reset_status == IM_RESET_FINISHED_FAIL) {
+    printk("IBM MCA SCSI: reset failed.\n");
+    return SCSI_RESET_ERROR;
+  }
 
-  /*so reset finished ok - call outstanding done's, and return success */
-  printk ("IBM MCA SCSI: reset finished well.\n");
+  /* so reset finished ok - call outstanding done's, and return success */
+  printk ("IBM MCA SCSI: reset completed without error.\n");
   {
     int i;
     for (i = 0; i < MAX_LOG_DEV; i++)
@@ -947,3 +1082,11 @@
 }
 
 /*--------------------------------------------------------------------*/
+
+#ifdef MODULE
+/* Eventually this will go into an include file, but this will be later */
+Scsi_Host_Template driver_template = IBMMCA;
+
+#include "scsi_module.c"
+#endif
+
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/ibmmca.h linux/drivers/scsi/ibmmca.h
--- v2.1.30/linux/drivers/scsi/ibmmca.h	Sun Jan 26 02:07:18 1997
+++ linux/drivers/scsi/ibmmca.h	Mon Mar 31 13:25:25 1997
@@ -8,10 +8,11 @@
 
 /*services provided to the higher level of Linux SCSI driver */
 int ibmmca_detect (Scsi_Host_Template *);
+int ibmmca_release (struct Scsi_Host *);
 int ibmmca_command (Scsi_Cmnd *);
 int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 int ibmmca_abort (Scsi_Cmnd *);
-int ibmmca_reset (Scsi_Cmnd *);
+int ibmmca_reset (Scsi_Cmnd *, unsigned int);
 int ibmmca_biosparam (Disk *, kdev_t, int *);
 
 /*structure for /proc filesystem */
@@ -25,7 +26,7 @@
           NULL,                 /*proc info fn*/      \
           "IBMMCA",             /*name*/              \
           ibmmca_detect,        /*detect fn*/         \
-          NULL,                 /*release fn*/        \
+          ibmmca_release,       /*release fn*/        \
           NULL,                 /*info fn*/           \
           ibmmca_command,       /*command fn*/        \
           ibmmca_queuecommand,  /*queuecommand fn*/   \
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c
--- v2.1.30/linux/drivers/scsi/in2000.c	Mon Oct 14 23:39:48 1996
+++ linux/drivers/scsi/in2000.c	Mon Mar 31 10:26:12 1997
@@ -127,6 +127,7 @@
 #include <linux/module.h>
 #endif
 
+#define uchar unsigned char
 
 #define IN2000_VERSION    "1.30"
 #define IN2000_DATE       "14/Oct/1996"
@@ -199,16 +200,296 @@
 static struct Scsi_Host *instance_list = 0;
 
 #ifdef PROC_INTERFACE
-unsigned long disc_allowed_total;
-unsigned long disc_taken_total;
+static unsigned long disc_allowed_total;
+static unsigned long disc_taken_total;
 #endif
 
+/* IN2000 io_port offsets */
+#define IO_WD_ASR       0x00     /* R - 3393 auxstat reg */
+#define     ASR_INT        0x80
+#define     ASR_LCI        0x40
+#define     ASR_BSY        0x20
+#define     ASR_CIP        0x10
+#define     ASR_PE         0x02
+#define     ASR_DBR        0x01
+#define IO_WD_ADDR      0x00     /* W - 3393 address reg */
+#define IO_WD_DATA      0x01     /* R/W - rest of 3393 regs */
+#define IO_FIFO         0x02     /* R/W - in2000 dual-port fifo (16 bits) */
+#define IN2000_FIFO_SIZE   2048  /*    fifo capacity in bytes */
+#define IO_CARD_RESET   0x03     /* W - in2000 start master reset */
+#define IO_FIFO_COUNT   0x04     /* R - in2000 fifo counter */
+#define IO_FIFO_WRITE   0x05     /* W - clear fifo counter, start write */
+#define IO_FIFO_READ    0x07     /* W - start fifo read */
+#define IO_LED_OFF      0x08     /* W - turn off in2000 activity LED */
+#define IO_SWITCHES     0x08     /* R - read in2000 dip switch */
+#define     SW_ADDR0       0x01  /*    bit 0 = bit 0 of index to io addr */
+#define     SW_ADDR1       0x02  /*    bit 1 = bit 1 of index io addr */
+#define     SW_DISINT      0x04  /*    bit 2 true if ints disabled */
+#define     SW_INT0        0x08  /*    bit 3 = bit 0 of index to interrupt */
+#define     SW_INT1        0x10  /*    bit 4 = bit 1 of index to interrupt */
+#define     SW_INT_SHIFT   3     /*    shift right this amount to right justify int bits */
+#define     SW_SYNC_DOS5   0x20  /*    bit 5 used by Always BIOS */
+#define     SW_FLOPPY      0x40  /*    bit 6 true if floppy enabled */
+#define     SW_BIT7        0x80  /*    bit 7 hardwired true (ground) */
+#define IO_LED_ON       0x09     /* W - turn on in2000 activity LED */
+#define IO_HARDWARE     0x0a     /* R - read in2000 hardware rev, stop reset */
+#define IO_INTR_MASK    0x0c     /* W - in2000 interrupt mask reg */
+#define     IMASK_WD       0x01  /*    WD33c93 interrupt mask */
+#define     IMASK_FIFO     0x02  /*    FIFO interrupt mask */
+
+/* wd register names */
+#define WD_OWN_ID    0x00
+#define WD_CONTROL   0x01
+#define WD_TIMEOUT_PERIOD  0x02
+#define WD_CDB_1     0x03
+#define WD_CDB_2     0x04
+#define WD_CDB_3     0x05
+#define WD_CDB_4     0x06
+#define WD_CDB_5     0x07
+#define WD_CDB_6     0x08
+#define WD_CDB_7     0x09
+#define WD_CDB_8     0x0a
+#define WD_CDB_9     0x0b
+#define WD_CDB_10    0x0c
+#define WD_CDB_11    0x0d
+#define WD_CDB_12    0x0e
+#define WD_TARGET_LUN      0x0f
+#define WD_COMMAND_PHASE   0x10
+#define WD_SYNCHRONOUS_TRANSFER  0x11
+#define WD_TRANSFER_COUNT_MSB 0x12
+#define WD_TRANSFER_COUNT  0x13
+#define WD_TRANSFER_COUNT_LSB 0x14
+#define WD_DESTINATION_ID  0x15
+#define WD_SOURCE_ID    0x16
+#define WD_SCSI_STATUS     0x17
+#define WD_COMMAND      0x18
+#define WD_DATA      0x19
+#define WD_QUEUE_TAG    0x1a
+#define WD_AUXILIARY_STATUS   0x1f
+
+/* WD commands */
+#define WD_CMD_RESET    0x00
+#define WD_CMD_ABORT    0x01
+#define WD_CMD_ASSERT_ATN  0x02
+#define WD_CMD_NEGATE_ACK  0x03
+#define WD_CMD_DISCONNECT  0x04
+#define WD_CMD_RESELECT    0x05
+#define WD_CMD_SEL_ATN     0x06
+#define WD_CMD_SEL      0x07
+#define WD_CMD_SEL_ATN_XFER   0x08
+#define WD_CMD_SEL_XFER    0x09
+#define WD_CMD_RESEL_RECEIVE  0x0a
+#define WD_CMD_RESEL_SEND  0x0b
+#define WD_CMD_WAIT_SEL_RECEIVE 0x0c
+#define WD_CMD_TRANS_ADDR  0x18
+#define WD_CMD_TRANS_INFO  0x20
+#define WD_CMD_TRANSFER_PAD   0x21
+#define WD_CMD_SBT_MODE    0x80
+
+/* SCSI Bus Phases */
+#define PHS_DATA_OUT    0x00
+#define PHS_DATA_IN     0x01
+#define PHS_COMMAND     0x02
+#define PHS_STATUS      0x03
+#define PHS_MESS_OUT    0x06
+#define PHS_MESS_IN     0x07
+
+/* Command Status Register definitions */
+
+  /* reset state interrupts */
+#define CSR_RESET    0x00
+#define CSR_RESET_AF    0x01
+
+  /* successful completion interrupts */
+#define CSR_RESELECT    0x10
+#define CSR_SELECT      0x11
+#define CSR_SEL_XFER_DONE  0x16
+#define CSR_XFER_DONE      0x18
+
+  /* paused or aborted interrupts */
+#define CSR_MSGIN    0x20
+#define CSR_SDP         0x21
+#define CSR_SEL_ABORT      0x22
+#define CSR_RESEL_ABORT    0x25
+#define CSR_RESEL_ABORT_AM 0x27
+#define CSR_ABORT    0x28
+
+  /* terminated interrupts */
+#define CSR_INVALID     0x40
+#define CSR_UNEXP_DISC     0x41
+#define CSR_TIMEOUT     0x42
+#define CSR_PARITY      0x43
+#define CSR_PARITY_ATN     0x44
+#define CSR_BAD_STATUS     0x45
+#define CSR_UNEXP    0x48
+
+  /* service required interrupts */
+#define CSR_RESEL    0x80
+#define CSR_RESEL_AM    0x81
+#define CSR_DISC     0x85
+#define CSR_SRV_REQ     0x88
+
+   /* Own ID/CDB Size register */
+#define OWNID_EAF    0x08
+#define OWNID_EHP    0x10
+#define OWNID_RAF    0x20
+#define OWNID_FS_8   0x00
+#define OWNID_FS_12  0x40
+#define OWNID_FS_16  0x80
+
+   /* Control register */
+#define CTRL_HSP     0x01
+#define CTRL_HA      0x02
+#define CTRL_IDI     0x04
+#define CTRL_EDI     0x08
+#define CTRL_HHP     0x10
+#define CTRL_POLLED  0x00
+#define CTRL_BURST   0x20
+#define CTRL_BUS     0x40
+#define CTRL_DMA     0x80
+
+   /* Timeout Period register */
+#define TIMEOUT_PERIOD_VALUE  20    /* results in 200 ms. */
+
+   /* Synchronous Transfer Register */
+#define STR_FSS      0x80
+
+   /* Destination ID register */
+#define DSTID_DPD    0x40
+#define DATA_OUT_DIR 0
+#define DATA_IN_DIR  1
+#define DSTID_SCC    0x80
+
+   /* Source ID register */
+#define SRCID_MASK   0x07
+#define SRCID_SIV    0x08
+#define SRCID_DSP    0x20
+#define SRCID_ES     0x40
+#define SRCID_ER     0x80
+
+
+
+#define DEFAULT_SX_PER     500   /* (ns) fairly safe */
+#define DEFAULT_SX_OFF     0     /* aka async */
+
+#define OPTIMUM_SX_PER     252   /* (ns) best we can do (mult-of-4) */
+#define OPTIMUM_SX_OFF     12    /* size of in2000 fifo */
+
+
+/* defines for hostdata->chip */
+
+#define C_WD33C93       0
+#define C_WD33C93A      1
+#define C_WD33C93B      2
+#define C_UNKNOWN_CHIP  100
+
+/* defines for hostdata->state */
+
+#define S_UNCONNECTED         0
+#define S_SELECTING           1
+#define S_RUNNING_LEVEL2      2
+#define S_CONNECTED           3
+#define S_PRE_TMP_DISC        4
+#define S_PRE_CMP_DISC        5
+
+/* defines for hostdata->fifo */
+
+#define FI_FIFO_UNUSED        0
+#define FI_FIFO_READING       1
+#define FI_FIFO_WRITING       2
+
+/* defines for hostdata->level2 */
+/* NOTE: only the first 3 are trustworthy at this point -
+ * having trouble when more than 1 device is reading/writing
+ * at the same time...
+ */
+
+#define L2_NONE      0  /* no combination commands - we get lots of ints */
+#define L2_SELECT    1  /* start with SEL_ATN_XFER, but never resume it */
+#define L2_BASIC     2  /* resume after STATUS ints & RDP messages */
+#define L2_DATA      3  /* resume after DATA_IN/OUT ints */
+#define L2_MOST      4  /* resume after anything except a RESELECT int */
+#define L2_RESELECT  5  /* resume after everything, including RESELECT ints */
+#define L2_ALL       6  /* always resume */
+
+/* defines for hostdata->disconnect */
+
+#define DIS_NEVER    0
+#define DIS_ADAPTIVE 1
+#define DIS_ALWAYS   2
+
+/* defines for hostdata->args */
+
+#define DB_TEST               1<<0
+#define DB_FIFO               1<<1
+#define DB_QUEUE_COMMAND      1<<2
+#define DB_EXECUTE            1<<3
+#define DB_INTR               1<<4
+#define DB_TRANSFER           1<<5
+#define DB_MASK               0x3f
+
+#define A_NO_SCSI_RESET       1<<15
+
+
+/* defines for hostdata->sync_xfer[] */
+
+#define SS_UNSET     0
+#define SS_FIRST     1
+#define SS_WAITING   2
+#define SS_SET       3
+
+/* defines for hostdata->proc */
+
+#define PR_VERSION   1<<0
+#define PR_INFO      1<<1
+#define PR_TOTALS    1<<2
+#define PR_CONNECTED 1<<3
+#define PR_INPUTQ    1<<4
+#define PR_DISCQ     1<<5
+#define PR_TEST      1<<6
+#define PR_STOP      1<<7
+
 
 #define read1_io(a)     (inb(hostdata->io_base+(a)))
 #define read2_io(a)     (inw(hostdata->io_base+(a)))
 #define write1_io(b,a)  (outb((b),hostdata->io_base+(a)))
 #define write2_io(w,a)  (outw((w),hostdata->io_base+(a)))
 
+
+struct sx_period {
+   unsigned int   period_ns;
+   uchar          reg_value;
+   };
+
+
+struct IN2000_hostdata {
+    struct Scsi_Host *next;
+    uchar            chip;             /* what kind of wd33c93 chip? */
+    uchar            microcode;        /* microcode rev if 'B' */
+    unsigned short   io_base;          /* IO port base */
+    unsigned int     dip_switch;       /* dip switch settings */
+    unsigned int     hrev;             /* hardware revision of card */
+    volatile uchar   busy[8];          /* index = target, bit = lun */
+    volatile Scsi_Cmnd *input_Q;       /* commands waiting to be started */
+    volatile Scsi_Cmnd *selecting;     /* trying to select this command */
+    volatile Scsi_Cmnd *connected;     /* currently connected command */
+    volatile Scsi_Cmnd *disconnected_Q;/* commands waiting for reconnect */
+    uchar            state;            /* what we are currently doing */
+    uchar            fifo;             /* what the FIFO is up to */
+    uchar            level2;           /* extent to which Level-2 commands are used */
+    uchar            disconnect;       /* disconnect/reselect policy */
+    unsigned int     args;             /* set from command-line argument */
+    uchar            incoming_msg[8];  /* filled during message_in phase */
+    int              incoming_ptr;     /* mainly used with EXTENDED messages */
+    uchar            outgoing_msg[8];  /* send this during next message_out */
+    int              outgoing_len;     /* length of outgoing message */
+    unsigned int     default_sx_per;   /* default transfer period for SCSI bus */
+    uchar            sync_xfer[8];     /* sync_xfer reg settings per target */
+    uchar            sync_stat[8];     /* status of sync negotiation per target */
+    uchar            sync_off;         /* bit mask: don't use sync with these targets */
+    uchar            proc;             /* bit mask: what's in proc output */
+    };
+
 /* These inline assembly defines are derived from a patch
  * sent to me by Bill Earnest. He's done a lot of very
  * valuable thinking, testing, and coding during his effort
@@ -243,7 +524,7 @@
    : "edx", "ecx", "esi" )       /* trashed */
 
 
-inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num)
+static inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num)
 {
    write1_io(reg_num,IO_WD_ADDR);
    return read1_io(IO_WD_DATA);
@@ -253,14 +534,14 @@
 #define READ_AUX_STAT() read1_io(IO_WD_ASR)
 
 
-inline void write_3393(struct IN2000_hostdata *hostdata, uchar reg_num, uchar value)
+static inline void write_3393(struct IN2000_hostdata *hostdata, uchar reg_num, uchar value)
 {
    write1_io(reg_num,IO_WD_ADDR);
    write1_io(value,IO_WD_DATA);
 }
 
 
-inline void write_3393_cmd(struct IN2000_hostdata *hostdata, uchar cmd)
+static inline void write_3393_cmd(struct IN2000_hostdata *hostdata, uchar cmd)
 {
 /*   while (READ_AUX_STAT() & ASR_CIP)
       printk("|");*/
@@ -269,7 +550,7 @@
 }
 
 
-uchar read_1_byte(struct IN2000_hostdata *hostdata)
+static uchar read_1_byte(struct IN2000_hostdata *hostdata)
 {
 uchar asr, x = 0;
 
@@ -284,7 +565,7 @@
 }
 
 
-void write_3393_count(struct IN2000_hostdata *hostdata, unsigned long value)
+static void write_3393_count(struct IN2000_hostdata *hostdata, unsigned long value)
 {
    write1_io(WD_TRANSFER_COUNT_MSB,IO_WD_ADDR);
    write1_io((value >> 16),IO_WD_DATA);
@@ -293,7 +574,7 @@
 }
 
 
-unsigned long read_3393_count(struct IN2000_hostdata *hostdata)
+static unsigned long read_3393_count(struct IN2000_hostdata *hostdata)
 {
 unsigned long value;
 
@@ -356,7 +637,7 @@
    return 7;
 }
 
-uchar calc_sync_xfer(unsigned int period, unsigned int offset)
+static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
 {
 uchar result;
 
@@ -368,7 +649,7 @@
 
 
 
-void in2000_execute(struct Scsi_Host *instance);
+static void in2000_execute(struct Scsi_Host *instance);
 
 int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
@@ -466,7 +747,7 @@
  * the input_Q, using the first command we find that's intended
  * for a currently non-busy target/lun.
  */
-void in2000_execute (struct Scsi_Host *instance)
+static void in2000_execute (struct Scsi_Host *instance)
 {
 struct IN2000_hostdata *hostdata;
 Scsi_Cmnd *cmd, *prev;
@@ -740,7 +1021,7 @@
 
 
 
-void transfer_pio(uchar *buf, int cnt,
+static void transfer_pio(uchar *buf, int cnt,
                   int data_in_dir, struct IN2000_hostdata *hostdata)
 {
 uchar asr;
@@ -776,7 +1057,7 @@
 
 
 
-void transfer_bytes(Scsi_Cmnd *cmd, int data_in_dir)
+static void transfer_bytes(Scsi_Cmnd *cmd, int data_in_dir)
 {
 struct IN2000_hostdata *hostdata;
 unsigned short *sp;
@@ -869,7 +1150,7 @@
  * re-think the multiple card capability....
  */
 
-void in2000_intr (int irqnum, void * dev_id, struct pt_regs *ptregs)
+static void in2000_intr (int irqnum, void * dev_id, struct pt_regs *ptregs)
 {
 struct Scsi_Host *instance;
 struct IN2000_hostdata *hostdata;
@@ -1655,7 +1936,7 @@
 #define RESET_CARD_AND_BUS 1
 #define B_FLAG 0x80
 
-int reset_hardware(struct Scsi_Host *instance, int type)
+static int reset_hardware(struct Scsi_Host *instance, int type)
 {
 struct IN2000_hostdata *hostdata;
 int qt,x;
@@ -1913,7 +2194,7 @@
 /* check_setup_strings() returns index if key found, 0 if not
  */
 
-int check_setup_strings(char *key, int *flags, int *val, char *buf)
+static int check_setup_strings(char *key, int *flags, int *val, char *buf)
 {
 int x;
 char *cp;
@@ -1951,21 +2232,21 @@
  * special macros declared in 'asm/io.h'. We use readb() and
  * readl() when reading from the card's BIOS area in in2000_detect().
  */
-const unsigned int *bios_tab[] = {
+static const unsigned int *bios_tab[] = {
    (unsigned int *)0xc8000,
    (unsigned int *)0xd0000,
    (unsigned int *)0xd8000,
    0
    };
 
-const unsigned short base_tab[] = {
+static const unsigned short base_tab[] = {
    0x220,
    0x200,
    0x110,
    0x100,
    };
 
-const int int_tab[] = {
+static const int int_tab[] = {
    15,
    14,
    11,
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/in2000.h linux/drivers/scsi/in2000.h
--- v2.1.30/linux/drivers/scsi/in2000.h	Sun Jan 26 02:07:18 1997
+++ linux/drivers/scsi/in2000.h	Mon Mar 31 10:26:12 1997
@@ -23,298 +23,13 @@
 #ifndef IN2000_H
 #define IN2000_H
 
-#include <asm/io.h>
-
-
-#define uchar unsigned char
-
-
-/* IN2000 io_port offsets */
-#define IO_WD_ASR       0x00     /* R - 3393 auxstat reg */
-#define     ASR_INT        0x80
-#define     ASR_LCI        0x40
-#define     ASR_BSY        0x20
-#define     ASR_CIP        0x10
-#define     ASR_PE         0x02
-#define     ASR_DBR        0x01
-#define IO_WD_ADDR      0x00     /* W - 3393 address reg */
-#define IO_WD_DATA      0x01     /* R/W - rest of 3393 regs */
-#define IO_FIFO         0x02     /* R/W - in2000 dual-port fifo (16 bits) */
-#define IN2000_FIFO_SIZE   2048  /*    fifo capacity in bytes */
-#define IO_CARD_RESET   0x03     /* W - in2000 start master reset */
-#define IO_FIFO_COUNT   0x04     /* R - in2000 fifo counter */
-#define IO_FIFO_WRITE   0x05     /* W - clear fifo counter, start write */
-#define IO_FIFO_READ    0x07     /* W - start fifo read */
-#define IO_LED_OFF      0x08     /* W - turn off in2000 activity LED */
-#define IO_SWITCHES     0x08     /* R - read in2000 dip switch */
-#define     SW_ADDR0       0x01  /*    bit 0 = bit 0 of index to io addr */
-#define     SW_ADDR1       0x02  /*    bit 1 = bit 1 of index io addr */
-#define     SW_DISINT      0x04  /*    bit 2 true if ints disabled */
-#define     SW_INT0        0x08  /*    bit 3 = bit 0 of index to interrupt */
-#define     SW_INT1        0x10  /*    bit 4 = bit 1 of index to interrupt */
-#define     SW_INT_SHIFT   3     /*    shift right this amount to right justify int bits */
-#define     SW_SYNC_DOS5   0x20  /*    bit 5 used by Always BIOS */
-#define     SW_FLOPPY      0x40  /*    bit 6 true if floppy enabled */
-#define     SW_BIT7        0x80  /*    bit 7 hardwired true (ground) */
-#define IO_LED_ON       0x09     /* W - turn on in2000 activity LED */
-#define IO_HARDWARE     0x0a     /* R - read in2000 hardware rev, stop reset */
-#define IO_INTR_MASK    0x0c     /* W - in2000 interrupt mask reg */
-#define     IMASK_WD       0x01  /*    WD33c93 interrupt mask */
-#define     IMASK_FIFO     0x02  /*    FIFO interrupt mask */
-
-/* wd register names */
-#define WD_OWN_ID    0x00
-#define WD_CONTROL   0x01
-#define WD_TIMEOUT_PERIOD  0x02
-#define WD_CDB_1     0x03
-#define WD_CDB_2     0x04
-#define WD_CDB_3     0x05
-#define WD_CDB_4     0x06
-#define WD_CDB_5     0x07
-#define WD_CDB_6     0x08
-#define WD_CDB_7     0x09
-#define WD_CDB_8     0x0a
-#define WD_CDB_9     0x0b
-#define WD_CDB_10    0x0c
-#define WD_CDB_11    0x0d
-#define WD_CDB_12    0x0e
-#define WD_TARGET_LUN      0x0f
-#define WD_COMMAND_PHASE   0x10
-#define WD_SYNCHRONOUS_TRANSFER  0x11
-#define WD_TRANSFER_COUNT_MSB 0x12
-#define WD_TRANSFER_COUNT  0x13
-#define WD_TRANSFER_COUNT_LSB 0x14
-#define WD_DESTINATION_ID  0x15
-#define WD_SOURCE_ID    0x16
-#define WD_SCSI_STATUS     0x17
-#define WD_COMMAND      0x18
-#define WD_DATA      0x19
-#define WD_QUEUE_TAG    0x1a
-#define WD_AUXILIARY_STATUS   0x1f
-
-/* WD commands */
-#define WD_CMD_RESET    0x00
-#define WD_CMD_ABORT    0x01
-#define WD_CMD_ASSERT_ATN  0x02
-#define WD_CMD_NEGATE_ACK  0x03
-#define WD_CMD_DISCONNECT  0x04
-#define WD_CMD_RESELECT    0x05
-#define WD_CMD_SEL_ATN     0x06
-#define WD_CMD_SEL      0x07
-#define WD_CMD_SEL_ATN_XFER   0x08
-#define WD_CMD_SEL_XFER    0x09
-#define WD_CMD_RESEL_RECEIVE  0x0a
-#define WD_CMD_RESEL_SEND  0x0b
-#define WD_CMD_WAIT_SEL_RECEIVE 0x0c
-#define WD_CMD_TRANS_ADDR  0x18
-#define WD_CMD_TRANS_INFO  0x20
-#define WD_CMD_TRANSFER_PAD   0x21
-#define WD_CMD_SBT_MODE    0x80
-
-/* SCSI Bus Phases */
-#define PHS_DATA_OUT    0x00
-#define PHS_DATA_IN     0x01
-#define PHS_COMMAND     0x02
-#define PHS_STATUS      0x03
-#define PHS_MESS_OUT    0x06
-#define PHS_MESS_IN     0x07
-
-/* Command Status Register definitions */
-
-  /* reset state interrupts */
-#define CSR_RESET    0x00
-#define CSR_RESET_AF    0x01
-
-  /* successful completion interrupts */
-#define CSR_RESELECT    0x10
-#define CSR_SELECT      0x11
-#define CSR_SEL_XFER_DONE  0x16
-#define CSR_XFER_DONE      0x18
-
-  /* paused or aborted interrupts */
-#define CSR_MSGIN    0x20
-#define CSR_SDP         0x21
-#define CSR_SEL_ABORT      0x22
-#define CSR_RESEL_ABORT    0x25
-#define CSR_RESEL_ABORT_AM 0x27
-#define CSR_ABORT    0x28
-
-  /* terminated interrupts */
-#define CSR_INVALID     0x40
-#define CSR_UNEXP_DISC     0x41
-#define CSR_TIMEOUT     0x42
-#define CSR_PARITY      0x43
-#define CSR_PARITY_ATN     0x44
-#define CSR_BAD_STATUS     0x45
-#define CSR_UNEXP    0x48
-
-  /* service required interrupts */
-#define CSR_RESEL    0x80
-#define CSR_RESEL_AM    0x81
-#define CSR_DISC     0x85
-#define CSR_SRV_REQ     0x88
-
-   /* Own ID/CDB Size register */
-#define OWNID_EAF    0x08
-#define OWNID_EHP    0x10
-#define OWNID_RAF    0x20
-#define OWNID_FS_8   0x00
-#define OWNID_FS_12  0x40
-#define OWNID_FS_16  0x80
-
-   /* Control register */
-#define CTRL_HSP     0x01
-#define CTRL_HA      0x02
-#define CTRL_IDI     0x04
-#define CTRL_EDI     0x08
-#define CTRL_HHP     0x10
-#define CTRL_POLLED  0x00
-#define CTRL_BURST   0x20
-#define CTRL_BUS     0x40
-#define CTRL_DMA     0x80
-
-   /* Timeout Period register */
-#define TIMEOUT_PERIOD_VALUE  20    /* results in 200 ms. */
-
-   /* Synchronous Transfer Register */
-#define STR_FSS      0x80
-
-   /* Destination ID register */
-#define DSTID_DPD    0x40
-#define DATA_OUT_DIR 0
-#define DATA_IN_DIR  1
-#define DSTID_SCC    0x80
-
-   /* Source ID register */
-#define SRCID_MASK   0x07
-#define SRCID_SIV    0x08
-#define SRCID_DSP    0x20
-#define SRCID_ES     0x40
-#define SRCID_ER     0x80
-
-
-
-#define DEFAULT_SX_PER     500   /* (ns) fairly safe */
-#define DEFAULT_SX_OFF     0     /* aka async */
-
-#define OPTIMUM_SX_PER     252   /* (ns) best we can do (mult-of-4) */
-#define OPTIMUM_SX_OFF     12    /* size of in2000 fifo */
-
-struct sx_period {
-   unsigned int   period_ns;
-   uchar          reg_value;
-   };
-
-
-struct IN2000_hostdata {
-    struct Scsi_Host *next;
-    uchar            chip;             /* what kind of wd33c93 chip? */
-    uchar            microcode;        /* microcode rev if 'B' */
-    unsigned short   io_base;          /* IO port base */
-    unsigned int     dip_switch;       /* dip switch settings */
-    unsigned int     hrev;             /* hardware revision of card */
-    volatile uchar   busy[8];          /* index = target, bit = lun */
-    volatile Scsi_Cmnd *input_Q;       /* commands waiting to be started */
-    volatile Scsi_Cmnd *selecting;     /* trying to select this command */
-    volatile Scsi_Cmnd *connected;     /* currently connected command */
-    volatile Scsi_Cmnd *disconnected_Q;/* commands waiting for reconnect */
-    uchar            state;            /* what we are currently doing */
-    uchar            fifo;             /* what the FIFO is up to */
-    uchar            level2;           /* extent to which Level-2 commands are used */
-    uchar            disconnect;       /* disconnect/reselect policy */
-    unsigned int     args;             /* set from command-line argument */
-    uchar            incoming_msg[8];  /* filled during message_in phase */
-    int              incoming_ptr;     /* mainly used with EXTENDED messages */
-    uchar            outgoing_msg[8];  /* send this during next message_out */
-    int              outgoing_len;     /* length of outgoing message */
-    unsigned int     default_sx_per;   /* default transfer period for SCSI bus */
-    uchar            sync_xfer[8];     /* sync_xfer reg settings per target */
-    uchar            sync_stat[8];     /* status of sync negotiation per target */
-    uchar            sync_off;         /* bit mask: don't use sync with these targets */
-    uchar            proc;             /* bit mask: what's in proc output */
-    };
-
-
-/* defines for hostdata->chip */
-
-#define C_WD33C93       0
-#define C_WD33C93A      1
-#define C_WD33C93B      2
-#define C_UNKNOWN_CHIP  100
-
-/* defines for hostdata->state */
-
-#define S_UNCONNECTED         0
-#define S_SELECTING           1
-#define S_RUNNING_LEVEL2      2
-#define S_CONNECTED           3
-#define S_PRE_TMP_DISC        4
-#define S_PRE_CMP_DISC        5
-
-/* defines for hostdata->fifo */
-
-#define FI_FIFO_UNUSED        0
-#define FI_FIFO_READING       1
-#define FI_FIFO_WRITING       2
-
-/* defines for hostdata->level2 */
-/* NOTE: only the first 3 are trustworthy at this point -
- * having trouble when more than 1 device is reading/writing
- * at the same time...
- */
-
-#define L2_NONE      0  /* no combination commands - we get lots of ints */
-#define L2_SELECT    1  /* start with SEL_ATN_XFER, but never resume it */
-#define L2_BASIC     2  /* resume after STATUS ints & RDP messages */
-#define L2_DATA      3  /* resume after DATA_IN/OUT ints */
-#define L2_MOST      4  /* resume after anything except a RESELECT int */
-#define L2_RESELECT  5  /* resume after everything, including RESELECT ints */
-#define L2_ALL       6  /* always resume */
-
-/* defines for hostdata->disconnect */
-
-#define DIS_NEVER    0
-#define DIS_ADAPTIVE 1
-#define DIS_ALWAYS   2
-
-/* defines for hostdata->args */
-
-#define DB_TEST               1<<0
-#define DB_FIFO               1<<1
-#define DB_QUEUE_COMMAND      1<<2
-#define DB_EXECUTE            1<<3
-#define DB_INTR               1<<4
-#define DB_TRANSFER           1<<5
-#define DB_MASK               0x3f
-
-#define A_NO_SCSI_RESET       1<<15
-
-
-/* defines for hostdata->sync_xfer[] */
-
-#define SS_UNSET     0
-#define SS_FIRST     1
-#define SS_WAITING   2
-#define SS_SET       3
-
-/* defines for hostdata->proc */
-
-#define PR_VERSION   1<<0
-#define PR_INFO      1<<1
-#define PR_TOTALS    1<<2
-#define PR_CONNECTED 1<<3
-#define PR_INPUTQ    1<<4
-#define PR_DISCQ     1<<5
-#define PR_TEST      1<<6
-#define PR_STOP      1<<7
-
+extern struct proc_dir_entry proc_scsi_in2000;
 
 int in2000_detect(Scsi_Host_Template *);
 int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int in2000_abort(Scsi_Cmnd *);
 void in2000_setup(char *, int *);
 int in2000_proc_info(char *, char **, off_t, int, int, int);
-struct proc_dir_entry proc_scsi_in2000;
 int in2000_biosparam(struct scsi_disk *, kdev_t, int *);
 int in2000_reset(Scsi_Cmnd *, unsigned int);
 
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.1.30/linux/drivers/scsi/scsi.c	Mon Mar 17 14:54:30 1997
+++ linux/drivers/scsi/scsi.c	Mon Mar 31 13:27:27 1997
@@ -277,11 +277,14 @@
 {"INSITE","Floptical   F*8I","*", BLIST_KEY},
 {"INSITE","I325VM","*", BLIST_KEY},
 {"NRC","MBR-7","*", BLIST_FORCELUN | BLIST_SINGLELUN},
+{"NRC","MBR-7.4","*", BLIST_FORCELUN | BLIST_SINGLELUN},
+{"NAKAMICH","MJ-4.8S","*", BLIST_FORCELUN | BLIST_SINGLELUN},
 {"PIONEER","CD-ROM DRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
 {"PIONEER","CD-ROM DRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
 {"EMULEX","MD21/S2     ESDI","*", BLIST_SINGLELUN},
 {"CANON","IPUBJD","*", BLIST_SPARSELUN},
 {"MATSHITA","PD","*", BLIST_FORCELUN | BLIST_SINGLELUN},
+{"YAMAHA","CDR100","1.00", BLIST_NOLUN},	/* Locks up if polled for lun != 0 */
 {"YAMAHA","CDR102","1.00", BLIST_NOLUN},	/* Locks up if polled for lun != 0 */
 /*
  * Must be at end of list...
@@ -1028,7 +1031,7 @@
 
     host = device->host;
 
-    if (intr_count && SCSI_BLOCK(host)) return NULL;
+    if (in_interrupt() && SCSI_BLOCK(host)) return NULL;
 
     while (1==1){
 	if (!device->single_lun) {
@@ -1243,12 +1246,12 @@
 	 * interrupt.
 	 */
 
-	if(!intr_count && SCpnt->host->irq)
+	if(!in_interrupt() && SCpnt->host->irq)
 	    disable_irq(SCpnt->host->irq);
 
 	host->hostt->queuecommand (SCpnt, scsi_done);
 
-	if(!intr_count && SCpnt->host->irq)
+	if(!in_interrupt() && SCpnt->host->irq)
 	    enable_irq(SCpnt->host->irq);
     }
     else
@@ -2897,7 +2900,9 @@
 	    if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM)
 	        new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth;
 	}
-	else if (SDpnt->type == TYPE_SCANNER || SDpnt->type == TYPE_PROCESSOR) {
+	else if (SDpnt->type == TYPE_SCANNER ||
+		 SDpnt->type == TYPE_PROCESSOR ||
+		 SDpnt->type == TYPE_MEDIUM_CHANGER) {
 	    new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth;
 	}
 	else {
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v2.1.30/linux/drivers/scsi/scsi.h	Mon Dec 30 03:01:10 1996
+++ linux/drivers/scsi/scsi.h	Wed Apr  2 17:53:20 1997
@@ -550,7 +550,7 @@
 	for(;;) {			            \
 	current->state = TASK_UNINTERRUPTIBLE;	    \
 	if (CONDITION) {		            \
-            if (intr_count)	                    \
+            if (in_interrupt())	                    \
 	        panic("scsi: trying to call schedule() in interrupt" \
 		      ", file %s, line %d.\n", __FILE__, __LINE__);  \
 	    schedule();			\
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.1.30/linux/drivers/scsi/sd.c	Tue Mar  4 10:25:24 1997
+++ linux/drivers/scsi/sd.c	Wed Apr  2 17:43:21 1997
@@ -147,7 +147,7 @@
     return 0;
 }
 
-static void sd_release(struct inode * inode, struct file * file)
+static int sd_release(struct inode * inode, struct file * file)
 {
     int target;
     fsync_dev(inode->i_rdev);
@@ -165,6 +165,7 @@
         __MOD_DEC_USE_COUNT(rscsi_disks[target].device->host->hostt->module);
     if(sd_template.module)
         __MOD_DEC_USE_COUNT(sd_template.module);
+    return 0;
 }
 
 static void sd_geninit(struct gendisk *);
@@ -491,7 +492,7 @@
 	     * from user space, since we do not want to
 	     * sleep from an interrupt.
 	     */
-	    if( SDev->removable && !intr_count )
+	    if( SDev->removable && !in_interrupt() )
 	    {
                 scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
 		/* scsi_ioctl may allow CURRENT to change, so start over. */
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v2.1.30/linux/drivers/scsi/sg.c	Sun Jan 26 02:07:21 1997
+++ linux/drivers/scsi/sg.c	Wed Apr  2 17:43:21 1997
@@ -149,7 +149,7 @@
     return 0;
 }
 
-static void sg_close(struct inode * inode, struct file * filp)
+static int sg_close(struct inode * inode, struct file * filp)
 {
     int dev=MINOR(inode->i_rdev);
     scsi_generics[dev].users--;
@@ -159,6 +159,7 @@
         __MOD_DEC_USE_COUNT(sg_template.module);
     scsi_generics[dev].exclude=0;
     wake_up(&scsi_generics[dev].generic_wait);
+    return 0;
 }
 
 static char *sg_malloc(int size)
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.1.30/linux/drivers/scsi/sr.c	Sun Jan 26 02:07:21 1997
+++ linux/drivers/scsi/sr.c	Mon Mar 31 10:27:58 1997
@@ -423,7 +423,7 @@
  	     * from user space, since we do not want to
  	     * sleep from an interrupt.
  	     */
- 	    if( SDev->removable && !intr_count )
+ 	    if( SDev->removable && !in_interrupt() )
  	    {
 		scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
  	    }
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v2.1.30/linux/drivers/scsi/st.c	Tue Mar  4 10:25:24 1997
+++ linux/drivers/scsi/st.c	Wed Apr  2 17:43:22 1997
@@ -804,7 +804,7 @@
 
 
 /* Close the device*/
-	static void
+	static int
 scsi_tape_close(struct inode * inode, struct file * filp)
 {
     int result;
@@ -923,7 +923,7 @@
     if(st_template.module)
 	__MOD_DEC_USE_COUNT(st_template.module);
 
-    return;
+    return 0;
 }
 
 
@@ -2008,7 +2008,7 @@
 		      arg - MT_ST_HPLOADER_OFFSET);
 	   }
 #endif
-	   cmd[3] = arg; /* MediaID field of C1553A */
+	   cmd[3] = arg - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
        }
 #if ST_NOWAIT
        cmd[1] = 1;  /* Don't wait for completion */
@@ -2975,6 +2975,7 @@
 }
 
 
+#ifndef MODULE
 /* Set the boot options. Syntax: st=xxx,yyy
    where xxx is buffer size in 1024 byte blocks and yyy is write threshold
    in 1024 byte blocks. */
@@ -2991,6 +2992,7 @@
   if (ints[0] > 2 && ints[3] > 0)
     st_max_buffers = ints[3];
 }
+#endif
 
 
 static struct file_operations st_fops = {
diff -u --recursive --new-file v2.1.30/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v2.1.30/linux/drivers/sound/soundcard.c	Tue Mar  4 10:25:25 1997
+++ linux/drivers/sound/soundcard.c	Wed Apr  2 17:43:22 1997
@@ -127,7 +127,7 @@
   return retval;
 }
 
-static void
+static int
 sound_release (struct inode *inode, struct file *file)
 {
   int             dev;
@@ -140,6 +140,7 @@
 #ifdef MODULE
   MOD_DEC_USE_COUNT;
 #endif
+  return 0;
 }
 
 static int
diff -u --recursive --new-file v2.1.30/linux/fs/Config.in linux/fs/Config.in
--- v2.1.30/linux/fs/Config.in	Tue Jan 14 02:59:10 1997
+++ linux/fs/Config.in	Fri Mar 28 14:13:29 1997
@@ -37,6 +37,7 @@
 tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
 tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS
 tristate 'ROM filesystem support' CONFIG_ROMFS_FS
+tristate 'Kernel automounter support (experimental)' CONFIG_AUTOFS_FS
 if [ "$CONFIG_AFFS_FS" != "n" ]; then
   define_bool CONFIG_AMIGA_PARTITION y
 fi
diff -u --recursive --new-file v2.1.30/linux/fs/Makefile linux/fs/Makefile
--- v2.1.30/linux/fs/Makefile	Tue Jan 14 03:00:18 1997
+++ linux/fs/Makefile	Fri Mar 28 15:07:55 1997
@@ -17,7 +17,7 @@
 
 MOD_LIST_NAME := FS_MODULES
 ALL_SUB_DIRS = minix ext2 fat msdos vfat proc isofs nfs umsdos \
-		hpfs sysv smbfs ncpfs ufs affs romfs
+		hpfs sysv smbfs ncpfs ufs affs romfs autofs
 
 ifeq ($(CONFIG_QUOTA),y)
 O_OBJS += dquot.o
@@ -150,6 +150,14 @@
 else
   ifeq ($(CONFIG_ROMFS_FS),m)
   MOD_SUB_DIRS += romfs
+  endif
+endif
+
+ifeq ($(CONFIG_AUTOFS_FS),y)
+SUB_DIRS += autofs
+else
+  ifeq ($(CONFIG_AUTOFS_FS),m)
+  MOD_SUB_DIRS += autofs
   endif
 endif
 
diff -u --recursive --new-file v2.1.30/linux/fs/affs/file.c linux/fs/affs/file.c
--- v2.1.30/linux/fs/affs/file.c	Sun Jan 26 02:07:24 1997
+++ linux/fs/affs/file.c	Wed Apr  2 17:43:22 1997
@@ -42,7 +42,7 @@
 static long affs_file_write_ofs(struct inode *inode, struct file *filp, const char *buf,
 				unsigned long count);
 static int affs_open_file(struct inode *inode, struct file *filp);
-static void affs_release_file(struct inode *inode, struct file *filp);
+static int affs_release_file(struct inode *inode, struct file *filp);
 
 static struct file_operations affs_file_operations = {
 	NULL,			/* lseek - default */
@@ -883,7 +883,7 @@
 	return error;
 }
 
-static void
+static int
 affs_release_file(struct inode *inode, struct file *filp)
 {
 	struct affs_zone	*zone;
@@ -913,4 +913,5 @@
 		}
 	}
 	unlock_super(inode->i_sb);
+	return 0;
 }
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/Makefile linux/fs/autofs/Makefile
--- v2.1.30/linux/fs/autofs/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/Makefile	Fri Mar 28 14:12:45 1997
@@ -0,0 +1,16 @@
+#
+# Makefile for the linux autofs-filesystem routines.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+#
+
+O_TARGET := autofs.o
+O_OBJS   := dir.o dirhash.o init.o inode.o root.o symlink.o waitq.o
+
+M_OBJS   := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/dir.c linux/fs/autofs/dir.c
--- v2.1.30/linux/fs/autofs/dir.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/dir.c	Fri Mar 28 14:12:45 1997
@@ -0,0 +1,91 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/dir.c
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/modversions.h>
+#include <linux/auto_fs.h>
+
+static int autofs_dir_readdir(struct inode *inode, struct file *filp,
+			       void *dirent, filldir_t filldir)
+{
+	if (!inode || !S_ISDIR(inode->i_mode))
+		return -ENOTDIR;
+
+	switch((unsigned long) filp->f_pos)
+	{
+	case 0:
+		if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0)
+			return 0;
+		filp->f_pos++;
+		/* fall through */
+	case 1:
+		if (filldir(dirent, "..", 2, 1, AUTOFS_ROOT_INO) < 0)
+			return 0;
+		filp->f_pos++;
+		/* fall through */
+	}
+	return 1;
+}
+
+static int autofs_dir_lookup(struct inode *dir, const char *name, int len,
+			      struct inode **result)
+{
+	*result = dir;
+	if (!len)
+		return 0;
+	if (name[0] == '.') {
+		if (len == 1)
+			return 0;
+		if (name[1] == '.' && len == 2) {
+			/* Return the root directory */
+			*result = iget(dir->i_sb,AUTOFS_ROOT_INO);
+			iput(dir);
+			return 0;
+		}
+	}
+	*result = NULL;
+	iput(dir);
+	return -ENOENT;		/* No other entries */
+}
+
+static struct file_operations autofs_dir_operations = {
+	NULL,			/* lseek */
+	NULL,			/* read */
+	NULL,			/* write */
+	autofs_dir_readdir,	/* readdir */
+	NULL,			/* select */
+	NULL,			/* ioctl */
+	NULL,			/* mmap */
+	NULL,			/* open */
+	NULL,			/* release */
+	NULL			/* fsync */
+};
+
+struct inode_operations autofs_dir_inode_operations = {
+	&autofs_dir_operations,	/* file operations */
+	NULL,			/* create */
+	autofs_dir_lookup,	/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	NULL,			/* read_page */
+	NULL,			/* writepage */
+	NULL,			/* bmap */
+	NULL,			/* truncate */
+	NULL			/* permission */
+};
+
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/dirhash.c linux/fs/autofs/dirhash.c
--- v2.1.30/linux/fs/autofs/dirhash.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/dirhash.c	Fri Mar 28 14:12:45 1997
@@ -0,0 +1,130 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/dirhash.c
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/modversions.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/auto_fs.h>
+
+/* Adapted from the Dragon Book, page 436 */
+/* This particular hashing algorithm requires autofs_hash_t == u32 */
+autofs_hash_t autofs_hash(const char *name, int len)
+{
+	autofs_hash_t h = 0;
+	while ( len-- ) {
+		h = (h << 4) + (unsigned char) (*name++);
+		h ^= ((h & 0xf0000000) >> 24);
+	}
+	return h;
+}
+
+void autofs_initialize_hash(struct autofs_dirhash *dh) {
+	memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *));
+}
+
+struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, autofs_hash_t hash, const char *name, int len)
+{
+	struct autofs_dir_ent *dhn;
+
+	DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", hash));
+	autofs_say(name,len);
+
+	for ( dhn = dh->h[hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) {
+		if ( hash == dhn->hash &&
+		     len == dhn->len &&
+		     !memcmp(name, dhn->name, len) )
+			break;
+	}
+
+	return dhn;
+}
+
+void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
+{
+	struct autofs_dir_ent **dhnp;
+
+	DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash));
+	autofs_say(ent->name,ent->len);
+
+	dhnp = &dh->h[ent->hash % AUTOFS_HASH_SIZE];
+	ent->next = *dhnp;
+	ent->back = dhnp;
+	*dhnp = ent;
+}
+
+void autofs_hash_delete(struct autofs_dir_ent *ent)
+{
+	*(ent->back) = ent->next;
+	kfree(ent->name);
+	kfree(ent);
+}
+
+/*
+ * Used by readdir().  We must validate "ptr", so we can't simply make it
+ * a pointer.  Values below 0xffff are reserved; calling with any value
+ * <= 0x10000 will return the first entry found.
+ */
+struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh, off_t *ptr)
+{
+	int bucket, ecount, i;
+	struct autofs_dir_ent *ent;
+
+	bucket = (*ptr >> 16) - 1;
+	ecount = *ptr & 0xffff;
+
+	if ( bucket < 0 ) {
+		bucket = ecount = 0;
+	} 
+
+	DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
+
+	ent = NULL;
+
+	while  ( bucket < AUTOFS_HASH_SIZE ) {
+		ent = dh->h[bucket];
+		for ( i = ecount ; ent && i ; i-- )
+			ent = ent->next;
+
+		if (ent) {
+			ecount++; /* Point to *next* entry */
+			break;
+		}
+
+		bucket++; ecount = 0;
+	}
+
+#ifdef DEBUG
+	if ( !ent )
+		printk("autofs_hash_enum: nothing found\n");
+	else {
+		printk("autofs_hash_enum: found hash %08x, name", ent->hash);
+		autofs_say(ent->name,ent->len);
+	}
+#endif
+
+	*ptr = ((bucket+1) << 16) + ecount;
+	return ent;
+}
+
+void autofs_hash_nuke(struct autofs_dirhash *dh)
+{
+	int i;
+	struct autofs_dir_ent *ent, *nent;
+
+	for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
+		for ( ent = dh->h[i] ; ent ; ent = nent ) {
+			nent = ent->next;
+			kfree(ent->name);
+			kfree(ent);
+		}
+	}
+}
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/init.c linux/fs/autofs/init.c
--- v2.1.30/linux/fs/autofs/init.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/init.c	Fri Mar 28 15:12:16 1997
@@ -0,0 +1,50 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/init.c
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/modversions.h>
+#include <linux/module.h>
+#include <linux/auto_fs.h>
+
+struct file_system_type autofs_fs_type = {
+	autofs_read_super, "autofs", 0, NULL
+};
+
+int init_autofs_fs(void)
+{
+	return register_filesystem(&autofs_fs_type);
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+	int status;
+	
+	if ((status = init_autofs_fs()) == 0)
+		register_symtab(0);
+	return status;
+}
+
+void cleanup_module(void)
+{
+	unregister_filesystem(&autofs_fs_type);
+}
+#endif
+
+#ifdef DEBUG
+void autofs_say(const char *name, int len)
+{
+	printk("(%d: ", len);
+	while ( len-- )
+		printk("%c", *name++);
+	printk(")\n");
+}
+#endif
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/inode.c linux/fs/autofs/inode.c
--- v2.1.30/linux/fs/autofs/inode.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/inode.c	Fri Mar 28 14:12:45 1997
@@ -0,0 +1,273 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/inode.c
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/modversions.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/file.h>
+#include <linux/locks.h>
+#include <asm/bitops.h>
+#include <linux/auto_fs.h>
+#define __NO_VERSION__
+#include <linux/module.h>
+
+static void autofs_put_inode(struct inode *inode)
+{
+        if (inode->i_nlink)
+                return;
+        inode->i_size = 0;
+}
+
+static void autofs_put_super(struct super_block *sb)
+{
+	struct autofs_sb_info *sbi;
+	unsigned int n;
+
+        lock_super(sb);
+	sbi = (struct autofs_sb_info *) sb->u.generic_sbp;
+	autofs_hash_nuke(&sbi->dirhash);
+	for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) {
+		if ( test_bit(n, sbi->symlink_bitmap) )
+			kfree(sbi->symlink[n].data);
+	}
+	fput(sbi->pipe, sbi->pipe->f_inode);
+
+        sb->s_dev = 0;
+	kfree(sb->u.generic_sbp);
+        unlock_super(sb);
+
+	DPRINTK(("autofs: shutting down\n"));
+	
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+}
+
+static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static void autofs_read_inode(struct inode *inode);
+static void autofs_write_inode(struct inode *inode);
+
+static struct super_operations autofs_sops = {
+        autofs_read_inode,
+        NULL,
+        autofs_write_inode,
+        autofs_put_inode,
+        autofs_put_super,
+        NULL,
+        autofs_statfs,
+        NULL
+};
+
+static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
+{
+        char *this_char, *value;
+        
+        *uid = current->uid;
+        *gid = current->gid;
+	*pgrp = current->pgrp;
+
+	*minproto = *maxproto = AUTOFS_PROTO_VERSION;
+
+        *pipefd = -1;
+
+        if ( !options ) return 1;
+        for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
+                if ((value = strchr(this_char,'=')) != NULL)
+                        *value++ = 0;
+                if (!strcmp(this_char,"fd")) {
+                        if (!value || !*value)
+                                return 1;
+                        *pipefd = simple_strtoul(value,&value,0);
+                        if (*value)
+                                return 1;
+                }
+                else if (!strcmp(this_char,"uid")) {
+                        if (!value || !*value)
+                                return 1;
+                        *uid = simple_strtoul(value,&value,0);
+                        if (*value)
+                                return 1;
+                }
+                else if (!strcmp(this_char,"gid")) {
+                        if (!value || !*value)
+                                return 1;
+                        *gid = simple_strtoul(value,&value,0);
+                        if (*value)
+                                return 1;
+                }
+                else if (!strcmp(this_char,"pgrp")) {
+                        if (!value || !*value)
+                                return 1;
+                        *pgrp = simple_strtoul(value,&value,0);
+                        if (*value)
+                                return 1;
+                }
+                else if (!strcmp(this_char,"minproto")) {
+                        if (!value || !*value)
+                                return 1;
+                        *minproto = simple_strtoul(value,&value,0);
+                        if (*value)
+                                return 1;
+                }
+                else if (!strcmp(this_char,"maxproto")) {
+                        if (!value || !*value)
+                                return 1;
+                        *maxproto = simple_strtoul(value,&value,0);
+                        if (*value)
+                                return 1;
+                }
+                else break;
+        }
+        return (*pipefd < 0);
+}
+
+struct super_block *autofs_read_super(struct super_block *s, void *data,
+                                      int silent)
+{
+        int pipefd;
+	struct autofs_sb_info *sbi;
+	int minproto, maxproto;
+
+	MOD_INC_USE_COUNT;
+
+        lock_super(s);
+        sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL);
+	if ( !sbi ) {
+		s->s_dev = 0;
+		return NULL;
+	}
+	DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
+
+	s->u.generic_sbp = sbi;
+	sbi->catatonic = 0;
+	sbi->oz_pgrp = current->pgrp;
+	autofs_initialize_hash(&sbi->dirhash);
+	sbi->queues = NULL;
+	memset(sbi->symlink_bitmap, 0, sizeof(u32)*AUTOFS_SYMLINK_BITMAP_LEN);
+	sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
+        s->s_blocksize = 1024;
+        s->s_blocksize_bits = 10;
+        s->s_magic = AUTOFS_SUPER_MAGIC;
+        s->s_op = &autofs_sops;
+        unlock_super(s);
+        if (!(s->s_mounted = iget(s, AUTOFS_ROOT_INO))) {
+                s->s_dev = 0;
+		kfree(sbi);
+                printk("autofs: get root inode failed\n");
+		MOD_DEC_USE_COUNT;
+                return NULL;
+        }
+
+        if ( parse_options(data,&pipefd,&s->s_mounted->i_uid,&s->s_mounted->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
+		iput(s->s_mounted);
+                s->s_dev = 0;
+		kfree(sbi);
+                printk("autofs: called with bogus options\n");
+		MOD_DEC_USE_COUNT;
+                return NULL;
+        }
+
+	if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) {
+		iput(s->s_mounted);
+		s->s_dev = 0;
+		kfree(sbi);
+		printk("autofs: kernel does not match daemon version\n");
+		MOD_DEC_USE_COUNT;
+		return NULL;
+	}
+
+	DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
+	sbi->pipe = fget(pipefd);
+	if ( !sbi->pipe || !sbi->pipe->f_op || !sbi->pipe->f_op->write ) {
+		if ( sbi->pipe ) {
+			fput(sbi->pipe, sbi->pipe->f_inode);
+			printk("autofs: pipe file descriptor does not contain proper ops\n");
+		} else {
+			printk("autofs: could not open pipe file descriptor\n");
+		}
+		iput(s->s_mounted);
+		s->s_dev = 0;
+		kfree(sbi);
+		MOD_DEC_USE_COUNT;
+		return NULL;
+	}
+        return s;
+}
+
+static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+{
+        struct statfs tmp;
+
+        tmp.f_type = AUTOFS_SUPER_MAGIC;
+        tmp.f_bsize = PAGE_SIZE/sizeof(long);
+        tmp.f_blocks = 0;
+        tmp.f_bfree = 0;
+        tmp.f_bavail = 0;
+        tmp.f_files = 0;
+        tmp.f_ffree = 0;
+        tmp.f_namelen = NAME_MAX;
+        copy_to_user(buf, &tmp, bufsiz);
+}
+
+static void autofs_read_inode(struct inode *inode)
+{
+        ino_t ino = inode->i_ino;
+	unsigned int n;
+        struct autofs_sb_info *sbi =
+		(struct autofs_sb_info *) inode->i_sb->u.generic_sbp;
+
+        inode->i_op = NULL;
+        inode->i_mode = 0;
+        inode->i_nlink = 2;
+        inode->i_size = 0;
+        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+        inode->i_blocks = 0;
+        inode->i_blksize = 1024;
+
+        if ( ino == AUTOFS_ROOT_INO ) {
+                inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
+                inode->i_op = &autofs_root_inode_operations;
+		inode->i_uid = inode->i_gid = 0; /* Changed in read_super */
+                return;
+        } 
+	
+        inode->i_uid = inode->i_sb->s_mounted->i_uid;
+        inode->i_gid = inode->i_sb->s_mounted->i_gid;
+        
+	if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) {
+		/* Symlink inode - should be in symlink list */
+		struct autofs_symlink *sl;
+
+		n = ino - AUTOFS_FIRST_SYMLINK;
+		if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
+			printk("autofs: Looking for bad symlink inode 0x%08x\n", (unsigned int) ino);
+			return;
+		}
+		
+		inode->i_op = &autofs_symlink_inode_operations;
+		sl = &sbi->symlink[n];
+		inode->u.generic_ip = sl;
+		inode->i_mode = S_IFLNK | S_IRWXUGO;
+		inode->i_mtime = inode->i_ctime = sl->mtime;
+		inode->i_size = sl->len;
+		inode->i_nlink = 1;
+	} else {
+		/* All non-root directory inodes look the same */
+		inode->i_op = &autofs_dir_inode_operations;
+		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+	}
+}
+
+static void autofs_write_inode(struct inode *inode)
+{
+        inode->i_dirt = 0;
+}
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.1.30/linux/fs/autofs/root.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/root.c	Fri Mar 28 14:12:45 1997
@@ -0,0 +1,363 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/root.c
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/modversions.h>
+#include <linux/errno.h>
+#include <linux/stat.h>
+#include <linux/malloc.h>
+#include <linux/ioctl.h>
+#include <linux/auto_fs.h>
+
+static int autofs_root_readdir(struct inode *,struct file *,void *,filldir_t);
+static int autofs_root_lookup(struct inode *,const char *,int,struct inode **);
+static int autofs_root_symlink(struct inode *,const char *,int,const char *);
+static int autofs_root_unlink(struct inode *,const char *,int);
+static int autofs_root_rmdir(struct inode *,const char *,int);
+static int autofs_root_mkdir(struct inode *,const char *,int,int);
+static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
+
+static struct file_operations autofs_root_operations = {
+        NULL,                   /* lseek */
+        NULL,                   /* read */
+        NULL,                   /* write */
+        autofs_root_readdir,    /* readdir */
+        NULL,                   /* select */
+        autofs_root_ioctl,	/* ioctl */
+        NULL,                   /* mmap */
+        NULL,                   /* open */
+        NULL,                   /* release */
+        NULL                    /* fsync */
+};
+
+struct inode_operations autofs_root_inode_operations = {
+        &autofs_root_operations, /* file operations */
+        NULL,                   /* create */
+        autofs_root_lookup,     /* lookup */
+        NULL,                   /* link */
+        autofs_root_unlink,     /* unlink */
+        autofs_root_symlink,    /* symlink */
+        autofs_root_mkdir,      /* mkdir */
+        autofs_root_rmdir,      /* rmdir */
+        NULL,                   /* mknod */
+        NULL,                   /* rename */
+        NULL,                   /* readlink */
+        NULL,                   /* follow_link */
+        NULL,                   /* readpage */
+        NULL,                   /* writepage */
+        NULL,                   /* bmap */
+        NULL,                   /* truncate */
+        NULL                    /* permission */
+};
+
+static int autofs_root_readdir(struct inode *inode, struct file *filp,
+			       void *dirent, filldir_t filldir)
+{
+	struct autofs_dir_ent *ent;
+	struct autofs_dirhash *dirhash;
+	off_t onr, nr;
+
+	if (!inode || !S_ISDIR(inode->i_mode))
+		return -ENOTDIR;
+
+	dirhash = &((struct autofs_sb_info *)inode->i_sb->u.generic_sbp)->dirhash;
+	nr = filp->f_pos;
+
+	switch(nr)
+	{
+	case 0:
+		if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
+			return 0;
+		filp->f_pos = ++nr;
+		/* fall through */
+	case 1:
+		if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
+			return 0;
+		filp->f_pos = ++nr;
+		/* fall through */
+	default:
+		while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr) ) {
+			if (filldir(dirent,ent->name,ent->len,onr,ent->ino) < 0)
+				return 0;
+			filp->f_pos = nr;
+		}
+		break;
+	}
+
+	return 0;
+}
+
+static int autofs_root_lookup(struct inode *dir, const char *name, int len,
+			      struct inode **result)
+{
+	struct autofs_sb_info *sbi;
+	struct autofs_dir_ent *ent;
+	struct inode *res;
+	autofs_hash_t hash;
+	int status, oz_mode;
+
+	DPRINTK(("autofs_root_lookup: name = "));
+	autofs_say(name,len);
+
+	*result = NULL;
+	if (!dir)
+		return -ENOENT;
+	if (!S_ISDIR(dir->i_mode)) {
+		iput(dir);
+		return -ENOTDIR;
+	}
+
+	/* Handle special cases: . and ..; since this is a root directory,
+	   they both point to the inode itself */
+	*result = dir;
+	if (!len)
+		return 0;
+	if (name[0] == '.') {
+		if (len == 1)
+			return 0;
+		if (name[1] == '.' && len == 2)
+			return 0;
+	}
+
+	*result = res = NULL;
+	sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
+
+	hash = autofs_hash(name,len);
+
+	oz_mode = autofs_oz_mode(sbi);
+	DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", current->pid, current->pgrp, sbi->catatonic, oz_mode));
+
+	do {
+		while ( !(ent = autofs_hash_lookup(&sbi->dirhash,hash,name,len)) ) {
+			DPRINTK(("lookup failed, pid = %u, pgrp = %u\n", current->pid, current->pgrp));
+			
+			if ( oz_mode ) {
+				iput(dir);
+				return -ENOENT;
+			} else {
+				status = autofs_wait(sbi,hash,name,len);
+				DPRINTK(("autofs_wait returned %d\n", status));
+				if ( status ) {
+					iput(dir);
+					return status;
+				}
+			}
+		}
+
+		DPRINTK(("lookup successful, inode = %08x\n", (unsigned int)ent->ino));
+
+		if (!(res = iget(dir->i_sb,ent->ino))) {
+			printk("autofs: iget returned null!\n");
+			iput(dir);
+			return -EACCES;
+		}
+		
+		if ( !oz_mode && S_ISDIR(res->i_mode) && res->i_sb == dir->i_sb ) {
+			/* Not a mount point yet, call 1-800-DAEMON */
+			DPRINTK(("autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u\n", res->i_ino, current->pid, current->pgrp));
+			iput(res);
+			res = NULL;
+			status = autofs_wait(sbi,hash,name,len);
+			if ( status ) {
+				iput(dir);
+				return status;
+			}
+		}
+	} while(!res);
+		
+	*result = res;
+	iput(dir);
+	return 0;
+}
+
+static int autofs_root_symlink(struct inode *dir, const char *name, int len, const char *symname)
+{
+	struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
+	struct autofs_dirhash *dh = &sbi->dirhash;
+	autofs_hash_t hash = autofs_hash(name,len);
+	struct autofs_dir_ent *ent;
+	unsigned int n;
+	int slsize;
+	struct autofs_symlink *sl;
+
+	DPRINTK(("autofs_root_symlink: %s <- ", symname));
+	autofs_say(name,len);
+
+	iput(dir);
+	
+	if ( !autofs_oz_mode(sbi) )
+		return -EPERM;
+
+	if ( autofs_hash_lookup(dh,hash,name,len) )
+		return -EEXIST;
+
+	n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS);
+	if ( n >= AUTOFS_MAX_SYMLINKS )
+		return -ENOSPC;
+
+	set_bit(n,sbi->symlink_bitmap);
+	sl = &sbi->symlink[n];
+	sl->len = strlen(symname);
+	sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
+	if ( !sl->data ) {
+		clear_bit(n,sbi->symlink_bitmap);
+		return -ENOSPC;
+	}
+	ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
+	if ( !ent ) {
+		kfree(sl->data);
+		clear_bit(n,sbi->symlink_bitmap);
+		return -ENOSPC;
+	}
+	ent->name = kmalloc(len, GFP_KERNEL);
+	if ( !ent->name ) {
+		kfree(sl->data);
+		kfree(ent);
+		clear_bit(n,sbi->symlink_bitmap);
+		return -ENOSPC;
+	}
+	memcpy(sl->data,symname,slsize);
+	sl->mtime = CURRENT_TIME;
+
+	ent->ino = AUTOFS_FIRST_SYMLINK + n;
+	ent->hash = hash;
+	memcpy(ent->name,name,ent->len = len);
+	ent->expiry = END_OF_TIME;
+
+	autofs_hash_insert(dh,ent);
+
+	return 0;
+}
+
+static int autofs_root_unlink(struct inode *dir, const char *name, int len)
+{
+	struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
+	struct autofs_dirhash *dh = &sbi->dirhash;
+	autofs_hash_t hash = autofs_hash(name,len);
+	struct autofs_dir_ent *ent;
+	unsigned int n;
+
+	if ( !autofs_oz_mode(sbi) )
+		return -EPERM;
+
+	ent = autofs_hash_lookup(dh,hash,name,len);
+	if ( !ent )
+		return -ENOENT;
+	n = ent->ino - AUTOFS_FIRST_SYMLINK;
+	if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap) )
+		return -EINVAL;	/* Not a symlink inode, can't unlink */
+	autofs_hash_delete(ent);
+	clear_bit(n,sbi->symlink_bitmap);
+	kfree(sbi->symlink[n].data);
+	
+	return 0;
+}
+
+static int autofs_root_rmdir(struct inode *dir, const char *name, int len)
+{
+	struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
+	struct autofs_dirhash *dh = &sbi->dirhash;
+	autofs_hash_t hash = autofs_hash(name,len);
+	struct autofs_dir_ent *ent;
+
+	if ( !autofs_oz_mode(sbi) ) {
+		iput(dir);
+		return -EPERM;
+	}
+	ent = autofs_hash_lookup(dh,hash,name,len);
+	if ( !ent ) {
+		iput(dir);
+		return -ENOENT;
+	}
+	if ( (unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO ) {
+		iput(dir);
+		return -ENOTDIR; /* Not a directory */
+	}
+	autofs_hash_delete(ent);
+	dir->i_nlink--;
+	iput(dir);
+
+	return 0;
+}
+
+static int autofs_root_mkdir(struct inode *dir, const char *name, int len, int mode)
+{
+	struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
+	struct autofs_dirhash *dh = &sbi->dirhash;
+	autofs_hash_t hash = autofs_hash(name,len);
+	struct autofs_dir_ent *ent;
+
+	if ( !autofs_oz_mode(sbi) ) {
+		iput(dir);
+		return -EPERM;
+	}
+	ent = autofs_hash_lookup(dh,hash,name,len);
+	if ( ent ) {
+		iput(dir);
+		return -EEXIST;
+	}
+	if ( sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO ) {
+		printk("autofs: Out of inode numbers -- what the heck did you do??\n");
+		iput(dir);
+		return -ENOSPC;
+	}
+	ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
+	if ( !ent ) {
+		iput(dir);
+		return -ENOSPC;
+	}
+	ent->name = kmalloc(len, GFP_KERNEL);
+	if ( !ent->name ) {
+		kfree(ent);
+		iput(dir);
+		return -ENOSPC;
+	}
+	ent->hash = hash;
+	memcpy(ent->name, name, ent->len = len);
+	ent->ino = sbi->next_dir_ino++;
+	ent->expiry = END_OF_TIME;
+	autofs_hash_insert(dh,ent);
+	dir->i_nlink++;
+	iput(dir);
+
+	return 0;
+}
+
+/*
+ * ioctl()'s on the root directory is the chief method for the daemon to
+ * generate kernel reactions
+ */
+static int autofs_root_ioctl(struct inode *inode, struct file *filp,
+			     unsigned int cmd, unsigned long arg)
+{
+	struct autofs_sb_info *sbi = (struct autofs_sb_info *)inode->i_sb->u.generic_sbp;
+
+	DPRINTK(("autofs_ioctl: cmd = %04x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,current->pgrp));
+
+	switch(cmd) {
+	case AUTOFS_IOC_READY:	/* Wait queue: go ahead and retry */
+		if ( !autofs_oz_mode(sbi) && !fsuser() )
+			return -EPERM;
+		return autofs_wait_release(sbi,arg,0);
+	case AUTOFS_IOC_FAIL:	/* Wait queue: fail with ENOENT */
+		/* Optional: add to failure cache */
+		if ( !autofs_oz_mode(sbi) && !fsuser() )
+			return -EPERM;
+		return autofs_wait_release(sbi,arg,-ENOENT);
+	case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */
+		if ( !autofs_oz_mode(sbi) && !fsuser() )
+			return -EPERM;
+		autofs_catatonic_mode(sbi);
+		return 0;
+	default:
+		return -ENOTTY;	/* Should this be ENOSYS? */
+	}
+}
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/symlink.c linux/fs/autofs/symlink.c
--- v2.1.30/linux/fs/autofs/symlink.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/symlink.c	Fri Mar 28 14:12:45 1997
@@ -0,0 +1,86 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/symlink.c
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/modversions.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/auto_fs.h>
+
+static int autofs_follow_link(struct inode *dir, struct inode *inode,
+			      int flag, int mode, struct inode **res_inode)
+{
+	int error;
+	char *link;
+
+	*res_inode = NULL;
+	if (!dir) {
+		dir = current->fs->root;
+		dir->i_count++;
+	}
+	if (!inode) {
+		iput(dir);
+		return -ENOENT;
+	}
+	if (!S_ISLNK(inode->i_mode)) {
+		iput(dir);
+		*res_inode = inode;
+		return 0;
+	}
+	if (current->link_count > 5) {
+		iput(dir);
+		iput(inode);
+		return -ELOOP;
+	}
+	link = ((struct autofs_symlink *)inode->u.generic_ip)->data;
+	current->link_count++;
+	error = open_namei(link,flag,mode,res_inode,dir);
+	current->link_count--;
+	iput(inode);
+	return error;
+}
+
+static int autofs_readlink(struct inode *inode, char *buffer, int buflen)
+{
+	struct autofs_symlink *sl;
+	int len;
+
+	if (!S_ISLNK(inode->i_mode)) {
+		iput(inode);
+		return -EINVAL;
+	}
+	sl = (struct autofs_symlink *)inode->u.generic_ip;
+	len = sl->len;
+	if (len > buflen) len = buflen;
+	copy_to_user(buffer,sl->data,len);
+	iput(inode);
+	return len;
+}
+
+struct inode_operations autofs_symlink_inode_operations = {
+	NULL,			/* file operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	autofs_readlink,	/* readlink */
+	autofs_follow_link,	/* follow_link */
+	NULL,			/* readpage */
+	NULL,			/* writepage */
+	NULL,			/* bmap */
+	NULL,			/* truncate */
+	NULL			/* permission */
+};
diff -u --recursive --new-file v2.1.30/linux/fs/autofs/waitq.c linux/fs/autofs/waitq.c
--- v2.1.30/linux/fs/autofs/waitq.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/autofs/waitq.c	Fri Mar 28 14:12:45 1997
@@ -0,0 +1,152 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/waitq.c
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/modversions.h>
+#include <linux/malloc.h>
+#include <linux/auto_fs.h>
+
+/* We make this a static variable rather than a part of the superblock; it
+   is better if we don't reassign numbers easily even across filesystems */
+static int autofs_next_wait_queue = 1;
+
+void autofs_catatonic_mode(struct autofs_sb_info *sbi)
+{
+	struct autofs_wait_queue *wq, *nwq;
+
+	DPRINTK(("autofs: entering catatonic mode\n"));
+
+	sbi->catatonic = 1;
+	wq = sbi->queues;
+	sbi->queues = NULL;	/* Erase all wait queues */
+	while ( wq ) {
+		nwq = wq->next;
+		wq->status = -ENOENT; /* Magic is gone - report failure */
+		kfree(wq->name);
+		wq->name = NULL;
+		wake_up(&wq->queue);
+		wq = nwq;
+	}
+}
+
+static int autofs_write(struct file *file, const void *addr, int bytes)
+{
+	unsigned short fs;
+	const char *data = (const char *)addr;
+	int written;
+
+	/** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
+
+	/* Save pointer to user space and point back to kernel space */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
+	while ( bytes && (written = file->f_op->write(file->f_inode,file,data,bytes)) > 0 ) {
+		data += written;
+		bytes -= written;
+	}
+	set_fs(fs);
+
+	return (bytes > 0);
+}
+	
+static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq)
+{
+	struct autofs_packet_missing pkt;
+
+	DPRINTK(("autofs_wait: wait id = 0x%08lx, name = ", wq->wait_queue_token));
+	autofs_say(wq->name,wq->len);
+
+	pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
+	pkt.hdr.type = autofs_ptype_missing;
+	pkt.wait_queue_token = wq->wait_queue_token;
+	pkt.len = wq->len;
+        memcpy(pkt.name, wq->name, pkt.len);
+	pkt.name[pkt.len] = '\0';
+
+	if ( autofs_write(sbi->pipe,&pkt,sizeof(struct autofs_packet_missing)) )
+		autofs_catatonic_mode(sbi);
+}
+
+int autofs_wait(struct autofs_sb_info *sbi, autofs_hash_t hash, const char *name, int len)
+{
+	struct autofs_wait_queue *wq;
+	int status;
+
+	for ( wq = sbi->queues ; wq ; wq = wq->next ) {
+		if ( wq->hash == hash &&
+		     wq->len == len &&
+		     !memcmp(wq->name,name,len) )
+			break;
+	}
+	
+	if ( !wq ) {
+		/* Create a new wait queue */
+		wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
+		if ( !wq )
+			return -ENOMEM;
+
+		wq->name = kmalloc(len,GFP_KERNEL);
+		if ( !wq->name ) {
+			kfree(wq);
+			return -ENOMEM;
+		}
+		wq->wait_queue_token = autofs_next_wait_queue++;
+		init_waitqueue(&wq->queue);
+		wq->hash = hash;
+		wq->len = len;
+		memcpy(wq->name, name, len);
+		wq->next = sbi->queues;
+		sbi->queues = wq;
+
+		/* autofs_notify_daemon() may block */
+		wq->wait_ctr++;
+		autofs_notify_daemon(sbi,wq);
+	} else
+		wq->wait_ctr++;
+
+	if ( wq->name ) {
+		/* wq->name is NULL if and only if the lock is released */
+		interruptible_sleep_on(&wq->queue);
+	} else {
+		DPRINTK(("autofs_wait: skipped sleeping\n"));
+	}
+
+	status = (current->signal & ~current->blocked) ? -EINTR : wq->status;
+	if ( ! --wq->wait_ctr )	/* Are we the last process to need status? */
+		kfree(wq);
+
+	return status;
+}
+
+
+int autofs_wait_release(struct autofs_sb_info *sbi, unsigned long wait_queue_token, int status)
+{
+	struct autofs_wait_queue *wq, **wql;
+
+	for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) {
+		if ( wq->wait_queue_token == wait_queue_token )
+			break;
+	}
+	if ( !wq )
+		return -EINVAL;
+
+	*wql = wq->next;	/* Unlink from chain */
+	kfree(wq->name);
+	wq->name = NULL;	/* Do not wait on this queue */
+
+	wq->status = status;
+
+	wake_up(&wq->queue);
+
+	return 0;
+}
+
diff -u --recursive --new-file v2.1.30/linux/fs/devices.c linux/fs/devices.c
--- v2.1.30/linux/fs/devices.c	Sat Jan 25 13:46:13 1997
+++ linux/fs/devices.c	Wed Apr  2 17:43:22 1997
@@ -235,11 +235,12 @@
 	return ret;
 }	
 
-void blkdev_release(struct inode * inode)
+int blkdev_release(struct inode * inode)
 {
 	struct file_operations *fops = get_blkfops(MAJOR(inode->i_rdev));
 	if (fops && fops->release)
-		fops->release(inode,NULL);
+		return fops->release(inode,NULL);
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.30/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.1.30/linux/fs/ext2/file.c	Sun Jan 26 02:07:43 1997
+++ linux/fs/ext2/file.c	Wed Apr  2 17:43:22 1997
@@ -38,7 +38,7 @@
 
 static long long ext2_file_lseek(struct inode *, struct file *, long long, int);
 static long ext2_file_write (struct inode *, struct file *, const char *, unsigned long);
-static void ext2_release_file (struct inode *, struct file *);
+static int ext2_release_file (struct inode *, struct file *);
 
 /*
  * We have mostly NULL's here: the current defaults are ok for
@@ -260,8 +260,9 @@
  * from ext2_open: open gets called at every open, but release
  * gets called only when /all/ the files are closed.
  */
-static void ext2_release_file (struct inode * inode, struct file * filp)
+static int ext2_release_file (struct inode * inode, struct file * filp)
 {
 	if (filp->f_mode & 2)
 		ext2_discard_prealloc (inode);
+	return 0;
 }
diff -u --recursive --new-file v2.1.30/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c
--- v2.1.30/linux/fs/ext2/fsync.c	Thu Nov 14 00:27:37 1996
+++ linux/fs/ext2/fsync.c	Mon Mar 31 12:52:31 1997
@@ -13,10 +13,15 @@
  *
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
+ * 
+ *  Removed unnecessary code duplication for little endian machines
+ *  and excessive __inline__s. 
+ *        Andi Kleen, 1997
  */
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/byteorder.h>
 
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -30,7 +35,7 @@
 #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb))
 #define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb))
 
-static __inline__ int sync_block (struct inode * inode, u32 * block, int wait)
+static int sync_block (struct inode * inode, u32 * block, int wait)
 {
 	struct buffer_head * bh;
 	int tmp;
@@ -58,7 +63,8 @@
 	return 0;
 }
 
-static __inline__ int sync_block_swab32 (struct inode * inode, u32 * block, int wait)
+#ifndef __LITTLE_ENDIAN
+static int sync_block_swab32 (struct inode * inode, u32 * block, int wait)
 {
 	struct buffer_head * bh;
 	int tmp;
@@ -85,8 +91,12 @@
 	bh->b_count--;
 	return 0;
 }
+#else
+#define sync_block_swab32 sync_block
+#endif
 
-static __inline__ int sync_iblock (struct inode * inode, u32 * iblock, 
+
+static int sync_iblock (struct inode * inode, u32 * iblock, 
 			struct buffer_head ** bh, int wait) 
 {
 	int rc, tmp;
@@ -109,7 +119,8 @@
 	return 0;
 }
 
-static __inline__ int sync_iblock_swab32 (struct inode * inode, u32 * iblock, 
+#ifndef __LITTLE_ENDIAN
+static int sync_iblock_swab32 (struct inode * inode, u32 * iblock, 
 			       struct buffer_head ** bh, int wait) 
 {
 	int rc, tmp;
@@ -131,9 +142,11 @@
 		return -1;
 	return 0;
 }
+#else
+#define sync_iblock_swab32 sync_iblock
+#endif
 
-
-static __inline__ int sync_direct (struct inode * inode, int wait)
+static int sync_direct (struct inode * inode, int wait)
 {
 	int i;
 	int rc, err = 0;
@@ -148,7 +161,7 @@
 	return err;
 }
 
-static __inline__ int sync_indirect (struct inode * inode, u32 * iblock, int wait)
+static int sync_indirect (struct inode * inode, u32 * iblock, int wait)
 {
 	int i;
 	struct buffer_head * ind_bh;
@@ -171,6 +184,7 @@
 	return err;
 }
 
+#ifndef __LITTLE_ENDIAN
 static __inline__ int sync_indirect_swab32 (struct inode * inode, u32 * iblock, int wait)
 {
 	int i;
@@ -193,8 +207,11 @@
 	brelse (ind_bh);
 	return err;
 }
+#else
+#define sync_indirect_swab32 sync_indirect
+#endif
 
-static __inline__ int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
+static int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
 {
 	int i;
 	struct buffer_head * dind_bh;
@@ -217,6 +234,7 @@
 	return err;
 }
 
+#ifndef __LITTLE_ENDIAN
 static __inline__ int sync_dindirect_swab32 (struct inode * inode, u32 * diblock, int wait)
 {
 	int i;
@@ -239,8 +257,11 @@
 	brelse (dind_bh);
 	return err;
 }
+#else
+#define sync_dindirect_swab32 sync_dindirect
+#endif
 
-static __inline__ int sync_tindirect (struct inode * inode, u32 * tiblock, int wait)
+static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait)
 {
 	int i;
 	struct buffer_head * tind_bh;
diff -u --recursive --new-file v2.1.30/linux/fs/filesystems.c linux/fs/filesystems.c
--- v2.1.30/linux/fs/filesystems.c	Thu Feb 27 10:57:31 1997
+++ linux/fs/filesystems.c	Fri Mar 28 15:10:39 1997
@@ -23,6 +23,7 @@
 #include <linux/affs_fs.h>
 #include <linux/ufs_fs.h>
 #include <linux/romfs_fs.h>
+#include <linux/auto_fs.h>
 #include <linux/major.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -108,6 +109,10 @@
 
 #ifdef CONFIG_UFS_FS
 	init_ufs_fs();
+#endif
+
+#ifdef CONFIG_AUTOFS_FS
+	init_autofs_fs();
 #endif
 
 	mount_root();
diff -u --recursive --new-file v2.1.30/linux/fs/locks.c linux/fs/locks.c
--- v2.1.30/linux/fs/locks.c	Sun Jan 26 02:07:44 1997
+++ linux/fs/locks.c	Wed Apr  2 17:43:22 1997
@@ -97,6 +97,9 @@
  *  Made mandatory locking a mount option. Default is not to allow mandatory
  *  locking.
  *  Andy Walker (andy@lysaker.kvaerner.no), Oct 04, 1996.
+ *
+ *  Some adaptations for NFS support.
+ *  Olaf Kirch (okir@monad.swb.de), Dec 1996,
  */
 
 #include <linux/malloc.h>
@@ -123,10 +126,8 @@
 static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl);
 static int flock_lock_file(struct file *filp, struct file_lock *caller,
 			   unsigned int wait);
-static int posix_lock_file(struct file *filp, struct file_lock *caller,
-			   unsigned int wait);
-static int posix_locks_deadlock(struct task_struct *my_task,
-				struct task_struct *blocked_task);
+static int posix_locks_deadlock(struct file_lock *caller,
+				struct file_lock *blocker);
 
 static struct file_lock *locks_alloc_lock(struct file_lock *fl);
 static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl);
@@ -137,7 +138,7 @@
 static void locks_delete_block(struct file_lock *blocker, struct file_lock *waiter);
 static void locks_wake_up_blocks(struct file_lock *blocker, unsigned int wait);
 
-static struct file_lock *file_lock_table = NULL;
+struct file_lock *file_lock_table = NULL;
 
 /* Free lock not inserted in any queue.
  */
@@ -161,6 +162,15 @@
 		(fl2->fl_end >= fl1->fl_start));
 }
 
+/* Check whether two locks have the same owner
+ */
+static inline int
+locks_same_owner(struct file_lock *fl1, struct file_lock *fl2)
+{
+	return (fl1->fl_owner == fl2->fl_owner) &&
+	       (fl1->fl_pid   == fl2->fl_pid);
+}
+
 /* Insert waiter into blocker's block list.
  * We use a circular list so that processes can be easily woken up in
  * the order they blocked. The documentation doesn't require this but
@@ -211,6 +221,21 @@
 	return;
 }
 
+/* The following two are for the benefit of lockd.
+ */
+void
+posix_block_lock(struct file_lock *blocker, struct file_lock *waiter)
+{
+	locks_insert_block(blocker, waiter);
+}
+
+void
+posix_unblock_lock(struct file_lock *waiter)
+{
+	if (waiter->fl_prevblock)
+		locks_delete_block(waiter->fl_prevblock, waiter);
+}
+
 /* Wake up processes blocked waiting for blocker.
  * If told to wait then schedule the processes until the block list
  * is empty, otherwise empty the block list ourselves.
@@ -220,6 +245,8 @@
 	struct file_lock *waiter;
 
 	while ((waiter = blocker->fl_nextblock) != NULL) {
+		if (waiter->fl_notify)
+			waiter->fl_notify(waiter);
 		wake_up(&waiter->fl_wait);
 		if (wait)
 			/* Let the blocked process remove waiter from the
@@ -266,6 +293,7 @@
 	struct flock flock;
 	struct file *filp;
 	struct file_lock *fl,file_lock;
+	int error;
 
 	if ((fd >= NR_OPEN) || !(filp = current->files->fd[fd]))
 		return (-EBADF);
@@ -278,21 +306,28 @@
 	if (!filp->f_inode || !posix_make_lock(filp, &file_lock, &flock))
 		return (-EINVAL);
 
-	for (fl = filp->f_inode->i_flock; fl != NULL; fl = fl->fl_next) {
-		if (!(fl->fl_flags & FL_POSIX))
-			continue;
-		if (posix_locks_conflict(&file_lock, fl)) {
-			flock.l_pid = fl->fl_owner->pid;
-			flock.l_start = fl->fl_start;
-			flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
-				fl->fl_end - fl->fl_start + 1;
-			flock.l_whence = 0;
-			flock.l_type = fl->fl_type;
-			return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0; 
-		}
-	}
-
-	flock.l_type = F_UNLCK;			/* no conflict found */
+	if (filp->f_op->lock) {
+		error = filp->f_op->lock(filp->f_inode, filp,
+					F_GETLK, &file_lock);
+		if (error < 0)
+			return error;
+		fl = &file_lock;
+	} else {
+		fl = posix_test_lock(filp, &file_lock);
+	}
+ 
+	if (fl != NULL) {
+		flock.l_pid = fl->fl_pid;
+		flock.l_start = fl->fl_start;
+		flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
+			fl->fl_end - fl->fl_start + 1;
+		flock.l_whence = 0;
+		flock.l_type = fl->fl_type;
+		return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0; 
+	} else {
+		flock.l_type = F_UNLCK;
+  	}
+  
 	return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0; 
 }
 
@@ -305,6 +340,7 @@
 	struct file_lock file_lock;
 	struct flock flock;
 	struct inode *inode;
+	int error;
 
 	/* Get arguments and validate them ...
 	 */
@@ -365,7 +401,13 @@
 	default:
 		return -EINVAL;
 	}
-	
+
+	if (filp->f_op->lock != NULL) {
+		error = filp->f_op->lock(filp->f_inode, filp, cmd, &file_lock);
+		if (error < 0)
+			return error;
+	}
+
 	return (posix_lock_file(filp, &file_lock, cmd == F_SETLKW));
 }
 
@@ -373,7 +415,7 @@
  */
 void locks_remove_locks(struct task_struct *task, struct file *filp)
 {
-	struct file_lock *fl;
+	struct file_lock file_lock, *fl;
 	struct file_lock **before;
 
 	/* For POSIX locks we free all locks on this file for the given task.
@@ -385,15 +427,39 @@
 	while ((fl = *before) != NULL) {
 		if (((fl->fl_flags & FL_POSIX) && (fl->fl_owner == task)) ||
 		    ((fl->fl_flags & FL_FLOCK) && (fl->fl_file == filp) &&
-		     (filp->f_count == 1)))
+		     (filp->f_count == 1))) {
+			file_lock = *fl;
 			locks_delete_lock(before, 0);
-		else
+			if (filp->f_op->lock) {
+				file_lock.fl_type = F_UNLCK;
+				filp->f_op->lock(filp->f_inode, filp,
+						 F_SETLK, &file_lock);
+				/* List may have changed: */
+				before = &filp->f_inode->i_flock;
+			}
+		} else {
 			before = &fl->fl_next;
+		}
 	}
 
 	return;
 }
 
+struct file_lock *
+posix_test_lock(struct file *filp, struct file_lock *fl)
+{
+	struct file_lock *cfl;
+
+	for (cfl = filp->f_inode->i_flock; cfl; cfl = cfl->fl_next) {
+		if (!(cfl->fl_flags & FL_POSIX))
+			continue;
+		if (posix_locks_conflict(cfl, fl))
+			break;
+	}
+
+	return cfl;
+}
+
 int locks_verify_locked(struct inode *inode)
 {
 	/* Candidates for mandatory locking have the setgid bit set
@@ -445,6 +511,7 @@
 	tfl.fl_file = filp;
 	tfl.fl_flags = FL_POSIX | FL_ACCESS;
 	tfl.fl_owner = current;
+	tfl.fl_pid = current->pid;
 	tfl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK;
 	tfl.fl_start = offset;
 	tfl.fl_end = offset + count - 1;
@@ -464,7 +531,7 @@
 				return (-EAGAIN);
 			if (current->signal & ~current->blocked)
 				return (-ERESTARTSYS);
-			if (posix_locks_deadlock(current, fl->fl_owner))
+			if (posix_locks_deadlock(&tfl, fl))
 				return (-EDEADLK);
 
 			locks_insert_block(fl, &tfl);
@@ -528,6 +595,7 @@
 	
 	fl->fl_file = filp;
 	fl->fl_owner = current;
+	fl->fl_pid = current->pid;
 
 	return (1);
 }
@@ -575,7 +643,7 @@
 	 * each other.
 	 */
 	if (!(sys_fl->fl_flags & FL_POSIX) ||
-	    (caller_fl->fl_owner == sys_fl->fl_owner))
+	    locks_same_owner(caller_fl, sys_fl))
 		return (0);
 
 	return (locks_conflict(caller_fl, sys_fl));
@@ -628,25 +696,39 @@
  * at a time. When we find blocked_task on a wait queue we can re-search
  * with blocked_task equal to that queue's owner, until either blocked_task
  * isn't found, or blocked_task is found on a queue owned by my_task.
+ *
+ * Note: the above assumption may not be true when handling lock requests
+ * from a broken NFS client. But broken NFS clients have a lot more to
+ * worry about than proper deadlock detection anyway... --okir
  */
-static int posix_locks_deadlock(struct task_struct *my_task,
-				struct task_struct *blocked_task)
+static int posix_locks_deadlock(struct file_lock *caller_fl,
+				struct file_lock *block_fl)
 {
 	struct file_lock *fl;
 	struct file_lock *bfl;
+	void		 *caller_owner, *blocked_owner;
+	unsigned int	 caller_pid, blocked_pid;
+
+	caller_owner = caller_fl->fl_owner;
+	caller_pid = caller_fl->fl_pid;
+	blocked_owner = block_fl->fl_owner;
+	blocked_pid = block_fl->fl_pid;
 
 next_task:
-	if (my_task == blocked_task)
+	if (caller_owner == blocked_owner && caller_pid == blocked_pid)
 		return (1);
 	for (fl = file_lock_table; fl != NULL; fl = fl->fl_nextlink) {
 		if (fl->fl_owner == NULL || fl->fl_nextblock == NULL)
 			continue;
 		for (bfl = fl->fl_nextblock; bfl != fl; bfl = bfl->fl_nextblock) {
-			if (bfl->fl_owner == blocked_task) {
-				if (fl->fl_owner == my_task) {
+			if (bfl->fl_owner == blocked_owner &&
+			    bfl->fl_pid == blocked_pid) {
+				if (fl->fl_owner == caller_owner &&
+				    fl->fl_pid == caller_pid) {
 					return (1);
 				}
-				blocked_task = fl->fl_owner;
+				blocked_owner = fl->fl_owner;
+				blocked_pid = fl->fl_pid;
 				goto next_task;
 			}
 		}
@@ -731,7 +813,7 @@
  * To all purists: Yes, I use a few goto's. Just pass on to the next function.
  */
 
-static int posix_lock_file(struct file *filp, struct file_lock *caller,
+int posix_lock_file(struct file *filp, struct file_lock *caller,
 			   unsigned int wait)
 {
 	struct file_lock *fl;
@@ -752,7 +834,7 @@
 				return (-EAGAIN);
 			if (current->signal & ~current->blocked)
 				return (-ERESTARTSYS);
-			if (posix_locks_deadlock(caller->fl_owner, fl->fl_owner))
+			if (posix_locks_deadlock(caller, fl))
 				return (-EDEADLK);
 			locks_insert_block(fl, caller);
 			interruptible_sleep_on(&caller->fl_wait);
@@ -771,13 +853,13 @@
 	/* First skip locks owned by other processes.
 	 */
 	while ((fl = *before) && (!(fl->fl_flags & FL_POSIX) ||
-				  (caller->fl_owner != fl->fl_owner))) {
+				  !locks_same_owner(caller, fl))) {
 		before = &fl->fl_next;
 	}
 
 	/* Process locks with this owner.
 	 */
-	while ((fl = *before) && (caller->fl_owner == fl->fl_owner)) {
+	while ((fl = *before) && locks_same_owner(caller, fl)) {
 		/* Detect adjacent or overlapping regions (if same lock type)
 		 */
 		if (caller->fl_type == fl->fl_type) {
@@ -845,6 +927,7 @@
 				fl->fl_start = caller->fl_start;
 				fl->fl_end = caller->fl_end;
 				fl->fl_type = caller->fl_type;
+				fl->fl_u = caller->fl_u;
 				caller = fl;
 				added = 1;
 			}
@@ -902,10 +985,13 @@
 
 	tmp->fl_flags = fl->fl_flags;
 	tmp->fl_owner = fl->fl_owner;
+	tmp->fl_pid = fl->fl_pid;
 	tmp->fl_file = fl->fl_file;
 	tmp->fl_type = fl->fl_type;
 	tmp->fl_start = fl->fl_start;
 	tmp->fl_end = fl->fl_end;
+	tmp->fl_notify = fl->fl_notify;
+	tmp->fl_u = fl->fl_u;
 
 	return (tmp);
 }
@@ -977,7 +1063,7 @@
 	}
 	p += sprintf(p, "%s ", (fl->fl_type == F_RDLCK) ? "READ " : "WRITE");
 	p += sprintf(p, "%d %s:%ld %ld %ld ",
-		     fl->fl_owner ? fl->fl_owner->pid : 0,
+		     fl->fl_pid,
 		     kdevname(inode->i_dev), inode->i_ino, fl->fl_start,
 		     fl->fl_end);
 	p += sprintf(p, "%08lx %08lx %08lx %08lx %08lx\n",
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- v2.1.30/linux/fs/ncpfs/dir.c	Sun Jan 26 02:07:44 1997
+++ linux/fs/ncpfs/dir.c	Fri Mar 28 10:42:22 1997
@@ -23,95 +23,88 @@
 
 struct ncp_dirent {
 	struct nw_info_struct i;
-	struct nw_search_sequence s; /* given back for i */
+	struct nw_search_sequence s;	/* given back for i */
 	unsigned long f_pos;
 };
 
 static long
-ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count);
+ ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count);
 
-static int 
-ncp_readdir(struct inode *inode, struct file *filp,
-            void *dirent, filldir_t filldir);
+static int
+ ncp_readdir(struct inode *inode, struct file *filp,
+	     void *dirent, filldir_t filldir);
 
 static int
-ncp_read_volume_list(struct ncp_server *server, int start_with,
-		     int cache_size);
+ ncp_read_volume_list(struct ncp_server *server, int start_with,
+		      int cache_size);
 
 static int
-ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
-	       int cache_size, struct ncp_dirent *entry);
+ ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
+		int cache_size, struct ncp_dirent *entry);
 
 static struct inode *
-ncp_iget(struct inode *dir, struct nw_file_info *finfo);
+ ncp_iget(struct inode *dir, struct nw_file_info *finfo);
 
 static struct ncp_inode_info *
-ncp_find_dir_inode(struct inode *dir, const char *name);
+ ncp_find_dir_inode(struct inode *dir, const char *name);
 
 static int
-ncp_lookup(struct inode *dir, const char *__name,
-           int len, struct inode **result);
+ ncp_lookup(struct inode *dir, const char *__name,
+	    int len, struct inode **result);
 
-static int 
-ncp_create(struct inode *dir, const char *name, int len, int mode, 
-           struct inode **result);
+static int
+ ncp_create(struct inode *dir, const char *name, int len, int mode,
+	    struct inode **result);
 
-static int 
-ncp_mkdir(struct inode *dir, const char *name, int len, int mode);
+static int
+ ncp_mkdir(struct inode *dir, const char *name, int len, int mode);
 
-static int 
-ncp_rmdir(struct inode *dir, const char *name, int len);
+static int
+ ncp_rmdir(struct inode *dir, const char *name, int len);
 
 static int
-ncp_unlink(struct inode *dir, const char *name, int len);
+ ncp_unlink(struct inode *dir, const char *name, int len);
 
 static int
-ncp_rename(struct inode *old_dir, const char *old_name, int old_len, 
-           struct inode *new_dir, const char *new_name, int new_len,
-           int must_be_dir);
-
-static inline void
-str_upper(char *name)
-{
-	while (*name)
-	{
-		if (*name >= 'a' && *name <= 'z')
-		{
+ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
+	    struct inode *new_dir, const char *new_name, int new_len,
+	    int must_be_dir);
+
+static inline void str_upper(char *name)
+{
+	while (*name) {
+		if (*name >= 'a' && *name <= 'z') {
 			*name -= ('a' - 'A');
 		}
 		name++;
 	}
 }
 
-static inline void
-str_lower(char *name)
+static inline void str_lower(char *name)
 {
-	while (*name)
-	{
-		if (*name >= 'A' && *name <= 'Z')
-		{
+	while (*name) {
+		if (*name >= 'A' && *name <= 'Z') {
 			*name += ('a' - 'A');
 		}
-		name ++;
+		name++;
 	}
 }
 
-static inline int
-ncp_namespace(struct inode *i)
+static inline int ncp_namespace(struct inode *i)
 {
-	struct ncp_server *server   = NCP_SERVER(i);
+	struct ncp_server *server = NCP_SERVER(i);
 	struct nw_info_struct *info = NCP_ISTRUCT(i);
 	return server->name_space[info->volNumber];
 }
 
-static inline int
-ncp_preserve_case(struct inode *i)
+static inline int ncp_preserve_case(struct inode *i)
 {
 	return (ncp_namespace(i) == NW_NS_OS2);
 }
 
-static struct file_operations ncp_dir_operations = {
-        NULL,			/* lseek - default */
+static struct file_operations ncp_dir_operations =
+{
+	NULL,			/* lseek - default */
 	ncp_dir_read,		/* read - bad */
 	NULL,			/* write - bad */
 	ncp_readdir,		/* readdir */
@@ -123,23 +116,24 @@
 	NULL			/* fsync */
 };
 
-struct inode_operations ncp_dir_inode_operations = {
+struct inode_operations ncp_dir_inode_operations =
+{
 	&ncp_dir_operations,	/* default directory file ops */
 	ncp_create,		/* create */
-	ncp_lookup,    		/* lookup */
+	ncp_lookup,		/* lookup */
 	NULL,			/* link */
-	ncp_unlink,    		/* unlink */
+	ncp_unlink,		/* unlink */
 	NULL,			/* symlink */
-	ncp_mkdir,     		/* mkdir */
-	ncp_rmdir,     		/* rmdir */
+	ncp_mkdir,		/* mkdir */
+	ncp_rmdir,		/* rmdir */
 	NULL,			/* mknod */
-	ncp_rename,    		/* rename */
+	ncp_rename,		/* rename */
 	NULL,			/* readlink */
 	NULL,			/* follow_link */
 	NULL,			/* bmap */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL                    /* smap */
+	NULL			/* smap */
 };
 
 
@@ -151,223 +145,181 @@
  * enable the NFS exportability of a ncpfs-mounted volume.
  */
 
-static inline int
-ncp_single_volume(struct ncp_server *server)
+static inline int ncp_single_volume(struct ncp_server *server)
 {
 	return (server->m.mounted_vol[0] != '\0');
 }
 
 inline ino_t
-ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info)
+ ncp_info_ino(struct ncp_server * server, struct ncp_inode_info * info)
 {
 	return ncp_single_volume(server)
-		? info->finfo.i.dirEntNum : (ino_t)info;
+	    ? info->finfo.i.dirEntNum : (ino_t) info;
 }
 
-static inline int
-ncp_is_server_root(struct inode *inode)
+static inline int ncp_is_server_root(struct inode *inode)
 {
 	struct ncp_server *s = NCP_SERVER(inode);
 
-	return (   (!ncp_single_volume(s))
+	return ((!ncp_single_volume(s))
 		&& (inode->i_ino == ncp_info_ino(s, &(s->root))));
 }
 
 struct ncp_inode_info *
-ncp_find_inode(struct inode *inode)
+ ncp_find_inode(struct inode *inode)
 {
 	struct ncp_server *server = NCP_SERVER(inode);
-        struct ncp_inode_info *root = &(server->root);
-        struct ncp_inode_info *this = root;
+	struct ncp_inode_info *root = &(server->root);
+	struct ncp_inode_info *this = root;
 
 	ino_t ino = inode->i_ino;
 
-        do
-	{
-                if (ino == ncp_info_ino(server, this))
-		{
+	do {
+		if (ino == ncp_info_ino(server, this)) {
 			return this;
 		}
 		this = this->next;
-        }
+	}
 	while (this != root);
 
 	return NULL;
 }
-	
-static long
-ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count)
+
+static long ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count)
 {
 	return -EISDIR;
 }
 
-static kdev_t             c_dev = 0;
-static unsigned long      c_ino = 0;
-static int                c_size;
-static int                c_seen_eof;
-static int                c_last_returned_index;
-static struct ncp_dirent* c_entry = NULL;
-static int                c_lock = 0;
+static kdev_t c_dev = 0;
+static unsigned long c_ino = 0;
+static int c_size;
+static int c_seen_eof;
+static int c_last_returned_index;
+static struct ncp_dirent *c_entry = NULL;
+static int c_lock = 0;
 static struct wait_queue *c_wait = NULL;
 
-static inline void
-ncp_lock_dircache(void)
+static inline void ncp_lock_dircache(void)
 {
 	while (c_lock)
 		sleep_on(&c_wait);
 	c_lock = 1;
 }
 
-static inline void
-ncp_unlock_dircache(void)
+static inline void ncp_unlock_dircache(void)
 {
 	c_lock = 0;
 	wake_up(&c_wait);
 }
 
-static int
-ncp_readdir(struct inode *inode, struct file *filp,
-            void *dirent, filldir_t filldir)
+static int ncp_readdir(struct inode *inode, struct file *filp,
+		       void *dirent, filldir_t filldir)
 {
 	int result = 0;
 	int i = 0;
-        int index = 0;
+	int index = 0;
 	struct ncp_dirent *entry = NULL;
-        struct ncp_server *server = NCP_SERVER(inode);
+	struct ncp_server *server = NCP_SERVER(inode);
 	struct ncp_inode_info *dir = NCP_INOP(inode);
 
-	DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int)filp->f_pos);
+	DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int) filp->f_pos);
 	DDPRINTK("ncp_readdir: inode->i_ino = %ld, c_ino = %ld\n",
 		 inode->i_ino, c_ino);
 
-	if (!inode || !S_ISDIR(inode->i_mode))
-	{
+	if (!inode || !S_ISDIR(inode->i_mode)) {
 		printk("ncp_readdir: inode is NULL or not a directory\n");
 		return -EBADF;
 	}
-
-	if (!ncp_conn_valid(server))
-	{
+	if (!ncp_conn_valid(server)) {
 		return -EIO;
 	}
-
 	ncp_lock_dircache();
 
-	if (c_entry == NULL) 
-	{
-		i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE;
+	if (c_entry == NULL) {
+		i = sizeof(struct ncp_dirent) * NCP_READDIR_CACHE_SIZE;
 		c_entry = (struct ncp_dirent *) vmalloc(i);
-		if (c_entry == NULL)
-		{
+		if (c_entry == NULL) {
 			printk("ncp_readdir: no MEMORY for cache\n");
 			result = -ENOMEM;
 			goto finished;
 		}
 	}
-
-        if (filp->f_pos == 0)
-	{
-                ncp_invalid_dir_cache(inode);
-		if (filldir(dirent,".",1, filp->f_pos,
-			    ncp_info_ino(server, dir)) < 0)
-		{
+	if (filp->f_pos == 0) {
+		ncp_invalid_dir_cache(inode);
+		if (filldir(dirent, ".", 1, filp->f_pos,
+			    ncp_info_ino(server, dir)) < 0) {
 			goto finished;
 		}
 		filp->f_pos += 1;
-        }
-
-	if (filp->f_pos == 1)
-	{
-		if (filldir(dirent,"..",2, filp->f_pos,
-			    ncp_info_ino(server, dir->dir)) < 0)
-		{
+	}
+	if (filp->f_pos == 1) {
+		if (filldir(dirent, "..", 2, filp->f_pos,
+			    ncp_info_ino(server, dir->dir)) < 0) {
 			goto finished;
 		}
 		filp->f_pos += 1;
 	}
-
-	if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino))
-	{
-		for (i = 0; i < c_size; i++)
-		{
-			if (filp->f_pos == c_entry[i].f_pos)
-			{
-                                entry = &c_entry[i];
-                                c_last_returned_index = i;
-                                index = i;
-                                break;
+	if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino)) {
+		for (i = 0; i < c_size; i++) {
+			if (filp->f_pos == c_entry[i].f_pos) {
+				entry = &c_entry[i];
+				c_last_returned_index = i;
+				index = i;
+				break;
 			}
 		}
-                if ((entry == NULL) && c_seen_eof)
-		{
+		if ((entry == NULL) && c_seen_eof) {
 			goto finished;
 		}
 	}
-
-	if (entry == NULL)
-	{
+	if (entry == NULL) {
 		int entries;
 		DDPRINTK("ncp_readdir: Not found in cache.\n");
 
-		if (ncp_is_server_root(inode))
-		{
+		if (ncp_is_server_root(inode)) {
 			entries = ncp_read_volume_list(server, filp->f_pos,
-						       NCP_READDIR_CACHE_SIZE);
+						 NCP_READDIR_CACHE_SIZE);
 			DPRINTK("ncp_read_volume_list returned %d\n", entries);
 
-		}
-		else
-		{
+		} else {
 			entries = ncp_do_readdir(server, inode, filp->f_pos,
 						 NCP_READDIR_CACHE_SIZE,
 						 c_entry);
 			DPRINTK("ncp_readdir returned %d\n", entries);
 		}
 
-		if (entries < 0)
-		{
+		if (entries < 0) {
 			c_dev = 0;
 			c_ino = 0;
 			result = entries;
 			goto finished;
 		}
-
-		if (entries > 0)
-		{
-                        c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE);
-			c_dev  = inode->i_dev;
-			c_ino  = inode->i_ino;
+		if (entries > 0) {
+			c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE);
+			c_dev = inode->i_dev;
+			c_ino = inode->i_ino;
 			c_size = entries;
 			entry = c_entry;
-                        c_last_returned_index = 0;
-                        index = 0;
+			c_last_returned_index = 0;
+			index = 0;
 
-			if (!ncp_preserve_case(inode))
-			{
-				for (i = 0; i < c_size; i++)
-				{
+			if (!ncp_preserve_case(inode)) {
+				for (i = 0; i < c_size; i++) {
 					str_lower(c_entry[i].i.entryName);
 				}
 			}
 		}
 	}
-
-        if (entry == NULL)
-	{
-                /* Nothing found, even from a ncp call */
+	if (entry == NULL) {
+		/* Nothing found, even from a ncp call */
 		goto finished;
-        }
-
-        while (index < c_size)
-	{
+	}
+	while (index < c_size) {
 		ino_t ino;
 
-		if (ncp_single_volume(server))
-		{
-			ino = (ino_t)(entry->i.dirEntNum);
-		}
-		else
-		{
+		if (ncp_single_volume(server)) {
+			ino = (ino_t) (entry->i.dirEntNum);
+		} else {
 			/* For getwd() we have to return the correct
 			 * inode in d_ino if the inode is currently in
 			 * use. Otherwise the inode number does not
@@ -379,41 +331,36 @@
 			/* Some programs seem to be confused about a
 			 * zero inode number, so we set it to one.
 			 * Thanks to Gordon Chaffee for this one. */
-			if (ino_info == NULL)
-			{
+			if (ino_info == NULL) {
 				ino_info = (struct ncp_inode_info *) 1;
 			}
-			ino = (ino_t)(ino_info);
+			ino = (ino_t) (ino_info);
 		}
 
 		DDPRINTK("ncp_readdir: entry->path= %s\n", entry->i.entryName);
 		DDPRINTK("ncp_readdir: entry->f_pos = %ld\n", entry->f_pos);
 
-                if (filldir(dirent, entry->i.entryName, entry->i.nameLen,
-                            entry->f_pos, ino) < 0)
-		{
+		if (filldir(dirent, entry->i.entryName, entry->i.nameLen,
+			    entry->f_pos, ino) < 0) {
 			break;
-                }
-
-		if (   (inode->i_dev != c_dev)
+		}
+		if ((inode->i_dev != c_dev)
 		    || (inode->i_ino != c_ino)
-		    || (entry->f_pos != filp->f_pos))
-		{
+		    || (entry->f_pos != filp->f_pos)) {
 			/* Someone has destroyed the cache while we slept
 			   in filldir */
 			break;
 		}
-                filp->f_pos += 1;
-                index += 1;
-                entry += 1;
+		filp->f_pos += 1;
+		index += 1;
+		entry += 1;
 	}
- finished:
+      finished:
 	ncp_unlock_dircache();
 	return result;
 }
 
-static int
-ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size)
+static int ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size)
 {
 	struct ncp_dirent *entry = c_entry;
 
@@ -421,47 +368,35 @@
 	int i;
 
 #if 1
-	if (fpos < 2)
-	{
+	if (fpos < 2) {
 		printk("OOPS, we expect fpos >= 2");
 		fpos = 2;
 	}
 #endif
 
-	for (i=0; i<NCP_NUMBER_OF_VOLUMES; i++)
-	{
+	for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) {
 		struct ncp_volume_info info;
 
-		if (ncp_get_volume_info_with_number(server, i, &info) != 0)
-		{
+		if (ncp_get_volume_info_with_number(server, i, &info) != 0) {
 			return (total_count - fpos);
 		}
-
-		if (strlen(info.volume_name) > 0)
-		{
-			if (total_count < fpos)
-			{
+		if (strlen(info.volume_name) > 0) {
+			if (total_count < fpos) {
 				DPRINTK("ncp_read_volumes: skipped vol: %s\n",
 					info.volume_name);
-			}
-			else if (total_count >= fpos + cache_size)
-			{
+			} else if (total_count >= fpos + cache_size) {
 				return (total_count - fpos);
-			}
-			else
-			{
+			} else {
 				DPRINTK("ncp_read_volumes: found vol: %s\n",
 					info.volume_name);
 
 				if (ncp_lookup_volume(server,
 						      info.volume_name,
-						      &(entry->i)) != 0)
-				{
+						      &(entry->i)) != 0) {
 					DPRINTK("ncpfs: could not lookup vol "
 						"%s\n", info.volume_name);
 					continue;
 				}
-
 				entry->f_pos = total_count;
 				entry += 1;
 			}
@@ -471,59 +406,46 @@
 	return (total_count - fpos);
 }
 
-static int
-ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
-	       int cache_size, struct ncp_dirent *entry)
+static int ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
+			  int cache_size, struct ncp_dirent *entry)
 {
 	static struct nw_search_sequence seq;
 	static struct inode *last_dir;
 	static int total_count;
 
 #if 1
-	if (fpos < 2)
-	{
+	if (fpos < 2) {
 		printk("OOPS, we expect fpos >= 2");
 		fpos = 2;
 	}
 #endif
 	DPRINTK("ncp_do_readdir: fpos = %d\n", fpos);
 
-	if (fpos == 2)
-	{
+	if (fpos == 2) {
 		last_dir = NULL;
 		total_count = 2;
 	}
-
-	if ((fpos != total_count) || (dir != last_dir))
-	{
+	if ((fpos != total_count) || (dir != last_dir)) {
 		total_count = 2;
 		last_dir = dir;
 
 		DPRINTK("ncp_do_readdir: re-used seq for %s\n",
 			NCP_ISTRUCT(dir)->entryName);
 
-		if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq)!=0)
-		{
+		if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq) != 0) {
 			DPRINTK("ncp_init_search failed\n");
 			return total_count - fpos;
 		}
 	}
-
-	while (total_count < fpos + cache_size)
-	{
+	while (total_count < fpos + cache_size) {
 		if (ncp_search_for_file_or_subdir(server, &seq,
-						  &(entry->i)) != 0)
-		{
+						  &(entry->i)) != 0) {
 			return total_count - fpos;
 		}
-
-		if (total_count < fpos)
-		{
+		if (total_count < fpos) {
 			DPRINTK("ncp_do_readdir: skipped file: %s\n",
 				entry->i.entryName);
-		}
-		else
-		{
+		} else {
 			DDPRINTK("ncp_do_r: file: %s, f_pos=%d,total_count=%d",
 				 entry->i.entryName, fpos, total_count);
 			entry->s = seq;
@@ -535,143 +457,124 @@
 	return (total_count - fpos);
 }
 
-void
-ncp_init_dir_cache(void)
+void ncp_init_dir_cache(void)
 {
-	c_dev   = 0;
-        c_ino   = 0;
-        c_entry = NULL;
+	c_dev = 0;
+	c_ino = 0;
+	c_entry = NULL;
 }
 
-void
-ncp_invalid_dir_cache(struct inode *ino)
+void ncp_invalid_dir_cache(struct inode *ino)
 {
-	if ((ino->i_dev == c_dev) && (ino->i_ino == c_ino))
-	{
+	if ((ino->i_dev == c_dev) && (ino->i_ino == c_ino)) {
 		c_dev = 0;
-                c_ino = 0;
-                c_seen_eof = 0;
-        }
+		c_ino = 0;
+		c_seen_eof = 0;
+	}
 }
 
-void
-ncp_free_dir_cache(void)
-{
-        DPRINTK("ncp_free_dir_cache: enter\n");
-        
-        if (c_entry == NULL)
-	{
-                return;
-	}
+void ncp_free_dir_cache(void)
+{
+	DPRINTK("ncp_free_dir_cache: enter\n");
 
+	if (c_entry == NULL) {
+		return;
+	}
 	vfree(c_entry);
 	c_entry = NULL;
 
-        DPRINTK("ncp_free_dir_cache: exit\n");
+	DPRINTK("ncp_free_dir_cache: exit\n");
 }
 
 
 static struct inode *
-ncp_iget(struct inode *dir, struct nw_file_info *finfo)
+ ncp_iget(struct inode *dir, struct nw_file_info *finfo)
 {
 	struct inode *inode;
-        struct ncp_inode_info *new_inode_info;
-        struct ncp_inode_info *root;
+	struct ncp_inode_info *new_inode_info;
+	struct ncp_inode_info *root;
 
-	if (dir == NULL)
-	{
+	if (dir == NULL) {
 		printk("ncp_iget: dir is NULL\n");
 		return NULL;
 	}
-
-	if (finfo == NULL)
-	{
+	if (finfo == NULL) {
 		printk("ncp_iget: finfo is NULL\n");
 		return NULL;
 	}
+	new_inode_info = ncp_kmalloc(sizeof(struct ncp_inode_info),
+				     GFP_KERNEL);
 
-        new_inode_info = ncp_kmalloc(sizeof(struct ncp_inode_info),
-                                     GFP_KERNEL);
-
-        if (new_inode_info == NULL)
-	{
-                printk("ncp_iget: could not alloc mem for %s\n",
+	if (new_inode_info == NULL) {
+		printk("ncp_iget: could not alloc mem for %s\n",
 		       finfo->i.entryName);
-                return NULL;
-        }
+		return NULL;
+	}
+	new_inode_info->state = NCP_INODE_LOOKED_UP;
+	new_inode_info->nused = 0;
+	new_inode_info->dir = NCP_INOP(dir);
+	new_inode_info->finfo = *finfo;
+
+	NCP_INOP(dir)->nused += 1;
+
+	/* We have to link the new inode_info into the doubly linked
+	   list of inode_infos to make a complete linear search
+	   possible. */
+
+	root = &(NCP_SERVER(dir)->root);
+
+	new_inode_info->prev = root;
+	new_inode_info->next = root->next;
+	root->next->prev = new_inode_info;
+	root->next = new_inode_info;
 
-        new_inode_info->state = NCP_INODE_LOOKED_UP;
-        new_inode_info->nused = 0;
-        new_inode_info->dir   = NCP_INOP(dir);
-        new_inode_info->finfo = *finfo;
-
-        NCP_INOP(dir)->nused += 1;
-
-        /* We have to link the new inode_info into the doubly linked
-           list of inode_infos to make a complete linear search
-           possible. */
-
-        root = &(NCP_SERVER(dir)->root);
-
-        new_inode_info->prev = root;
-        new_inode_info->next = root->next;
-        root->next->prev = new_inode_info;
-        root->next = new_inode_info;
-        
 	if (!(inode = iget(dir->i_sb, ncp_info_ino(NCP_SERVER(dir),
-						   new_inode_info))))
-	{
+						   new_inode_info)))) {
 		printk("ncp_iget: iget failed!");
 		return NULL;
 	}
-
 	return inode;
 }
 
-void
-ncp_free_inode_info(struct ncp_inode_info *i)
+void ncp_free_inode_info(struct ncp_inode_info *i)
 {
-        if (i == NULL)
-	{
-                printk("ncp_free_inode: i == NULL\n");
-                return;
-        }
-
-        i->state = NCP_INODE_CACHED;
-        while ((i->nused == 0) && (i->state == NCP_INODE_CACHED))
-	{
-                struct ncp_inode_info *dir = i->dir;
+	if (i == NULL) {
+		printk("ncp_free_inode: i == NULL\n");
+		return;
+	}
+	i->state = NCP_INODE_CACHED;
+	while ((i->nused == 0) && (i->state == NCP_INODE_CACHED)) {
+		struct ncp_inode_info *dir = i->dir;
 
-                i->next->prev = i->prev;
-                i->prev->next = i->next;
+		i->next->prev = i->prev;
+		i->prev->next = i->next;
 
 		DDPRINTK("ncp_free_inode_info: freeing %s\n",
 			 i->finfo.i.entryName);
 
-                ncp_kfree_s(i, sizeof(struct ncp_inode_info));
+		ncp_kfree_s(i, sizeof(struct ncp_inode_info));
 
-                if (dir == i) return;
+		if (dir == i)
+			return;
 
-                (dir->nused)--;
-                i = dir;
-        }
+		(dir->nused)--;
+		i = dir;
+	}
 }
-        
-void
-ncp_init_root(struct ncp_server *server)
+
+void ncp_init_root(struct ncp_server *server)
 {
-        struct ncp_inode_info *root = &(server->root);
+	struct ncp_inode_info *root = &(server->root);
 	struct nw_info_struct *i = &(root->finfo.i);
 	unsigned short dummy;
 
-	DPRINTK("ncp_init_root: server %s\n", server->m.server_name);
-	DPRINTK("ncp_init_root: i = %x\n", (int)i);
+	DPRINTK("ncp_init_root: i = %x\n", (int) i);
 
-        root->finfo.opened = 0;
-	i->attributes  = aDIR;
+	root->finfo.opened = 0;
+	i->attributes = aDIR;
 	i->dataStreamSize = 1024;
 	i->dirEntNum = i->DosDirNum = 0;
-	i->volNumber = NCP_NUMBER_OF_VOLUMES+1;	/* illegal volnum */
+	i->volNumber = NCP_NUMBER_OF_VOLUMES + 1;	/* illegal volnum */
 	ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
 	ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));
 	ncp_date_unix2dos(0, &dummy, &(i->lastAccessDate));
@@ -683,25 +586,21 @@
 	i->nameLen = 0;
 	i->entryName[0] = '\0';
 
-        root->state = NCP_INODE_LOOKED_UP;
-        root->nused = 1;
-        root->dir   = root;
-        root->next = root->prev = root;
-        return;
+	root->state = NCP_INODE_LOOKED_UP;
+	root->nused = 1;
+	root->dir = root;
+	root->next = root->prev = root;
+	return;
 }
 
-int
-ncp_conn_logged_in(struct ncp_server *server)
+int ncp_conn_logged_in(struct ncp_server *server)
 {
-	if (server->m.mounted_vol[0] == '\0')
-	{
+	if (server->m.mounted_vol[0] == '\0') {
 		return 0;
 	}
-
 	str_upper(server->m.mounted_vol);
 	if (ncp_lookup_volume(server, server->m.mounted_vol,
-			      &(server->root.finfo.i)) != 0)
-	{
+			      &(server->root.finfo.i)) != 0) {
 		return -ENOENT;
 	}
 	str_lower(server->root.finfo.i.entryName);
@@ -709,202 +608,166 @@
 	return 0;
 }
 
-void
-ncp_free_all_inodes(struct ncp_server *server)
+void ncp_free_all_inodes(struct ncp_server *server)
 {
-        /* Here nothing should be to do. I do not know whether it's
-           better to leave some memory allocated or be stuck in an
-           endless loop */
+	/* Here nothing should be to do. I do not know whether it's
+	   better to leave some memory allocated or be stuck in an
+	   endless loop */
 #if 1
-        struct ncp_inode_info *root = &(server->root);
+	struct ncp_inode_info *root = &(server->root);
 
-        if (root->next != root)
-	{
-                printk("ncp_free_all_inodes: INODES LEFT!!!\n");
-        }
-
-        while (root->next != root)
-	{
-                printk("ncp_free_all_inodes: freeing inode\n");
-                ncp_free_inode_info(root->next);
-                /* In case we have an endless loop.. */
-                schedule();
-        }
-#endif        
-        
-        return;
+	if (root->next != root) {
+		printk("ncp_free_all_inodes: INODES LEFT!!!\n");
+	}
+	while (root->next != root) {
+		printk("ncp_free_all_inodes: freeing inode\n");
+		ncp_free_inode_info(root->next);
+		/* In case we have an endless loop.. */
+		schedule();
+	}
+#endif
+
+	return;
 }
 
 /* We will search the inode that belongs to this name, currently by a
    complete linear search through the inodes belonging to this
    filesystem. This has to be fixed. */
 static struct ncp_inode_info *
-ncp_find_dir_inode(struct inode *dir, const char *name)
+ ncp_find_dir_inode(struct inode *dir, const char *name)
 {
 	struct ncp_server *server = NCP_SERVER(dir);
 	struct nw_info_struct *dir_info = NCP_ISTRUCT(dir);
-        struct ncp_inode_info *result = &(server->root);
+	struct ncp_inode_info *result = &(server->root);
 
-        if (name == NULL)
-	{
-                return NULL;
+	if (name == NULL) {
+		return NULL;
 	}
-
-        do
-	{
-		if (   (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum)
-		    && (result->dir->finfo.i.volNumber == dir_info->volNumber)
+	do {
+		if ((result->dir->finfo.i.dirEntNum == dir_info->dirEntNum)
+		&& (result->dir->finfo.i.volNumber == dir_info->volNumber)
 		    && (strcmp(result->finfo.i.entryName, name) == 0)
-		    /* The root dir is never looked up using this
-		     * routine.  Without the following test a root
-		     * directory 'sys' in a volume named 'sys' could
-		     * never be looked up, because
-		     * server->root->dir==server->root. */
-		    && (result != &(server->root)))
-		{
-                        return result;
+		/* The root dir is never looked up using this
+		 * routine.  Without the following test a root
+		 * directory 'sys' in a volume named 'sys' could
+		 * never be looked up, because
+		 * server->root->dir==server->root. */
+		    && (result != &(server->root))) {
+			return result;
 		}
-                result = result->next;
+		result = result->next;
 
-        }
+	}
 	while (result != &(server->root));
 
-        return NULL;
+	return NULL;
 }
 
-static int 
-ncp_lookup(struct inode *dir, const char *__name, int len,
-           struct inode **result)
+static int ncp_lookup(struct inode *dir, const char *__name, int len,
+		      struct inode **result)
 {
 	struct nw_file_info finfo;
 	struct ncp_server *server;
 	struct ncp_inode_info *result_info;
 	int found_in_cache;
 	int down_case = 0;
-	char name[len+1];
+	char name[len + 1];
 
 	*result = NULL;
 
-	if (!dir || !S_ISDIR(dir->i_mode))
-	{
+	if (!dir || !S_ISDIR(dir->i_mode)) {
 		printk("ncp_lookup: inode is NULL or not a directory.\n");
 		iput(dir);
 		return -ENOENT;
 	}
-
 	server = NCP_SERVER(dir);
 
-	if (!ncp_conn_valid(server))
-	{
+	if (!ncp_conn_valid(server)) {
 		iput(dir);
 		return -EIO;
 	}
-
 	DPRINTK("ncp_lookup: %s, len %d\n", __name, len);
 
 	/* Fast cheat for . */
-	if (len == 0 || (len == 1 && __name[0] == '.'))
-	{
+	if (len == 0 || (len == 1 && __name[0] == '.')) {
 		*result = dir;
 		return 0;
 	}
-
 	/* ..and for .. */
-	if (len == 2 && __name[0] == '.' && __name[1] == '.')
-	{
+	if (len == 2 && __name[0] == '.' && __name[1] == '.') {
 		struct ncp_inode_info *parent = NCP_INOP(dir)->dir;
 
-		if (parent->state == NCP_INODE_CACHED)
-		{
+		if (parent->state == NCP_INODE_CACHED) {
 			parent->state = NCP_INODE_LOOKED_UP;
 		}
-
 		*result = iget(dir->i_sb, ncp_info_ino(server, parent));
 		iput(dir);
-		if (*result == 0)
-		{
+		if (*result == 0) {
 			return -EACCES;
-		}
-		else
-		{
+		} else {
 			return 0;
 		}
 	}
-
 	memcpy(name, __name, len);
 	name[len] = 0;
 	lock_super(dir->i_sb);
 	result_info = ncp_find_dir_inode(dir, name);
 
-        if (result_info != 0)
-	{
-                if (result_info->state == NCP_INODE_CACHED)
-		{
-                        result_info->state = NCP_INODE_LOOKED_UP;
+	if (result_info != 0) {
+		if (result_info->state == NCP_INODE_CACHED) {
+			result_info->state = NCP_INODE_LOOKED_UP;
 		}
+		/* Here we convert the inode_info address into an
+		   inode number */
 
-                /* Here we convert the inode_info address into an
-                   inode number */
-
-                *result = iget(dir->i_sb, ncp_info_ino(server, result_info));
+		*result = iget(dir->i_sb, ncp_info_ino(server, result_info));
 		unlock_super(dir->i_sb);
-                iput(dir);
-
-                if (*result == NULL)
-		{
-                        return -EACCES;
-                }
+		iput(dir);
 
+		if (*result == NULL) {
+			return -EACCES;
+		}
 		return 0;
-        }
-
-        /* If the file is in the dir cache, we do not have to ask the
-           server. */
+	}
+	/* If the file is in the dir cache, we do not have to ask the
+	   server. */
 
-        found_in_cache = 0;
+	found_in_cache = 0;
 	ncp_lock_dircache();
 
-        if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino))
-	{
-                int first = c_last_returned_index;
-                int i;
-
-                i = first;
-                do
-		{
-                        DDPRINTK("ncp_lookup: trying index: %d, name: %s\n",
+	if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino)) {
+		int first = c_last_returned_index;
+		int i;
+
+		i = first;
+		do {
+			DDPRINTK("ncp_lookup: trying index: %d, name: %s\n",
 				 i, c_entry[i].i.entryName);
 
-                        if (strcmp(c_entry[i].i.entryName, name) == 0)
-			{
-                                DPRINTK("ncp_lookup: found in cache!\n");
+			if (strcmp(c_entry[i].i.entryName, name) == 0) {
+				DPRINTK("ncp_lookup: found in cache!\n");
 				finfo.i = c_entry[i].i;
 				found_in_cache = 1;
 				break;
-                        }
-                        i = (i + 1) % c_size;
-                }
+			}
+			i = (i + 1) % c_size;
+		}
 		while (i != first);
-        }
+	}
 	ncp_unlock_dircache();
 
-        if (found_in_cache == 0)
-	{
+	if (found_in_cache == 0) {
 		int res;
 
 		DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
 			 NCP_ISTRUCT(dir)->entryName, name);
 
-		if (ncp_is_server_root(dir))
-		{
+		if (ncp_is_server_root(dir)) {
 			str_upper(name);
 			down_case = 1;
 			res = ncp_lookup_volume(server, name, &(finfo.i));
-		}
-		else
-		{
-			if (!ncp_preserve_case(dir))
-			{
+		} else {
+			if (!ncp_preserve_case(dir)) {
 				str_upper(name);
 				down_case = 1;
 			}
@@ -913,313 +776,246 @@
 					      NCP_ISTRUCT(dir)->dirEntNum,
 					      name, &(finfo.i));
 		}
-		if (res != 0)
-		{
+		if (res != 0) {
 			unlock_super(dir->i_sb);
-                        iput(dir);
-                        return -ENOENT;
-                }
-        }
-
+			iput(dir);
+			return -ENOENT;
+		}
+	}
 	finfo.opened = 0;
 
-	if (down_case != 0)
-	{
+	if (down_case != 0) {
 		str_lower(finfo.i.entryName);
 	}
-
-	if (!(*result = ncp_iget(dir, &finfo)))
-	{
+	if (!(*result = ncp_iget(dir, &finfo))) {
 		unlock_super(dir->i_sb);
 		iput(dir);
 		return -EACCES;
 	}
-
 	unlock_super(dir->i_sb);
 	iput(dir);
 	return 0;
 }
 
-static int 
-ncp_create(struct inode *dir, const char *name, int len, int mode,
-           struct inode **result)
+static int ncp_create(struct inode *dir, const char *name, int len, int mode,
+		      struct inode **result)
 {
 	struct nw_file_info finfo;
-	__u8 _name[len+1];
+	__u8 _name[len + 1];
 
 	*result = NULL;
 
-	if (!dir || !S_ISDIR(dir->i_mode))
-	{
+	if (!dir || !S_ISDIR(dir->i_mode)) {
 		printk("ncp_create: inode is NULL or not a directory\n");
 		iput(dir);
 		return -ENOENT;
 	}
-	if (!ncp_conn_valid(NCP_SERVER(dir)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(dir))) {
 		iput(dir);
 		return -EIO;
 	}
-
 	strncpy(_name, name, len);
 	_name[len] = '\0';
 
-	if (!ncp_preserve_case(dir))
-	{
+	if (!ncp_preserve_case(dir)) {
 		str_upper(_name);
 	}
-
 	lock_super(dir->i_sb);
 	if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
 					   NCP_ISTRUCT(dir), _name,
-					   OC_MODE_CREATE|OC_MODE_OPEN|
+					   OC_MODE_CREATE | OC_MODE_OPEN |
 					   OC_MODE_REPLACE,
-					   0, AR_READ|AR_WRITE,
-					   &finfo) != 0)
-	{
+					   0, AR_READ | AR_WRITE,
+					   &finfo) != 0) {
 		unlock_super(dir->i_sb);
 		iput(dir);
 		return -EACCES;
 	}
-
 	ncp_invalid_dir_cache(dir);
 
-	if (!ncp_preserve_case(dir))
-	{
+	if (!ncp_preserve_case(dir)) {
 		str_lower(finfo.i.entryName);
 	}
-
 	finfo.access = O_RDWR;
 
-	if (!(*result = ncp_iget(dir, &finfo)) < 0)
-	{
+	if (!(*result = ncp_iget(dir, &finfo)) < 0) {
 		ncp_close_file(NCP_SERVER(dir), finfo.file_handle);
 		unlock_super(dir->i_sb);
 		iput(dir);
 		return -EINVAL;
 	}
-
 	unlock_super(dir->i_sb);
 	iput(dir);
-	return 0;	
+	return 0;
 }
 
-static int
-ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
+static int ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
 {
 	int error;
 	struct nw_file_info new_dir;
-	__u8 _name[len+1];
+	__u8 _name[len + 1];
 
-	if (   (name[0] == '.')
-	    && (   (len == 1)
-		|| (   (len == 2)
-		    && (name[1] == '.'))))
-	{
+	if ((name[0] == '.')
+	    && ((len == 1)
+		|| ((len == 2)
+		    && (name[1] == '.')))) {
 		iput(dir);
 		return -EEXIST;
 	}
-
 	strncpy(_name, name, len);
 	_name[len] = '\0';
 
-	if (!ncp_preserve_case(dir))
-	{
+	if (!ncp_preserve_case(dir)) {
 		str_upper(_name);
 	}
-
-	if (!dir || !S_ISDIR(dir->i_mode))
-	{
+	if (!dir || !S_ISDIR(dir->i_mode)) {
 		printk("ncp_mkdir: inode is NULL or not a directory\n");
 		iput(dir);
 		return -ENOENT;
 	}
-	if (!ncp_conn_valid(NCP_SERVER(dir)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(dir))) {
 		iput(dir);
 		return -EIO;
 	}
-
 	if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
 					   NCP_ISTRUCT(dir), _name,
 					   OC_MODE_CREATE, aDIR, 0xffff,
-					   &new_dir) != 0)
-	{
+					   &new_dir) != 0) {
 		error = -EACCES;
-	}
-	else
-	{
+	} else {
 		error = 0;
-                ncp_invalid_dir_cache(dir);
-        }
+		ncp_invalid_dir_cache(dir);
+	}
 
 	iput(dir);
 	return error;
 }
 
-static int
-ncp_rmdir(struct inode *dir, const char *name, int len)
+static int ncp_rmdir(struct inode *dir, const char *name, int len)
 {
 	int error;
-	__u8 _name[len+1];
+	__u8 _name[len + 1];
 
-	if (!dir || !S_ISDIR(dir->i_mode))
-	{
+	if (!dir || !S_ISDIR(dir->i_mode)) {
 		printk("ncp_rmdir: inode is NULL or not a directory\n");
 		iput(dir);
 		return -ENOENT;
 	}
-	if (!ncp_conn_valid(NCP_SERVER(dir)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(dir))) {
 		iput(dir);
 		return -EIO;
 	}
-        if (ncp_find_dir_inode(dir, name) != NULL)
-	{
+	if (ncp_find_dir_inode(dir, name) != NULL) {
 		iput(dir);
-                error = -EBUSY;
-        }
-	else
-	{
+		error = -EBUSY;
+	} else {
 
 		strncpy(_name, name, len);
 		_name[len] = '\0';
 
-		if (!ncp_preserve_case(dir))
-		{
+		if (!ncp_preserve_case(dir)) {
 			str_upper(_name);
 		}
-
-                if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
+		if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
 						    NCP_ISTRUCT(dir),
-						    _name)) == 0)
-		{
-                        ncp_invalid_dir_cache(dir);
-		}
-		else
-		{
+						    _name)) == 0) {
+			ncp_invalid_dir_cache(dir);
+		} else {
 			error = -EACCES;
 		}
-        }
+	}
 	iput(dir);
 	return error;
 }
 
-static int
-ncp_unlink(struct inode *dir, const char *name, int len)
+static int ncp_unlink(struct inode *dir, const char *name, int len)
 {
 	int error;
-	__u8 _name[len+1];
+	__u8 _name[len + 1];
 
-	if (!dir || !S_ISDIR(dir->i_mode))
-	{
+	if (!dir || !S_ISDIR(dir->i_mode)) {
 		printk("ncp_unlink: inode is NULL or not a directory\n");
 		iput(dir);
 		return -ENOENT;
 	}
-	if (!ncp_conn_valid(NCP_SERVER(dir)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(dir))) {
 		iput(dir);
 		return -EIO;
 	}
-        if (ncp_find_dir_inode(dir, name) != NULL)
-	{
+	if (ncp_find_dir_inode(dir, name) != NULL) {
 		iput(dir);
-                error = -EBUSY;
-        }
-	else
-	{
+		error = -EBUSY;
+	} else {
 		strncpy(_name, name, len);
 		_name[len] = '\0';
 
-		if (!ncp_preserve_case(dir))
-		{
+		if (!ncp_preserve_case(dir)) {
 			str_upper(_name);
 		}
-
-                if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
+		if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
 						    NCP_ISTRUCT(dir),
-						    _name)) == 0)
-		{
-                        ncp_invalid_dir_cache(dir);
-		}
-		else
-		{
+						    _name)) == 0) {
+			ncp_invalid_dir_cache(dir);
+		} else {
 			error = -EACCES;
 		}
-        }
+	}
 	iput(dir);
 	return error;
 }
 
-static int
-ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
-           struct inode *new_dir, const char *new_name, int new_len,
-           int must_be_dir)
+static int ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
+		struct inode *new_dir, const char *new_name, int new_len,
+		      int must_be_dir)
 {
 	int res;
-	char _old_name[old_len+1];
-	char _new_name[new_len+1];
+	char _old_name[old_len + 1];
+	char _new_name[new_len + 1];
 
-	if (!old_dir || !S_ISDIR(old_dir->i_mode))
-	{
+	if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
 		printk("ncp_rename: old inode is NULL or not a directory\n");
-                res = -ENOENT;
-                goto finished;
+		res = -ENOENT;
+		goto finished;
 	}
-
-	if (!ncp_conn_valid(NCP_SERVER(old_dir)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(old_dir))) {
 		res = -EIO;
 		goto finished;
 	}
-
-	if (!new_dir || !S_ISDIR(new_dir->i_mode))
-	{
+	if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
 		printk("ncp_rename: new inode is NULL or not a directory\n");
-                res = -ENOENT;
-                goto finished;
+		res = -ENOENT;
+		goto finished;
+	}
+	if ((ncp_find_dir_inode(old_dir, old_name) != NULL)
+	    || (ncp_find_dir_inode(new_dir, new_name) != NULL)) {
+		res = -EBUSY;
+		goto finished;
 	}
-
-        if (   (ncp_find_dir_inode(old_dir, old_name) != NULL)
-            || (ncp_find_dir_inode(new_dir, new_name) != NULL))
-	{
-                res = -EBUSY;
-                goto finished;
-        }
-
 	strncpy(_old_name, old_name, old_len);
 	_old_name[old_len] = '\0';
 
-	if (!ncp_preserve_case(old_dir))
-	{
+	if (!ncp_preserve_case(old_dir)) {
 		str_upper(_old_name);
 	}
-
 	strncpy(_new_name, new_name, new_len);
 	_new_name[new_len] = '\0';
 
-	if (!ncp_preserve_case(new_dir))
-	{
+	if (!ncp_preserve_case(new_dir)) {
 		str_upper(_new_name);
 	}
-
 	res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
-					    NCP_ISTRUCT(old_dir), _old_name,
-					    NCP_ISTRUCT(new_dir), _new_name);
+					 NCP_ISTRUCT(old_dir), _old_name,
+					NCP_ISTRUCT(new_dir), _new_name);
 
-        if (res == 0)
-	{
-                ncp_invalid_dir_cache(old_dir);
-                ncp_invalid_dir_cache(new_dir);
-        }
-	else
-	{
+	if (res == 0) {
+		ncp_invalid_dir_cache(old_dir);
+		ncp_invalid_dir_cache(new_dir);
+	} else {
 		res = -EACCES;
 	}
-	
- finished:
-	iput(old_dir); 
+
+      finished:
+	iput(old_dir);
 	iput(new_dir);
 	return res;
 }
@@ -1228,64 +1024,62 @@
 
 /* Linear day numbers of the respective 1sts in non-leap years. */
 
-static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
+static int day_n[] =
+{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
 		  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
 
 
 extern struct timezone sys_tz;
 
-static int
-utc2local(int time)
+static int utc2local(int time)
 {
-        return time - sys_tz.tz_minuteswest*60 +
+	return time - sys_tz.tz_minuteswest * 60 +
 	    (sys_tz.tz_dsttime ? 3600 : 0);
 }
 
-static int
-local2utc(int time)
+static int local2utc(int time)
 {
-        return time + sys_tz.tz_minuteswest*60 -
+	return time + sys_tz.tz_minuteswest * 60 -
 	    (sys_tz.tz_dsttime ? 3600 : 0);
 }
 
 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
 
-int
-ncp_date_dos2unix(unsigned short time,unsigned short date)
+int ncp_date_dos2unix(unsigned short time, unsigned short date)
 {
-	int month,year,secs;
+	int month, year, secs;
 
-	month = ((date >> 5) & 15)-1;
+	month = ((date >> 5) & 15) - 1;
 	year = date >> 9;
-	secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
-	    ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
-	    month < 2 ? 1 : 0)+3653);
-			/* days since 1.1.70 plus 80's leap day */
+	secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
+	    ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
+					      month < 2 ? 1 : 0) + 3653);
+	/* days since 1.1.70 plus 80's leap day */
 	return local2utc(secs);
 }
 
 
 /* Convert linear UNIX date to a MS-DOS time/date pair. */
-void
-ncp_date_unix2dos(int unix_date,unsigned short *time, unsigned short *date)
+void ncp_date_unix2dos(int unix_date, unsigned short *time, unsigned short *date)
 {
-	int day,year,nl_day,month;
+	int day, year, nl_day, month;
 
 	unix_date = utc2local(unix_date);
-	*time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
-	    (((unix_date/3600) % 24) << 11);
-	day = unix_date/86400-3652;
-	year = day/365;
-	if ((year+3)/4+365*year > day) year--;
-	day -= (year+3)/4+365*year;
+	*time = (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) +
+	    (((unix_date / 3600) % 24) << 11);
+	day = unix_date / 86400 - 3652;
+	year = day / 365;
+	if ((year + 3) / 4 + 365 * year > day)
+		year--;
+	day -= (year + 3) / 4 + 365 * year;
 	if (day == 59 && !(year & 3)) {
 		nl_day = day;
 		month = 2;
-	}
-	else {
-		nl_day = (year & 3) || day <= 59 ? day : day-1;
+	} else {
+		nl_day = (year & 3) || day <= 59 ? day : day - 1;
 		for (month = 0; month < 12; month++)
-			if (day_n[month] > nl_day) break;
+			if (day_n[month] > nl_day)
+				break;
 	}
-	*date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
+	*date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9);
 }
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
--- v2.1.30/linux/fs/ncpfs/file.c	Sun Jan 26 02:07:44 1997
+++ linux/fs/ncpfs/file.c	Fri Mar 28 10:42:22 1997
@@ -21,215 +21,172 @@
 
 static inline int min(int a, int b)
 {
-	return a<b ? a : b;
+	return a < b ? a : b;
 }
 
-static int 
-ncp_fsync(struct inode *inode, struct file *file)
+static int ncp_fsync(struct inode *inode, struct file *file)
 {
 	return 0;
 }
 
-int
-ncp_make_open(struct inode *i, int right)
+int ncp_make_open(struct inode *i, int right)
 {
-        struct nw_file_info *finfo;
+	struct nw_file_info *finfo;
 
-        if (i == NULL)
-	{
-                printk("ncp_make_open: got NULL inode\n");
-                return -EINVAL;
-        }
-
-        finfo = NCP_FINFO(i);
+	if (i == NULL) {
+		printk("ncp_make_open: got NULL inode\n");
+		return -EINVAL;
+	}
+	finfo = NCP_FINFO(i);
 
-        DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
+	DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
 
 	lock_super(i->i_sb);
-        if (finfo->opened == 0)
-	{
+	if (finfo->opened == 0) {
 		finfo->access = -1;
-                /* tries max. rights */
+		/* tries max. rights */
 		if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
 						   NULL, NULL,
 						   OC_MODE_OPEN, 0,
 						   AR_READ | AR_WRITE,
-						   finfo) == 0)
-		{
+						   finfo) == 0) {
 			finfo->access = O_RDWR;
-		}
-		else if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
-							NULL, NULL,
-							OC_MODE_OPEN, 0,
-							AR_READ,
-							finfo) == 0)
-		{
+		} else if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
+							  NULL, NULL,
+							  OC_MODE_OPEN, 0,
+							  AR_READ,
+							  finfo) == 0) {
 			finfo->access = O_RDONLY;
 		}
-        }
-
+	}
 	unlock_super(i->i_sb);
 
-        if (   ((right == O_RDONLY) && (   (finfo->access == O_RDONLY)
-                                        || (finfo->access == O_RDWR)))
-            || ((right == O_WRONLY) && (   (finfo->access == O_WRONLY)
-                                        || (finfo->access == O_RDWR)))
-            || ((right == O_RDWR)   && (finfo->access == O_RDWR)))
-                return 0;
+	if (((right == O_RDONLY) && ((finfo->access == O_RDONLY)
+				     || (finfo->access == O_RDWR)))
+	    || ((right == O_WRONLY) && ((finfo->access == O_WRONLY)
+					|| (finfo->access == O_RDWR)))
+	    || ((right == O_RDWR) && (finfo->access == O_RDWR)))
+		return 0;
 
-        return -EACCES;
+	return -EACCES;
 }
 
-static long
-ncp_file_read(struct inode *inode, struct file *file, char *buf, unsigned long count)
+static long ncp_file_read(struct inode *inode, struct file *file, char *buf, unsigned long count)
 {
 	int bufsize, already_read;
 	off_t pos;
-        int errno;
+	int errno;
 
-        DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName);
-        
-	if (inode == NULL)
-	{
+	DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName);
+
+	if (inode == NULL) {
 		DPRINTK("ncp_file_read: inode = NULL\n");
 		return -EINVAL;
 	}
-	if (!ncp_conn_valid(NCP_SERVER(inode)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(inode))) {
 		return -EIO;
 	}
-
-	if (!S_ISREG(inode->i_mode))
-	{
+	if (!S_ISREG(inode->i_mode)) {
 		DPRINTK("ncp_file_read: read from non-file, mode %07o\n",
-                        inode->i_mode);
+			inode->i_mode);
 		return -EINVAL;
 	}
-
 	pos = file->f_pos;
 
-	if (pos + count > inode->i_size)
-	{
+	if (pos + count > inode->i_size) {
 		count = inode->i_size - pos;
 	}
-
-	if (count <= 0)
-	{
+	if (count <= 0) {
 		return 0;
 	}
-
-        if ((errno = ncp_make_open(inode, O_RDONLY)) != 0)
-	{
-                return errno;
+	if ((errno = ncp_make_open(inode, O_RDONLY)) != 0) {
+		return errno;
 	}
-        
 	bufsize = NCP_SERVER(inode)->buffer_size;
 
-        already_read = 0;
+	already_read = 0;
 
 	/* First read in as much as possible for each bufsize. */
-        while (already_read < count)
-	{
+	while (already_read < count) {
 		int read_this_time;
 		int to_read = min(bufsize - (pos % bufsize),
 				  count - already_read);
 
 		if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
-			     pos, to_read, buf, &read_this_time) != 0)
-		{
-			return -EIO; /* This is not exact, i know.. */
+			     pos, to_read, buf, &read_this_time) != 0) {
+			return -EIO;	/* This is not exact, i know.. */
 		}
-
 		pos += read_this_time;
 		buf += read_this_time;
-                already_read += read_this_time;
+		already_read += read_this_time;
 
-		if (read_this_time < to_read)
-		{
-                        break;
+		if (read_this_time < to_read) {
+			break;
 		}
 	}
 
-        file->f_pos = pos;
+	file->f_pos = pos;
 
-	if (!IS_RDONLY(inode))
-	{
+	if (!IS_RDONLY(inode)) {
 		inode->i_atime = CURRENT_TIME;
 	}
-
 	inode->i_dirt = 1;
 
-        DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName);
+	DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName);
 
-        return already_read;
+	return already_read;
 }
 
-static long
-ncp_file_write(struct inode *inode, struct file *file, const char *buf,
-	       unsigned long count)
+static long ncp_file_write(struct inode *inode, struct file *file, const char *buf,
+			   unsigned long count)
 {
 	int bufsize, already_written;
-        off_t pos;
-        int errno;
-			  
-	if (inode == NULL)
-	{
+	off_t pos;
+	int errno;
+
+	if (inode == NULL) {
 		DPRINTK("ncp_file_write: inode = NULL\n");
 		return -EINVAL;
 	}
-	if (!ncp_conn_valid(NCP_SERVER(inode)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(inode))) {
 		return -EIO;
 	}
-
-	if (!S_ISREG(inode->i_mode))
-	{
+	if (!S_ISREG(inode->i_mode)) {
 		DPRINTK("ncp_file_write: write to non-file, mode %07o\n",
-                       inode->i_mode);
+			inode->i_mode);
 		return -EINVAL;
 	}
+	DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName);
 
-        DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName);
-
-	if (count <= 0)
-	{
+	if (count <= 0) {
 		return 0;
 	}
-
-        if ((errno = ncp_make_open(inode, O_RDWR)) != 0)
-	{
-                return errno;
+	if ((errno = ncp_make_open(inode, O_RDWR)) != 0) {
+		return errno;
 	}
-        
 	pos = file->f_pos;
 
-	if (file->f_flags & O_APPEND)
-	{
+	if (file->f_flags & O_APPEND) {
 		pos = inode->i_size;
 	}
-
 	bufsize = NCP_SERVER(inode)->buffer_size;
 
-        already_written = 0;
+	already_written = 0;
 
-        while (already_written < count)
-	{
+	while (already_written < count) {
 		int written_this_time;
 		int to_write = min(bufsize - (pos % bufsize),
 				   count - already_written);
 
 		if (ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
-			      pos, to_write, buf, &written_this_time) != 0)
-		{
+			  pos, to_write, buf, &written_this_time) != 0) {
 			return -EIO;
-                }
-
+		}
 		pos += written_this_time;
 		buf += written_this_time;
 		already_written += written_this_time;
 
-		if (written_this_time < to_write)
-		{
+		if (written_this_time < to_write) {
 			break;
 		}
 	}
@@ -239,18 +196,17 @@
 
 	file->f_pos = pos;
 
-        if (pos > inode->i_size)
-	{
-                inode->i_size = pos;
+	if (pos > inode->i_size) {
+		inode->i_size = pos;
 		ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
-        }
-
-        DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
+	}
+	DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
 
 	return already_written;
 }
 
-static struct file_operations ncp_file_operations = {
+static struct file_operations ncp_file_operations =
+{
 	NULL,			/* lseek - default */
 	ncp_file_read,		/* read */
 	ncp_file_write,		/* write */
@@ -258,12 +214,13 @@
 	NULL,			/* poll - default */
 	ncp_ioctl,		/* ioctl */
 	ncp_mmap,		/* mmap */
-	NULL,                   /* open */
-	NULL,                   /* release */
+	NULL,			/* open */
+	NULL,			/* release */
 	ncp_fsync,		/* fsync */
 };
 
-struct inode_operations ncp_file_inode_operations = {
+struct inode_operations ncp_file_inode_operations =
+{
 	&ncp_file_operations,	/* default file operations */
 	NULL,			/* create */
 	NULL,			/* lookup */
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- v2.1.30/linux/fs/ncpfs/inode.c	Sun Jan 19 05:47:26 1997
+++ linux/fs/ncpfs/inode.c	Fri Mar 28 10:42:22 1997
@@ -36,8 +36,9 @@
 static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
 static int ncp_notify_change(struct inode *inode, struct iattr *attr);
 
-static struct super_operations ncp_sops = {
-	ncp_read_inode,         /* read inode */
+static struct super_operations ncp_sops =
+{
+	ncp_read_inode,		/* read inode */
 	ncp_notify_change,	/* notify change */
 	NULL,			/* write inode */
 	ncp_put_inode,		/* put inode */
@@ -51,202 +52,150 @@
    ncp_inode_info's and initializes the inode from the data found
    there.  It does not allocate or deallocate anything. */
 
-static void
-ncp_read_inode(struct inode *inode)
+static void ncp_read_inode(struct inode *inode)
 {
-        /* Our task should be extremely simple here. We only have to
-           look up the information somebody else (ncp_iget) put into
-           the inode tree. The address of this information is the
-           inode->i_ino. Just to make sure everything went well, we
-           check it's there. */
+	/* Our task should be extremely simple here. We only have to
+	   look up the information somebody else (ncp_iget) put into
+	   the inode tree. The address of this information is the
+	   inode->i_ino. Just to make sure everything went well, we
+	   check it's there. */
 
-        struct ncp_inode_info *inode_info = ncp_find_inode(inode);
+	struct ncp_inode_info *inode_info = ncp_find_inode(inode);
 
-	if (inode_info == NULL)
-	{
+	if (inode_info == NULL) {
 		/* Ok, now we're in trouble. The inode info is not there. What
 		   should we do now??? */
 		printk("ncp_read_inode: inode info not found\n");
 		return;
 	}
+	inode_info->state = NCP_INODE_VALID;
 
-        inode_info->state = NCP_INODE_VALID;
-
-        NCP_INOP(inode) = inode_info;
+	NCP_INOP(inode) = inode_info;
 	inode_info->inode = inode;
 
-        if (NCP_ISTRUCT(inode)->attributes & aDIR)
-	{
-                inode->i_mode = NCP_SERVER(inode)->m.dir_mode;
+	if (NCP_ISTRUCT(inode)->attributes & aDIR) {
+		inode->i_mode = NCP_SERVER(inode)->m.dir_mode;
 		/* for directories dataStreamSize seems to be some
 		   Object ID ??? */
 		inode->i_size = 512;
-	}
-	else
-	{
-                inode->i_mode = NCP_SERVER(inode)->m.file_mode;
+	} else {
+		inode->i_mode = NCP_SERVER(inode)->m.file_mode;
 		inode->i_size = le32_to_cpu(NCP_ISTRUCT(inode)->dataStreamSize);
 	}
 
-        DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
+	DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
 
-        inode->i_nlink   = 1;
-        inode->i_uid     = NCP_SERVER(inode)->m.uid;
-        inode->i_gid     = NCP_SERVER(inode)->m.gid;
-        inode->i_blksize = 512;
-        inode->i_rdev    = 0;
-
-        if ((inode->i_blksize != 0) && (inode->i_size != 0))
-	{
-                inode->i_blocks =
-                        (inode->i_size - 1) / inode->i_blksize + 1;
-	}
-        else
-	{
-                inode->i_blocks = 0;
+	inode->i_nlink = 1;
+	inode->i_uid = NCP_SERVER(inode)->m.uid;
+	inode->i_gid = NCP_SERVER(inode)->m.gid;
+	inode->i_blksize = 512;
+	inode->i_rdev = 0;
+
+	if ((inode->i_blksize != 0) && (inode->i_size != 0)) {
+		inode->i_blocks =
+		    (inode->i_size - 1) / inode->i_blksize + 1;
+	} else {
+		inode->i_blocks = 0;
 	}
 
 	inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->modifyTime),
-					   le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate));
+			    le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate));
 	inode->i_ctime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->creationTime),
-					   le16_to_cpu(NCP_ISTRUCT(inode)->creationDate));
+			  le16_to_cpu(NCP_ISTRUCT(inode)->creationDate));
 	inode->i_atime = ncp_date_dos2unix(0,
-					   le16_to_cpu(NCP_ISTRUCT(inode)->lastAccessDate));
+			le16_to_cpu(NCP_ISTRUCT(inode)->lastAccessDate));
 
-        if (S_ISREG(inode->i_mode))
-	{
-                inode->i_op = &ncp_file_inode_operations;
-	}
-        else if (S_ISDIR(inode->i_mode))
-	{
-                inode->i_op = &ncp_dir_inode_operations;
-	}
-        else
-	{
-                inode->i_op = NULL;
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_op = &ncp_file_inode_operations;
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_op = &ncp_dir_inode_operations;
+	} else {
+		inode->i_op = NULL;
 	}
 }
 
-static void
-ncp_put_inode(struct inode *inode)
+static void ncp_put_inode(struct inode *inode)
 {
-        struct nw_file_info *finfo = NCP_FINFO(inode);
+	struct nw_file_info *finfo = NCP_FINFO(inode);
 	struct super_block *sb = inode->i_sb;
 
 	lock_super(sb);
-        if (finfo->opened != 0)
-	{
-                if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0)
-		{
-                        /* We can't do anything but complain. */
-                        printk("ncp_put_inode: could not close\n");
-                }
-        }
-
+	if (finfo->opened != 0) {
+		if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle) != 0) {
+			/* We can't do anything but complain. */
+			printk("ncp_put_inode: could not close\n");
+		}
+	}
 	DDPRINTK("ncp_put_inode: put %s\n",
-		finfo->i.entryName);
+		 finfo->i.entryName);
 
-        ncp_free_inode_info(NCP_INOP(inode));
+	ncp_free_inode_info(NCP_INOP(inode));
 
-        if (S_ISDIR(inode->i_mode))
-	{
-                DDPRINTK("ncp_put_inode: put directory %ld\n",
+	if (S_ISDIR(inode->i_mode)) {
+		DDPRINTK("ncp_put_inode: put directory %ld\n",
 			 inode->i_ino);
-                ncp_invalid_dir_cache(inode);
-        }
-
+		ncp_invalid_dir_cache(inode);
+	}
 	clear_inode(inode);
 	unlock_super(sb);
 }
 
 struct super_block *
-ncp_read_super(struct super_block *sb, void *raw_data, int silent)
+ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
 {
 	struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data;
-        struct ncp_server *server;
+	struct ncp_server *server;
 	struct file *ncp_filp;
-	struct file *wdog_filp;
-	struct file *msg_filp;
 	kdev_t dev = sb->s_dev;
 	int error;
 
-	if (data == NULL)
-	{
+	if (data == NULL) {
 		printk("ncp_read_super: missing data argument\n");
 		sb->s_dev = 0;
 		return NULL;
 	}
-
-	if (data->version != NCP_MOUNT_VERSION)
-	{
+	if (data->version != NCP_MOUNT_VERSION) {
 		printk("ncp warning: mount version %s than kernel\n",
 		       (data->version < NCP_MOUNT_VERSION) ?
-                       "older" : "newer");
+		       "older" : "newer");
 		sb->s_dev = 0;
 		return NULL;
 	}
-
-	if (   (data->ncp_fd >= NR_OPEN)
+	if ((data->ncp_fd >= NR_OPEN)
 	    || ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL)
-	    || (!S_ISSOCK(ncp_filp->f_inode->i_mode)))
-	{
+	    || (!S_ISSOCK(ncp_filp->f_inode->i_mode))) {
 		printk("ncp_read_super: invalid ncp socket\n");
 		sb->s_dev = 0;
 		return NULL;
 	}
+	/* We must malloc our own super-block info */
+	server = (struct ncp_server *) ncp_kmalloc(sizeof(struct ncp_server),
+						   GFP_KERNEL);
 
-	if (   (data->wdog_fd >= NR_OPEN)
-	    || ((wdog_filp = current->files->fd[data->wdog_fd]) == NULL)
-	    || (!S_ISSOCK(wdog_filp->f_inode->i_mode)))
-	{
-		printk("ncp_read_super: invalid wdog socket\n");
-		sb->s_dev = 0;
+	if (server == NULL) {
+		printk("ncp_read_super: could not alloc ncp_server\n");
 		return NULL;
 	}
-
-	if (   (data->message_fd >= NR_OPEN)
-	    || ((msg_filp = current->files->fd[data->message_fd]) == NULL)
-	    || (!S_ISSOCK(msg_filp->f_inode->i_mode)))
-	{
-		printk("ncp_read_super: invalid wdog socket\n");
-		sb->s_dev = 0;
-		return NULL;
-	}
-
-        /* We must malloc our own super-block info */
-        server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
-                                                   GFP_KERNEL);
-
-        if (server == NULL)
-	{
-                printk("ncp_read_super: could not alloc ncp_server\n");
-                return NULL;
-        }
-
 	ncp_filp->f_count += 1;
-	wdog_filp->f_count += 1;
-	msg_filp->f_count += 1;
 
 	lock_super(sb);
 
-        NCP_SBP(sb) = server;
+	NCP_SBP(sb) = server;
 
-	sb->s_blocksize = 1024; /* Eh...  Is this correct? */
+	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = NCP_SUPER_MAGIC;
 	sb->s_dev = dev;
 	sb->s_op = &ncp_sops;
 
-	server->ncp_filp    = ncp_filp;
-	server->wdog_filp   = wdog_filp;
-	server->msg_filp    = msg_filp;
-	server->lock        = 0;
-	server->wait        = NULL;
-        server->packet      = NULL;
+	server->ncp_filp = ncp_filp;
+	server->lock = 0;
+	server->wait = NULL;
+	server->packet = NULL;
 	server->buffer_size = 0;
 	server->conn_status = 0;
 
-        server->m = *data;
+	server->m = *data;
 	/* Althought anything producing this is buggy, it happens
 	   now because of PATH_MAX changes.. */
 	if (server->m.time_out < 10) {
@@ -254,166 +203,98 @@
 		printk("You need to recompile your ncpfs utils..\n");
 	}
 	server->m.file_mode = (server->m.file_mode &
-			       (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
-	server->m.dir_mode  = (server->m.dir_mode &
-			       (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
-
-	/* protect against invalid mount points */
-	server->m.mount_point[sizeof(server->m.mount_point)-1] = '\0';
+			       (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG;
+	server->m.dir_mode = (server->m.dir_mode &
+			      (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFDIR;
 
 	server->packet_size = NCP_PACKET_SIZE;
-	server->packet      = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
+	server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
 
-	if (server->packet == NULL)
-	{
+	if (server->packet == NULL) {
 		printk("ncpfs: could not alloc packet\n");
 		error = -ENOMEM;
 		unlock_super(sb);
 		goto fail;
 	}
-
-        /*
-         * Make the connection to the server
-         */
-
-	if (ncp_catch_watchdog(server) != 0)
-	{
-		printk("ncp_read_super: Could not catch watchdog\n");
-		error = -EINVAL;
-		unlock_super(sb);
-		goto fail;
-	}
-
-	if (ncp_catch_message(server) != 0)
-	{
-		printk("ncp_read_super: Could not catch messages\n");
-		ncp_dont_catch_watchdog(server);
-		error = -EINVAL;
-		unlock_super(sb);
-		goto fail;
-	}
-
 	ncp_lock_server(server);
 	error = ncp_connect(server);
 	ncp_unlock_server(server);
 	unlock_super(sb);
 
-	if (error < 0)
-	{
+	if (error < 0) {
 		sb->s_dev = 0;
 		printk("ncp_read_super: Failed connection, bailing out "
-                       "(error = %d).\n", -error);
-                ncp_kfree_s(server->packet, server->packet_size);
-		ncp_dont_catch_watchdog(server);
-                goto fail;
+		       "(error = %d).\n", -error);
+		ncp_kfree_s(server->packet, server->packet_size);
+		goto fail;
 	}
-
-        DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb));
+	DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
 
 	ncp_init_root(server);
 
-	if (!(sb->s_mounted = iget(sb, ncp_info_ino(server, &(server->root)))))
-	{
+	if (!(sb->s_mounted = iget(sb, ncp_info_ino(server,
+						    &(server->root))))) {
 		sb->s_dev = 0;
 		printk("ncp_read_super: get root inode failed\n");
-                goto disconnect;
+		goto disconnect;
 	}
-
 	if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
-				     &(server->buffer_size)) != 0)
-	{
+				     &(server->buffer_size)) != 0) {
 		sb->s_dev = 0;
 		printk("ncp_read_super: could not get bufsize\n");
 		goto disconnect;
 	}
-
 	DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
 
-        MOD_INC_USE_COUNT;
+	MOD_INC_USE_COUNT;
 	return sb;
 
- disconnect:
+      disconnect:
 	ncp_lock_server(server);
 	ncp_disconnect(server);
 	ncp_unlock_server(server);
 	ncp_kfree_s(server->packet, server->packet_size);
-	ncp_dont_catch_watchdog(server);
- fail:
+      fail:
 	ncp_filp->f_count -= 1;
-	wdog_filp->f_count -= 1;
-	msg_filp->f_count -= 1;
-        ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
-        return NULL;
+	ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
+	return NULL;
 }
 
-static void
-ncp_put_super(struct super_block *sb)
+static void ncp_put_super(struct super_block *sb)
 {
-        struct ncp_server *server = NCP_SBP(sb);
+	struct ncp_server *server = NCP_SBP(sb);
 
 	lock_super(sb);
 
 	ncp_lock_server(server);
-        ncp_disconnect(server);
+	ncp_disconnect(server);
 	ncp_unlock_server(server);
 
 	close_fp(server->ncp_filp);
+	kill_proc(server->m.wdog_pid, SIGTERM, 0);
 
-	ncp_dont_catch_watchdog(server);
-	close_fp(server->wdog_filp);
-	close_fp(server->msg_filp);
-
-        ncp_free_all_inodes(server);
+	ncp_free_all_inodes(server);
 
-        ncp_kfree_s(server->packet, server->packet_size);
+	ncp_kfree_s(server->packet, server->packet_size);
 
 	sb->s_dev = 0;
-        ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
+	ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
 	NCP_SBP(sb) = NULL;
 
 	unlock_super(sb);
 
-        MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 }
 
-/* This routine is called from an interrupt in ncp_msg_data_ready. So
- * we have to be careful NOT to sleep here! */
-void
-ncp_trigger_message(struct ncp_server *server)
-{
-#ifdef CONFIG_KERNELD
-	char command[ sizeof(server->m.mount_point)
-		     + sizeof(NCP_MSG_COMMAND) + 2];
-#endif
-
-	if (server == NULL)
-	{
-		printk("ncp_trigger_message: invalid server!\n");
-		return;
-	}
-
-	DPRINTK("ncp_trigger_message: on %s\n",
-		server->m.mount_point);
-
-#ifdef CONFIG_KERNELD
-	strcpy(command, NCP_MSG_COMMAND);
-	strcat(command, " ");
-	strcat(command, server->m.mount_point);
-	DPRINTK("ksystem: %s\n", command);
-	ksystem(command, KERNELD_NOWAIT);
-#endif
-}
-
-static void
-ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
 	struct statfs tmp;
 
 	/* We cannot say how much disk space is left on a mounted
-           NetWare Server, because free space is distributed over
-           volumes, and the current user might have disk quotas. So
-           free space is not that simple to determine. Our decision
-           here is to err conservatively. */
+	   NetWare Server, because free space is distributed over
+	   volumes, and the current user might have disk quotas. So
+	   free space is not that simple to determine. Our decision
+	   here is to err conservatively. */
 
 	tmp.f_type = NCP_SUPER_MAGIC;
 	tmp.f_bsize = 512;
@@ -426,18 +307,15 @@
 	copy_to_user(buf, &tmp, bufsiz);
 }
 
-static int
-ncp_notify_change(struct inode *inode, struct iattr *attr)
+static int ncp_notify_change(struct inode *inode, struct iattr *attr)
 {
 	int result = 0;
 	int info_mask;
 	struct nw_modify_dos_info info;
 
-	if (!ncp_conn_valid(NCP_SERVER(inode)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(inode))) {
 		return -EIO;
 	}
-
 	if ((result = inode_change_ok(inode, attr)) < 0)
 		return result;
 
@@ -447,7 +325,7 @@
 
 	if (((attr->ia_valid & ATTR_GID) &&
 	     (attr->ia_uid != NCP_SERVER(inode)->m.gid)))
-                return -EPERM;
+		return -EPERM;
 
 	if (((attr->ia_valid & ATTR_MODE) &&
 	     (attr->ia_mode &
@@ -457,67 +335,54 @@
 	info_mask = 0;
 	memset(&info, 0, sizeof(info));
 
-	if ((attr->ia_valid & ATTR_CTIME) != 0)
-	{
-		info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE);
+	if ((attr->ia_valid & ATTR_CTIME) != 0) {
+		info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
 		ncp_date_unix2dos(attr->ia_ctime,
-				  &(info.creationTime), &(info.creationDate));
+			     &(info.creationTime), &(info.creationDate));
 		info.creationTime = le16_to_cpu(info.creationTime);
 		info.creationDate = le16_to_cpu(info.creationDate);
 	}
-
-	if ((attr->ia_valid & ATTR_MTIME) != 0)
-	{
-		info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE);
+	if ((attr->ia_valid & ATTR_MTIME) != 0) {
+		info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
 		ncp_date_unix2dos(attr->ia_mtime,
 				  &(info.modifyTime), &(info.modifyDate));
 		info.modifyTime = le16_to_cpu(info.modifyTime);
 		info.modifyDate = le16_to_cpu(info.modifyDate);
 	}
-
-	if ((attr->ia_valid & ATTR_ATIME) != 0)
-	{
+	if ((attr->ia_valid & ATTR_ATIME) != 0) {
 		__u16 dummy;
 		info_mask |= (DM_LAST_ACCESS_DATE);
 		ncp_date_unix2dos(attr->ia_ctime,
 				  &(dummy), &(info.lastAccessDate));
 		info.lastAccessDate = le16_to_cpu(info.lastAccessDate);
 	}
-
-	if (info_mask != 0)
-	{
+	if (info_mask != 0) {
 		if ((result =
 		     ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
-							NCP_ISTRUCT(inode),
+						      NCP_ISTRUCT(inode),
 							info_mask,
-							&info)) != 0)
-		{
+							&info)) != 0) {
 			result = -EACCES;
 
-			if (info_mask == (DM_CREATE_TIME|DM_CREATE_DATE))
-			{
+			if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
 				/* NetWare seems not to allow this. I
-                                   do not know why. So, just tell the
-                                   user everything went fine. This is
-                                   a terrible hack, but I do not know
-                                   how to do this correctly. */
+				   do not know why. So, just tell the
+				   user everything went fine. This is
+				   a terrible hack, but I do not know
+				   how to do this correctly. */
 				result = 0;
 			}
 		}
 	}
-
-        if ((attr->ia_valid & ATTR_SIZE) != 0)
-	{
+	if ((attr->ia_valid & ATTR_SIZE) != 0) {
 		int written;
 
 		DPRINTK("ncpfs: trying to change size of %s to %ld\n",
 			NCP_ISTRUCT(inode)->entryName, attr->ia_size);
 
-		if ((result = ncp_make_open(inode, O_RDWR)) < 0)
-		{
+		if ((result = ncp_make_open(inode, O_RDWR)) < 0) {
 			return -EACCES;
 		}
-
 		ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
 			  attr->ia_size, 0, "", &written);
 
@@ -529,8 +394,7 @@
 
 		result = 0;
 	}
-
-        ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
+	ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
 
 	return result;
 }
@@ -540,40 +404,40 @@
 int ncp_current_malloced;
 #endif
 
-static struct file_system_type ncp_fs_type = {
-        ncp_read_super, "ncpfs", 0, NULL
-        };
+static struct file_system_type ncp_fs_type =
+{
+	ncp_read_super, "ncpfs", 0, NULL
+};
 
 int init_ncp_fs(void)
 {
-        return register_filesystem(&ncp_fs_type);
+	return register_filesystem(&ncp_fs_type);
 }
 
 #ifdef MODULE
 EXPORT_NO_SYMBOLS;
 
-int init_module( void)
+int init_module(void)
 {
-        DPRINTK("ncpfs: init_module called\n");
+	DPRINTK("ncpfs: init_module called\n");
 
 #ifdef DEBUG_NCP_MALLOC
-        ncp_malloced = 0;
-        ncp_current_malloced = 0;
+	ncp_malloced = 0;
+	ncp_current_malloced = 0;
 #endif
-        ncp_init_dir_cache();
+	ncp_init_dir_cache();
 
 	return init_ncp_fs();
 }
 
-void
-cleanup_module(void)
+void cleanup_module(void)
 {
-        DPRINTK("ncpfs: cleanup_module called\n");
-        ncp_free_dir_cache();
-        unregister_filesystem(&ncp_fs_type);
+	DPRINTK("ncpfs: cleanup_module called\n");
+	ncp_free_dir_cache();
+	unregister_filesystem(&ncp_fs_type);
 #ifdef DEBUG_NCP_MALLOC
-        printk("ncp_malloced: %d\n", ncp_malloced);
-        printk("ncp_current_malloced: %d\n", ncp_current_malloced);
+	printk("ncp_malloced: %d\n", ncp_malloced);
+	printk("ncp_current_malloced: %d\n", ncp_current_malloced);
 #endif
 }
 
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/ioctl.c linux/fs/ncpfs/ioctl.c
--- v2.1.30/linux/fs/ncpfs/ioctl.c	Mon Oct 28 04:29:26 1996
+++ linux/fs/ncpfs/ioctl.c	Fri Mar 28 10:42:22 1997
@@ -14,70 +14,41 @@
 #include <linux/mm.h>
 #include <linux/ncp.h>
 
-int
-ncp_ioctl (struct inode * inode, struct file * filp,
-           unsigned int cmd, unsigned long arg)
+int ncp_ioctl(struct inode *inode, struct file *filp,
+	      unsigned int cmd, unsigned long arg)
 {
 	int result;
 	struct ncp_ioctl_request request;
 	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) {
+	switch (cmd) {
 	case NCP_IOC_NCPREQUEST:
 
-		if (   (permission(inode, MAY_WRITE) != 0)
-		    && (current->uid != server->m.mounted_uid))
-		{
+		if ((permission(inode, MAY_WRITE) != 0)
+		    && (current->uid != server->m.mounted_uid)) {
 			return -EACCES;
 		}
-		
-		if ((result = verify_area(VERIFY_READ, (char *)arg,
-					  sizeof(request))) != 0)
-		{
+		if ((result = verify_area(VERIFY_READ, (char *) arg,
+					  sizeof(request))) != 0) {
 			return result;
 		}
+		copy_from_user(&request, (struct ncp_ioctl_request *) arg,
+			       sizeof(request));
 
-		copy_from_user(&request, (struct ncp_ioctl_request *)arg,
-			      sizeof(request));
-
-		if (   (request.function > 255)
+		if ((request.function > 255)
 		    || (request.size >
-			NCP_PACKET_SIZE - sizeof(struct ncp_request_header)))
-		{
+		  NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) {
 			return -EINVAL;
 		}
-
-		if ((result = verify_area(VERIFY_WRITE, (char *)request.data,
-					  NCP_PACKET_SIZE)) != 0)
-		{
+		if ((result = verify_area(VERIFY_WRITE, (char *) request.data,
+					  NCP_PACKET_SIZE)) != 0) {
 			return result;
 		}
-
 		ncp_lock_server(server);
 
 		/* FIXME: We hack around in the server's structures
-                   here to be able to use ncp_request */
+		   here to be able to use ncp_request */
 
 		server->has_subfunction = 0;
 		server->current_size = request.size;
@@ -95,66 +66,55 @@
 
 	case NCP_IOC_CONN_LOGGED_IN:
 
-		if (   (permission(inode, MAY_WRITE) != 0)
-		    && (current->uid != server->m.mounted_uid))
-		{
+		if ((permission(inode, MAY_WRITE) != 0)
+		    && (current->uid != server->m.mounted_uid)) {
 			return -EACCES;
 		}
-
 		return ncp_conn_logged_in(server);
-		
+
 	case NCP_IOC_GET_FS_INFO:
 
-		if (   (permission(inode, MAY_WRITE) != 0)
-		    && (current->uid != server->m.mounted_uid))
-		{
+		if ((permission(inode, MAY_WRITE) != 0)
+		    && (current->uid != server->m.mounted_uid)) {
 			return -EACCES;
 		}
-		
-		if ((result = verify_area(VERIFY_WRITE, (char *)arg,
-					  sizeof(info))) != 0)
-		{
+		if ((result = verify_area(VERIFY_WRITE, (char *) arg,
+					  sizeof(info))) != 0) {
 			return result;
 		}
+		copy_from_user(&info, (struct ncp_fs_info *) arg,
+			       sizeof(info));
 
-		copy_from_user(&info, (struct ncp_fs_info *)arg,
-			      sizeof(info));
-
-		if (info.version != NCP_GET_FS_INFO_VERSION)
-		{
+		if (info.version != NCP_GET_FS_INFO_VERSION) {
 			DPRINTK("info.version invalid: %d\n", info.version);
 			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;
+		/* TODO: 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;
+		info.directory_id = NCP_ISTRUCT(inode)->DosDirNum;
 
-		copy_to_user((struct ncp_fs_info *)arg, &info, sizeof(info));
-		return 0;		
+		copy_to_user((struct ncp_fs_info *) arg, &info, sizeof(info));
+		return 0;
 
-        case NCP_IOC_GETMOUNTUID:
+	case NCP_IOC_GETMOUNTUID:
 
-		if (   (permission(inode, MAY_READ) != 0)
-		    && (current->uid != server->m.mounted_uid))
-		{
+		if ((permission(inode, MAY_READ) != 0)
+		    && (current->uid != server->m.mounted_uid)) {
 			return -EACCES;
 		}
-		
-                if ((result = verify_area(VERIFY_WRITE, (uid_t*) arg,
-                                          sizeof(uid_t))) != 0)
-		{
-                        return result;
-                }
-                put_user(server->m.mounted_uid, (uid_t *) arg);
-                return 0;
+		if ((result = verify_area(VERIFY_WRITE, (uid_t *) arg,
+					  sizeof(uid_t))) != 0) {
+			return result;
+		}
+		put_user(server->m.mounted_uid, (uid_t *) arg);
+		return 0;
 
 	default:
 		return -EINVAL;
 	}
-	
+
 	return -EINVAL;
 }
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/mmap.c linux/fs/ncpfs/mmap.c
--- v2.1.30/linux/fs/ncpfs/mmap.c	Mon Oct 28 04:29:26 1996
+++ linux/fs/ncpfs/mmap.c	Fri Mar 28 10:42:22 1997
@@ -23,17 +23,16 @@
 
 static inline int min(int a, int b)
 {
-	return a<b ? a : b;
+	return a < b ? a : b;
 }
 
 /*
  * Fill in the supplied page for mmap
  */
-static unsigned long 
-ncp_file_mmap_nopage(struct vm_area_struct * area,
-		     unsigned long address, int no_share)
+static unsigned long ncp_file_mmap_nopage(struct vm_area_struct *area,
+				     unsigned long address, int no_share)
 {
-	struct inode * inode = area->vm_inode;
+	struct inode *inode = area->vm_inode;
 	unsigned long page;
 	unsigned int clear;
 	unsigned long tmp;
@@ -48,37 +47,28 @@
 	pos = address - area->vm_start + area->vm_offset;
 
 	clear = 0;
-	if (address + PAGE_SIZE > area->vm_end)
-	{
+	if (address + PAGE_SIZE > area->vm_end) {
 		clear = address + PAGE_SIZE - area->vm_end;
 	}
-
-        /* what we can read in one go */
+	/* what we can read in one go */
 	bufsize = NCP_SERVER(inode)->buffer_size;
 
 	fs = get_fs();
 	set_fs(get_ds());
 
-        if (ncp_make_open(inode, O_RDONLY) < 0)
-	{
-                clear = PAGE_SIZE;
-        }
-        else
-        {
+	if (ncp_make_open(inode, O_RDONLY) < 0) {
+		clear = PAGE_SIZE;
+	} else {
 		int already_read = 0;
 		int count = PAGE_SIZE - clear;
 		int to_read;
 
-		while (already_read < count)
-		{
+		while (already_read < count) {
 			int read_this_time;
 
-			if ((pos % bufsize) != 0)
-			{
+			if ((pos % bufsize) != 0) {
 				to_read = bufsize - (pos % bufsize);
-			}
-			else
-			{
+			} else {
 				to_read = bufsize;
 			}
 
@@ -87,33 +77,31 @@
 			if (ncp_read(NCP_SERVER(inode),
 				     NCP_FINFO(inode)->file_handle,
 				     pos, to_read,
-				     (char *)(page + already_read),
-				     &read_this_time) != 0)
-			{
-			       read_this_time = 0;
+				     (char *) (page + already_read),
+				     &read_this_time) != 0) {
+				read_this_time = 0;
 			}
-
 			pos += read_this_time;
 			already_read += read_this_time;
 
-			if (read_this_time < to_read)
-			{
+			if (read_this_time < to_read) {
 				break;
 			}
 		}
 
-        }
+	}
 
 	set_fs(fs);
 
 	tmp = page + PAGE_SIZE;
 	while (clear--) {
-		*(char *)--tmp = 0;
+		*(char *) --tmp = 0;
 	}
 	return page;
 }
 
-struct vm_operations_struct ncp_file_mmap = {
+struct vm_operations_struct ncp_file_mmap =
+{
 	NULL,			/* open */
 	NULL,			/* close */
 	NULL,			/* unmap */
@@ -128,18 +116,15 @@
 
 
 /* This is used for a general mmap of a ncp file */
-int
-ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
+int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma)
 {
-        DPRINTK("ncp_mmap: called\n");
+	DPRINTK("ncp_mmap: called\n");
 
-	if (!ncp_conn_valid(NCP_SERVER(inode)))
-	{
+	if (!ncp_conn_valid(NCP_SERVER(inode))) {
 		return -EIO;
 	}
-
-        /* only PAGE_COW or read-only supported now */
-	if (vma->vm_flags & VM_SHARED)	
+	/* only PAGE_COW or read-only supported now */
+	if (vma->vm_flags & VM_SHARED)
 		return -EINVAL;
 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
 		return -EACCES;
@@ -147,7 +132,6 @@
 		inode->i_atime = CURRENT_TIME;
 		inode->i_dirt = 1;
 	}
-
 	vma->vm_inode = inode;
 	inode->i_count++;
 	vma->vm_ops = &ncp_file_mmap;
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
--- v2.1.30/linux/fs/ncpfs/ncplib_kernel.c	Mon Dec 30 02:03:22 1996
+++ linux/fs/ncpfs/ncplib_kernel.c	Fri Mar 28 10:42:22 1997
@@ -8,53 +8,43 @@
 
 #include "ncplib_kernel.h"
 
-typedef __u8  byte;
-typedef __u16 word;
-typedef __u32 dword;
-
 static inline int min(int a, int b)
 {
-	return a<b ? a : b;
+	return a < b ? a : b;
 }
 
-static void
-assert_server_locked(struct ncp_server *server)
+static void assert_server_locked(struct ncp_server *server)
 {
-	if (server->lock == 0)
-	{
+	if (server->lock == 0) {
 		DPRINTK("ncpfs: server not locked!\n");
 	}
 }
 
-static void
-ncp_add_byte(struct ncp_server *server, byte x)
+static void ncp_add_byte(struct ncp_server *server, __u8 x)
 {
 	assert_server_locked(server);
-	*(byte *)(&(server->packet[server->current_size])) = x;
+	*(__u8 *) (&(server->packet[server->current_size])) = x;
 	server->current_size += 1;
 	return;
 }
 
-static void
-ncp_add_word(struct ncp_server *server, word x)
+static void ncp_add_word(struct ncp_server *server, __u16 x)
 {
 	assert_server_locked(server);
-	put_unaligned(x, (word *)(&(server->packet[server->current_size])));
+	put_unaligned(x, (__u16 *) (&(server->packet[server->current_size])));
 	server->current_size += 2;
 	return;
 }
 
-static void
-ncp_add_dword(struct ncp_server *server, dword x)
+static void ncp_add_dword(struct ncp_server *server, __u32 x)
 {
 	assert_server_locked(server);
-	put_unaligned(x, (dword *)(&(server->packet[server->current_size])));
+	put_unaligned(x, (__u32 *) (&(server->packet[server->current_size])));
 	server->current_size += 4;
 	return;
 }
 
-static void
-ncp_add_mem(struct ncp_server *server, const void *source, int size)
+static void ncp_add_mem(struct ncp_server *server, const void *source, int size)
 {
 	assert_server_locked(server);
 	memcpy(&(server->packet[server->current_size]), source, size);
@@ -62,8 +52,7 @@
 	return;
 }
 
-static void
-ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size)
+static void ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size)
 {
 	assert_server_locked(server);
 	copy_from_user(&(server->packet[server->current_size]), source, size);
@@ -71,13 +60,11 @@
 	return;
 }
 
-static void
-ncp_add_pstring(struct ncp_server *server, const char *s)
+static void ncp_add_pstring(struct ncp_server *server, const char *s)
 {
 	int len = strlen(s);
 	assert_server_locked(server);
-	if (len > 255)
-	{
+	if (len > 255) {
 		DPRINTK("ncpfs: string too long: %s\n", s);
 		len = 255;
 	}
@@ -86,8 +73,7 @@
 	return;
 }
 
-static void
-ncp_init_request(struct ncp_server *server)
+static void ncp_init_request(struct ncp_server *server)
 {
 	ncp_lock_server(server);
 
@@ -95,11 +81,10 @@
 	server->has_subfunction = 0;
 }
 
-static void
-ncp_init_request_s(struct ncp_server *server, int subfunction)
+static void ncp_init_request_s(struct ncp_server *server, int subfunction)
 {
 	ncp_init_request(server);
-	ncp_add_word(server, 0); /* preliminary size */
+	ncp_add_word(server, 0);	/* preliminary size */
 
 	ncp_add_byte(server, subfunction);
 
@@ -107,53 +92,49 @@
 }
 
 static char *
-ncp_reply_data(struct ncp_server *server, int offset)
+ ncp_reply_data(struct ncp_server *server, int offset)
 {
 	return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
 }
 
-static byte
-ncp_reply_byte(struct ncp_server *server, int offset)
+static __u8
+ ncp_reply_byte(struct ncp_server *server, int offset)
 {
-	return *(byte *)(ncp_reply_data(server, offset));
+	return get_unaligned((__u8 *) ncp_reply_data(server, offset));
 }
 
-static word
-ncp_reply_word(struct ncp_server *server, int offset)
+static __u16
+ ncp_reply_word(struct ncp_server *server, int offset)
 {
-	return *(word *)(ncp_reply_data(server, offset));
+	return get_unaligned((__u16 *) ncp_reply_data(server, offset));
 }
 
-static dword
-ncp_reply_dword(struct ncp_server *server, int offset)
+static __u32
+ ncp_reply_dword(struct ncp_server *server, int offset)
 {
-	return *(dword *)(ncp_reply_data(server, offset));
+	return get_unaligned((__u32 *) ncp_reply_data(server, offset));
 }
 
-int
-ncp_negotiate_buffersize(struct ncp_server *server,
-			 int size, int *target)
+int ncp_negotiate_buffersize(struct ncp_server *server,
+			     int size, int *target)
 {
 	int result;
 
 	ncp_init_request(server);
 	ncp_add_word(server, htons(size));
-	
-	if ((result = ncp_request(server, 33)) != 0)
-	{
+
+	if ((result = ncp_request(server, 33)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
-	*target =min(ntohs(ncp_reply_word(server, 0)), size);
+	*target = min(ntohs(ncp_reply_word(server, 0)), size);
 
 	ncp_unlock_server(server);
 	return 0;
 }
 
-int
-ncp_get_volume_info_with_number(struct ncp_server *server, int n,
-				struct ncp_volume_info *target)
+int ncp_get_volume_info_with_number(struct ncp_server *server, int n,
+				    struct ncp_volume_info *target)
 {
 	int result;
 	int len;
@@ -161,14 +142,12 @@
 	ncp_init_request_s(server, 44);
 	ncp_add_byte(server, n);
 
-	if ((result = ncp_request(server, 22)) != 0)
-	{
+	if ((result = ncp_request(server, 22)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	target->total_blocks = ncp_reply_dword(server, 0);
-	target->free_blocks  = ncp_reply_dword(server, 4);
+	target->free_blocks = ncp_reply_dword(server, 4);
 	target->purgeable_blocks = ncp_reply_dword(server, 8);
 	target->not_yet_purgeable_blocks = ncp_reply_dword(server, 12);
 	target->total_dir_entries = ncp_reply_dword(server, 16);
@@ -178,20 +157,17 @@
 	memset(&(target->volume_name), 0, sizeof(target->volume_name));
 
 	len = ncp_reply_byte(server, 29);
-	if (len > NCP_VOLNAME_LEN)
-	{
+	if (len > NCP_VOLNAME_LEN) {
 		DPRINTK("ncpfs: volume name too long: %d\n", len);
 		ncp_unlock_server(server);
 		return -EIO;
 	}
-
 	memcpy(&(target->volume_name), ncp_reply_data(server, 30), len);
 	ncp_unlock_server(server);
 	return 0;
 }
 
-int
-ncp_close_file(struct ncp_server *server, const char *file_id)
+int ncp_close_file(struct ncp_server *server, const char *file_id)
 {
 	int result;
 
@@ -204,35 +180,27 @@
 	return result;
 }
 
-static void
-ncp_add_handle_path(struct ncp_server *server,
-		    __u8 vol_num,
-		    __u32 dir_base, int have_dir_base,
-		    char *path)
+static void ncp_add_handle_path(struct ncp_server *server,
+				__u8 vol_num,
+				__u32 dir_base, int have_dir_base,
+				char *path)
 {
 	ncp_add_byte(server, vol_num);
 	ncp_add_dword(server, dir_base);
-	if (have_dir_base != 0)
-	{
-		ncp_add_byte(server, 1); /* dir_base */
-	}
-	else
-	{
-		ncp_add_byte(server, 0xff); /* no handle */
-	}
-	if (path != NULL)
-	{
-		ncp_add_byte(server, 1); /* 1 component */
-		ncp_add_pstring(server, path);
+	if (have_dir_base != 0) {
+		ncp_add_byte(server, 1);	/* dir_base */
+	} else {
+		ncp_add_byte(server, 0xff);	/* no handle */
 	}
-	else
-	{
+	if (path != NULL) {
+		ncp_add_byte(server, 1);	/* 1 component */
+		ncp_add_pstring(server, path);
+	} else {
 		ncp_add_byte(server, 0);
 	}
 }
 
-static void
-ncp_extract_file_info(void *structure, struct nw_info_struct *target)
+static void ncp_extract_file_info(void *structure, struct nw_info_struct *target)
 {
 	__u8 *name_len;
 	const int info_struct_size = sizeof(struct nw_info_struct) - 257;
@@ -240,70 +208,60 @@
 	memcpy(target, structure, info_struct_size);
 	name_len = structure + info_struct_size;
 	target->nameLen = *name_len;
-	strncpy(target->entryName, name_len+1, *name_len);
+	strncpy(target->entryName, name_len + 1, *name_len);
 	target->entryName[*name_len] = '\0';
 	return;
 }
 
-int
-ncp_obtain_info(struct ncp_server *server,
-		__u8 vol_num, __u32 dir_base,
-		char *path, /* At most 1 component */
-		struct nw_info_struct *target)
+int ncp_obtain_info(struct ncp_server *server,
+		    __u8 vol_num, __u32 dir_base,
+		    char *path,	/* At most 1 component */
+		    struct nw_info_struct *target)
 {
 	int result;
 
-	if (target == NULL)
-	{
+	if (target == NULL) {
 		return -EINVAL;
 	}
-
 	ncp_init_request(server);
-	ncp_add_byte(server, 6); /* subfunction */
+	ncp_add_byte(server, 6);	/* subfunction */
 	ncp_add_byte(server, server->name_space[vol_num]);
 	ncp_add_byte(server, server->name_space[vol_num]);
-	ncp_add_word(server, htons(0xff00)); /* get all */
+	ncp_add_word(server, htons(0xff00));	/* get all */
 	ncp_add_dword(server, RIM_ALL);
 	ncp_add_handle_path(server, vol_num, dir_base, 1, path);
 
-	if ((result = ncp_request(server, 87)) != 0)
-	{
+	if ((result = ncp_request(server, 87)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	ncp_extract_file_info(ncp_reply_data(server, 0), target);
 	ncp_unlock_server(server);
 	return 0;
 }
 
-static inline int
-ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
+static inline int ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
 {
 	int result;
 	__u8 *namespace;
 	__u16 no_namespaces;
 
 	ncp_init_request(server);
-	ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
+	ncp_add_byte(server, 24);	/* Subfunction: Get Name Spaces Loaded */
 	ncp_add_word(server, 0);
 	ncp_add_byte(server, volume);
 
-	if ((result = ncp_request(server, 87)) != 0)
-	{
+	if ((result = ncp_request(server, 87)) != 0) {
 		ncp_unlock_server(server);
 		return 0;
 	}
-
 	no_namespaces = ncp_reply_word(server, 0);
 	namespace = ncp_reply_data(server, 2);
 
-	while (no_namespaces > 0)
-	{
-		DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
+	while (no_namespaces > 0) {
+		DPRINTK("get_namespaces: found %d on %d\n", *namespace, volume);
 
-		if (*namespace == 4)
-		{
+		if (*namespace == 4) {
 			DPRINTK("get_namespaces: found OS2\n");
 			ncp_unlock_server(server);
 			return 1;
@@ -315,10 +273,9 @@
 	return 0;
 }
 
-int
-ncp_lookup_volume(struct ncp_server *server,
-		  char *volname,
-		  struct nw_info_struct *target)
+int ncp_lookup_volume(struct ncp_server *server,
+		      char *volname,
+		      struct nw_info_struct *target)
 {
 	int result;
 	int volnum;
@@ -326,30 +283,28 @@
 	DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
 
 	ncp_init_request(server);
-	ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
-	ncp_add_byte(server, 0); /* DOS namespace */
-	ncp_add_byte(server, 0); /* reserved */
-	ncp_add_byte(server, 0); /* reserved */
-	ncp_add_byte(server, 0); /* reserved */
-
-	ncp_add_byte(server, 0); /* faked volume number */
-	ncp_add_dword(server, 0); /* faked dir_base */
-	ncp_add_byte(server, 0xff); /* Don't have a dir_base */
-	ncp_add_byte(server, 1); /* 1 path component */
+	ncp_add_byte(server, 22);	/* Subfunction: Generate dir handle */
+	ncp_add_byte(server, 0);	/* DOS namespace */
+	ncp_add_byte(server, 0);	/* reserved */
+	ncp_add_byte(server, 0);	/* reserved */
+	ncp_add_byte(server, 0);	/* reserved */
+
+	ncp_add_byte(server, 0);	/* faked volume number */
+	ncp_add_dword(server, 0);	/* faked dir_base */
+	ncp_add_byte(server, 0xff);	/* Don't have a dir_base */
+	ncp_add_byte(server, 1);	/* 1 path component */
 	ncp_add_pstring(server, volname);
 
-	if ((result = ncp_request(server, 87)) != 0)
-	{
+	if ((result = ncp_request(server, 87)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	memset(target, 0, sizeof(*target));
 	target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
 	target->volNumber = volnum = ncp_reply_byte(server, 8);
 	ncp_unlock_server(server);
 
-	server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
+	server->name_space[volnum] = ncp_has_os2_namespace(server, volnum) ? 4 : 0;
 
 	DPRINTK("lookup_vol: namespace[%d] = %d\n",
 		volnum, server->name_space[volnum]);
@@ -360,19 +315,18 @@
 	return 0;
 }
 
-int
-ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
-				   struct nw_info_struct *file,
-				   __u32 info_mask,
-				   struct nw_modify_dos_info *info)
+int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
+				       struct nw_info_struct *file,
+				       __u32 info_mask,
+				       struct nw_modify_dos_info *info)
 {
 	int result;
 
 	ncp_init_request(server);
-	ncp_add_byte(server, 7); /* subfunction */
+	ncp_add_byte(server, 7);	/* subfunction */
 	ncp_add_byte(server, server->name_space[file->volNumber]);
-	ncp_add_byte(server, 0); /* reserved */
-	ncp_add_word(server, htons(0x0680)); /* search attribs: all */
+	ncp_add_byte(server, 0);	/* reserved */
+	ncp_add_word(server, htons(0x0680));	/* search attribs: all */
 
 	ncp_add_dword(server, info_mask);
 	ncp_add_mem(server, info, sizeof(*info));
@@ -384,55 +338,50 @@
 	return result;
 }
 
-int
-ncp_del_file_or_subdir(struct ncp_server *server,
-		       struct nw_info_struct *dir, char *name)
+int ncp_del_file_or_subdir(struct ncp_server *server,
+			   struct nw_info_struct *dir, char *name)
 {
 	int result;
 
 	ncp_init_request(server);
-	ncp_add_byte(server, 8); /* subfunction */
+	ncp_add_byte(server, 8);	/* subfunction */
 	ncp_add_byte(server, server->name_space[dir->volNumber]);
-	ncp_add_byte(server, 0); /* reserved */
-	ncp_add_word(server, ntohs(0x0680)); /* search attribs: all */
+	ncp_add_byte(server, 0);	/* reserved */
+	ncp_add_word(server, ntohs(0x0680));	/* search attribs: all */
 	ncp_add_handle_path(server, dir->volNumber,
 			    dir->dirEntNum, 1, name);
-	
+
 	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
 	return result;
 }
 
-static inline void
-ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
+static inline void ConvertToNWfromDWORD(__u32 sfd, __u8 ret[6])
 {
-    __u16 *dest = (__u16 *) ret;
-    memcpy (ret + 2, &sfd, 4);
-    dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(1)));
-    return;
+	__u16 *dest = (__u16 *) ret;
+	memcpy(ret + 2, &sfd, 4);
+	dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(1)));
+	return;
 }
 
 /* If both dir and name are NULL, then in target there's already a
    looked-up entry that wants to be opened. */
-int
-ncp_open_create_file_or_subdir(struct ncp_server *server,
-			       struct nw_info_struct *dir, char *name,
-			       int open_create_mode,
-			       __u32 create_attributes,
-			       int desired_acc_rights,
-			       struct nw_file_info *target)
+int ncp_open_create_file_or_subdir(struct ncp_server *server,
+				   struct nw_info_struct *dir, char *name,
+				   int open_create_mode,
+				   __u32 create_attributes,
+				   int desired_acc_rights,
+				   struct nw_file_info *target)
 {
 	int result;
 	__u16 search_attribs = ntohs(0x0600);
 	__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
 
-	if ((create_attributes & aDIR) != 0)
-	{
-		search_attribs |= ntohs(0x0080);	
+	if ((create_attributes & aDIR) != 0) {
+		search_attribs |= ntohs(0x0080);
 	}
-
 	ncp_init_request(server);
-	ncp_add_byte(server, 1); /* subfunction */
+	ncp_add_byte(server, 1);	/* subfunction */
 	ncp_add_byte(server, server->name_space[volume]);
 	ncp_add_byte(server, open_create_mode);
 	ncp_add_word(server, search_attribs);
@@ -442,89 +391,76 @@
 	   for directories */
 	ncp_add_word(server, desired_acc_rights);
 
-	if (dir != NULL)
-	{
+	if (dir != NULL) {
 		ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
-	}
-	else
-	{
+	} else {
 		ncp_add_handle_path(server, volume, target->i.dirEntNum,
 				    1, NULL);
-	}	
+	}
 
-	if ((result = ncp_request(server, 87)) != 0)
-	{
+	if ((result = ncp_request(server, 87)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	target->opened = 1;
 	target->server_file_handle = ncp_reply_dword(server, 0);
 	target->open_create_action = ncp_reply_byte(server, 4);
 
-	if (dir != NULL)
-	{
+	if (dir != NULL) {
 		/* in target there's a new finfo to fill */
 		ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
 	}
-
 	ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
 
 	ncp_unlock_server(server);
 	return 0;
 }
-	
 
-int
-ncp_initialize_search(struct ncp_server *server,
-		      struct nw_info_struct *dir,
-		      struct nw_search_sequence *target)
+
+int ncp_initialize_search(struct ncp_server *server,
+			  struct nw_info_struct *dir,
+			  struct nw_search_sequence *target)
 {
 	int result;
 
 	ncp_init_request(server);
-	ncp_add_byte(server, 2); /* subfunction */
+	ncp_add_byte(server, 2);	/* subfunction */
 	ncp_add_byte(server, server->name_space[dir->volNumber]);
-	ncp_add_byte(server, 0); /* reserved */
+	ncp_add_byte(server, 0);	/* reserved */
 	ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
-	
-	if ((result = ncp_request(server, 87)) != 0)
-	{
+
+	if ((result = ncp_request(server, 87)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
 
 	ncp_unlock_server(server);
 	return 0;
 }
-	
+
 /* Search for everything */
-int
-ncp_search_for_file_or_subdir(struct ncp_server *server,
-			      struct nw_search_sequence *seq,
-			      struct nw_info_struct *target)
+int ncp_search_for_file_or_subdir(struct ncp_server *server,
+				  struct nw_search_sequence *seq,
+				  struct nw_info_struct *target)
 {
 	int result;
 
 	ncp_init_request(server);
-	ncp_add_byte(server, 3); /* subfunction */
+	ncp_add_byte(server, 3);	/* subfunction */
 	ncp_add_byte(server, server->name_space[seq->volNumber]);
-	ncp_add_byte(server, 0); /* data stream (???) */
-	ncp_add_word(server, 0xffff); /* Search attribs */
-	ncp_add_dword(server, RIM_ALL);	/* return info mask */
+	ncp_add_byte(server, 0);	/* data stream (???) */
+	ncp_add_word(server, 0xffff);	/* Search attribs */
+	ncp_add_dword(server, RIM_ALL);		/* return info mask */
 	ncp_add_mem(server, seq, 9);
-	ncp_add_byte(server, 2); /* 2 byte pattern */
-	ncp_add_byte(server, 0xff); /* following is a wildcard */
+	ncp_add_byte(server, 2);	/* 2 byte pattern */
+	ncp_add_byte(server, 0xff);	/* following is a wildcard */
 	ncp_add_byte(server, '*');
-	
-	if ((result = ncp_request(server, 87)) != 0)
-	{
+
+	if ((result = ncp_request(server, 87)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
 	ncp_extract_file_info(ncp_reply_data(server, 10), target);
 
@@ -532,34 +468,33 @@
 	return 0;
 }
 
-int
-ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
-			      struct nw_info_struct *old_dir, char *old_name,
-			      struct nw_info_struct *new_dir, char *new_name)
+int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
+			  struct nw_info_struct *old_dir, char *old_name,
+			  struct nw_info_struct *new_dir, char *new_name)
 {
 	int result;
 
-	if (   (old_dir == NULL) || (old_name == NULL)
+	if ((old_dir == NULL) || (old_name == NULL)
 	    || (new_dir == NULL) || (new_name == NULL))
 		return -EINVAL;
-	
+
 	ncp_init_request(server);
-	ncp_add_byte(server, 4); /* subfunction */
+	ncp_add_byte(server, 4);	/* subfunction */
 	ncp_add_byte(server, server->name_space[old_dir->volNumber]);
-	ncp_add_byte(server, 1); /* rename flag */
-	ncp_add_word(server, ntohs (0x0680)); /* search attributes */
+	ncp_add_byte(server, 1);	/* rename flag */
+	ncp_add_word(server, ntohs(0x0680));	/* search attributes */
 
 	/* source Handle Path */
 	ncp_add_byte(server, old_dir->volNumber);
 	ncp_add_dword(server, old_dir->dirEntNum);
 	ncp_add_byte(server, 1);
-	ncp_add_byte(server, 1); /* 1 source component */
+	ncp_add_byte(server, 1);	/* 1 source component */
 
 	/* dest Handle Path */
 	ncp_add_byte(server, new_dir->volNumber);
 	ncp_add_dword(server, new_dir->dirEntNum);
 	ncp_add_byte(server, 1);
-	ncp_add_byte(server, 1); /* 1 destination component */
+	ncp_add_byte(server, 1);	/* 1 destination component */
 
 	/* source path string */
 	ncp_add_pstring(server, old_name);
@@ -570,13 +505,12 @@
 	ncp_unlock_server(server);
 	return result;
 }
-	
+
 
 /* We have to transfer to/from user space */
-int
-ncp_read(struct ncp_server *server, const char *file_id,
-	 __u32 offset, __u16 to_read,
-	 char *target, int *bytes_read)
+int ncp_read(struct ncp_server *server, const char *file_id,
+	     __u32 offset, __u16 to_read,
+	     char *target, int *bytes_read)
 {
 	int result;
 
@@ -586,24 +520,21 @@
 	ncp_add_dword(server, htonl(offset));
 	ncp_add_word(server, htons(to_read));
 
-	if ((result = ncp_request(server, 72)) != 0)
-	{
+	if ((result = ncp_request(server, 72)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	*bytes_read = ntohs(ncp_reply_word(server, 0));
 
-	copy_to_user(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read);
+	copy_to_user(target, ncp_reply_data(server, 2 + (offset & 1)), *bytes_read);
 
 	ncp_unlock_server(server);
 	return 0;
 }
 
-int
-ncp_write(struct ncp_server *server, const char *file_id,
-	  __u32 offset, __u16 to_write,
-	  const char *source, int *bytes_written)
+int ncp_write(struct ncp_server *server, const char *file_id,
+	      __u32 offset, __u16 to_write,
+	      const char *source, int *bytes_written)
 {
 	int result;
 
@@ -614,15 +545,12 @@
 	ncp_add_word(server, htons(to_write));
 	ncp_add_mem_fromfs(server, source, to_write);
 
-	if ((result = ncp_request(server, 73)) != 0)
-	{
+	if ((result = ncp_request(server, 73)) != 0) {
 		ncp_unlock_server(server);
 		return result;
 	}
-
 	*bytes_written = to_write;
 
 	ncp_unlock_server(server);
 	return 0;
 }
-
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/ncplib_kernel.h linux/fs/ncpfs/ncplib_kernel.h
--- v2.1.30/linux/fs/ncpfs/ncplib_kernel.h	Mon Dec 30 02:03:22 1996
+++ linux/fs/ncpfs/ncplib_kernel.h	Fri Mar 28 10:42:22 1997
@@ -29,89 +29,11 @@
 ncp_negotiate_buffersize(struct ncp_server *server, int size,
 			 int *target);
 int
-ncp_get_encryption_key(struct ncp_server *server,
-		       char *target);
-int
-ncp_get_bindery_object_id(struct ncp_server *server,
-			  int object_type, char *object_name,
-			  struct ncp_bindery_object *target);
-int
-ncp_login_encrypted(struct ncp_server *server,
-		    struct ncp_bindery_object *object,
-		    unsigned char *key,
-		    unsigned char *passwd);
-int
-ncp_login_user(struct ncp_server *server,
-	       unsigned char *username,
-	       unsigned char *password);
-int
 ncp_get_volume_info_with_number(struct ncp_server *server, int n,
 				struct ncp_volume_info *target);
 
 int
-ncp_get_volume_number(struct ncp_server *server, const char *name,
-		      int *target);
-
-int
-ncp_file_search_init(struct ncp_server *server,
-		     int dir_handle, const char *path,
-		     struct ncp_filesearch_info *target);
-
-int
-ncp_file_search_continue(struct ncp_server *server,
-			 struct ncp_filesearch_info *fsinfo,
-			 int attributes, const char *path,
-			 struct ncp_file_info *target);
-
-int
-ncp_get_finfo(struct ncp_server *server,
-	      int dir_handle, const char *path, const char *name,
-	      struct ncp_file_info *target);
-
-int
-ncp_open_file(struct ncp_server *server,
-	      int dir_handle, const char *path,
-	      int attr, int access,
-	      struct ncp_file_info *target);
-int
 ncp_close_file(struct ncp_server *server, const char *file_id);
-
-int
-ncp_create_newfile(struct ncp_server *server,
-		   int dir_handle, const char *path,
-		   int attr,
-		   struct ncp_file_info *target);
-
-int
-ncp_create_file(struct ncp_server *server,
-		int dir_handle, const char *path,
-		int attr,
-		struct ncp_file_info *target);
-
-int
-ncp_erase_file(struct ncp_server *server,
-	       int dir_handle, const char *path,
-	       int attr);
-
-int
-ncp_rename_file(struct ncp_server *server,
-		int old_handle, const char *old_path,
-		int attr,
-		int new_handle, const char *new_path);
-
-int
-ncp_create_directory(struct ncp_server *server,
-		     int dir_handle, const char *path,
-		     int inherit_mask);
-
-int
-ncp_delete_directory(struct ncp_server *server,
-		     int dir_handle, const char *path);
-
-int
-ncp_rename_directory(struct ncp_server *server,
-		     int dir_handle,
-		     const char *old_path, const char *new_path);
 
 int
 ncp_read(struct ncp_server *server, const char *file_id,
diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c
--- v2.1.30/linux/fs/ncpfs/sock.c	Sun Jan 26 02:07:44 1997
+++ linux/fs/ncpfs/sock.c	Fri Mar 28 10:42:22 1997
@@ -25,315 +25,59 @@
 #include <linux/ncp_fs.h>
 #include <linux/ncp_fs_sb.h>
 #include <net/sock.h>
+#include <linux/poll.h>
 
-
-#define _S(nr) (1<<((nr)-1))
-static int _recvfrom(struct socket *sock, unsigned char *ubuf,
-		     int size, int noblock, unsigned flags,
-		     struct sockaddr_ipx *sa)
+static int _recv(struct socket *sock, unsigned char *ubuf, int size,
+		 unsigned flags)
 {
-        struct iovec iov;
-        struct msghdr msg;
+	struct iovec iov;
+	struct msghdr msg;
 	struct scm_cookie scm;
 
 	memset(&scm, 0, sizeof(scm));
 
-        iov.iov_base = ubuf;
-        iov.iov_len  = size;
-
-        msg.msg_name      = (void *)sa;
-        msg.msg_namelen   = 0;
-        if (sa)
-                msg.msg_namelen = sizeof(struct sockaddr_ipx);
-        msg.msg_control = NULL;
-        msg.msg_iov       = &iov;
-        msg.msg_iovlen    = 1;
-	if (noblock) {
-		flags |= MSG_DONTWAIT;
-	}
+	iov.iov_base = ubuf;
+	iov.iov_len = size;
 
-        return sock->ops->recvmsg(sock, &msg, size, flags, &scm);
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+	return sock->ops->recvmsg(sock, &msg, size, flags, &scm);
 }
 
-static int _sendto(struct socket *sock, const void *buff,
-		   int len, int noblock, unsigned flags,
-		   struct sockaddr_ipx *sa)
-
+static int _send(struct socket *sock, const void *buff, int len)
 {
-        struct iovec iov;
-        struct msghdr msg;
+	struct iovec iov;
+	struct msghdr msg;
 	struct scm_cookie scm;
 	int err;
 
-        iov.iov_base = (void *)buff;
-        iov.iov_len  = len;
-
-        msg.msg_name      = (void *)sa;
-        msg.msg_namelen   = sizeof(struct sockaddr_ipx);
-        msg.msg_control = NULL;
-        msg.msg_iov       = &iov;
-        msg.msg_iovlen    = 1;
+	iov.iov_base = (void *) buff;
+	iov.iov_len = len;
 
-	if (noblock) {
-		flags |= MSG_DONTWAIT;
-	}
-
-	msg.msg_flags = flags;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+	msg.msg_flags = 0;
 
 	err = scm_send(sock, &msg, &scm);
-	if (err < 0)
+	if (err < 0) {
 		return err;
-        err = sock->ops->sendmsg(sock, &msg, len, &scm);
+	}
+	err = sock->ops->sendmsg(sock, &msg, len, &scm);
 	scm_destroy(&scm);
 	return err;
 }
 
-
-static void
-ncp_wdog_data_ready(struct sock *sk, int len)
-{
-	struct socket *sock = sk->socket;
-
-	if (!sk->dead)
-	{
-		unsigned char packet_buf[2];
-		struct sockaddr_ipx sender;
-		int result;
-		unsigned short fs;
-
-		fs = get_fs();
-		set_fs(get_ds());
-
-		result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
-				   &sender);
-
-		if (   (result != 2)
-		    || (packet_buf[1] != '?')
-		    /* How to check connection number here? */
-		    )
-		{
-			printk("ncpfs: got strange packet on watchdog "
-			       "socket\n");
-		}
-		else
-		{
-			int result;
-			DDPRINTK("ncpfs: got watchdog from:\n");
-			DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
-				" conn:%02X,type:%c\n",
-				htonl(sender.sipx_network),
-				sender.sipx_node[0], sender.sipx_node[1],
-				sender.sipx_node[2], sender.sipx_node[3],
-				sender.sipx_node[4], sender.sipx_node[5],
-				ntohs(sender.sipx_port),
-				packet_buf[0], packet_buf[1]);
-
-			packet_buf[1] = 'Y';
-			result = _sendto(sock, (void *)packet_buf, 2, 1, 0,
-					 &sender);
-			DDPRINTK("send result: %d\n", result);
-		}
-		set_fs(fs);
-	}
-}
-
-int
-ncp_catch_watchdog(struct ncp_server *server)
-{
-        struct file   *file;
-        struct inode  *inode;
-        struct socket *sock;
-        struct sock   *sk;
-
-        if (   (server == NULL)
-            || ((file  = server->wdog_filp) == NULL)
-            || ((inode = file->f_inode) == NULL)
-            || (!S_ISSOCK(inode->i_mode)))
-	{
-                printk("ncp_catch_watchdog: did not get valid server!\n");
-                server->data_ready = NULL;
-                return -EINVAL;
-        }
-
-        sock = &(inode->u.socket_i);
-
-        if (sock->type != SOCK_DGRAM)
-	{
-                printk("ncp_catch_watchdog: did not get SOCK_DGRAM\n");
-                server->data_ready = NULL;
-                return -EINVAL;
-        }
-
-        sk   = sock->sk;
-
-        if (sk == NULL)
-	{
-                printk("ncp_catch_watchdog: sk == NULL");
-                server->data_ready = NULL;
-                return -EINVAL;
-        }
-
-        DDPRINTK("ncp_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
-                 (unsigned int)(sk->data_ready),
-                 (unsigned int)(server->data_ready));
-
-        if (sk->data_ready == ncp_wdog_data_ready)
-	{
-                printk("ncp_catch_watchdog: already done\n");
-                return -EINVAL;
-        }
-
-        server->data_ready = sk->data_ready;
-        sk->data_ready = ncp_wdog_data_ready;
-	sk->allocation = GFP_ATOMIC;
-        return 0;
-}
-                
-int
-ncp_dont_catch_watchdog(struct ncp_server *server)
-{
-        struct file   *file;
-        struct inode  *inode;
-        struct socket *sock;
-        struct sock   *sk;
-
-        if (   (server == NULL)
-            || ((file  = server->wdog_filp) == NULL)
-            || ((inode = file->f_inode) == NULL)
-            || (!S_ISSOCK(inode->i_mode)))
-	{
-                printk("ncp_dont_catch_watchdog: "
-                       "did not get valid server!\n");
-                return -EINVAL;
-        }
-
-        sock = &(inode->u.socket_i);
-
-        if (sock->type != SOCK_DGRAM)
-	{
-                printk("ncp_dont_catch_watchdog: did not get SOCK_DGRAM\n");
-                return -EINVAL;
-        }
-
-        sk = sock->sk;
-
-        if (sk == NULL)
-	{
-                printk("ncp_dont_catch_watchdog: sk == NULL");
-                return -EINVAL;
-        }
-
-        if (server->data_ready == NULL)
-	{
-                printk("ncp_dont_catch_watchdog: "
-                       "server->data_ready == NULL\n");
-                return -EINVAL;
-        }
-
-        if (sk->data_ready != ncp_wdog_data_ready)
-	{
-                printk("ncp_dont_catch_watchdog: "
-                       "sk->data_callback != ncp_data_callback\n");
-                return -EINVAL;
-        }
-
-        DDPRINTK("ncp_dont_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
-                 (unsigned int)(sk->data_ready),
-                 (unsigned int)(server->data_ready));
-
-        sk->data_ready = server->data_ready;
-	sk->allocation = GFP_KERNEL;
-        server->data_ready = NULL;
-        return 0;
-}
-
-static void
-ncp_msg_data_ready(struct sock *sk, int len)
-{
-	struct socket *sock = sk->socket;
-
-	if (!sk->dead)
-	{
-		unsigned char packet_buf[2];
-		struct sockaddr_ipx sender;
-		int result;
-		unsigned short fs;
-
-		fs = get_fs();
-		set_fs(get_ds());
-
-		result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
-				   &sender);
-
-		DPRINTK("ncpfs: got message of size %d from:\n", result);
-		DPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
-			" conn:%02X,type:%c\n",
-			htonl(sender.sipx_network),
-			sender.sipx_node[0], sender.sipx_node[1],
-			sender.sipx_node[2], sender.sipx_node[3],
-			sender.sipx_node[4], sender.sipx_node[5],
-			ntohs(sender.sipx_port),
-			packet_buf[0], packet_buf[1]);
-
-		ncp_trigger_message(sk->protinfo.af_ipx.ncp_server);
-
-		set_fs(fs);
-	}
-}
-
-int
-ncp_catch_message(struct ncp_server *server)
-{
-        struct file   *file;
-        struct inode  *inode;
-        struct socket *sock;
-        struct sock   *sk;
-
-        if (   (server == NULL)
-            || ((file  = server->msg_filp) == NULL)
-            || ((inode = file->f_inode) == NULL)
-            || (!S_ISSOCK(inode->i_mode)))
-	{
-                printk("ncp_catch_message: did not get valid server!\n");
-                return -EINVAL;
-        }
-
-        sock = &(inode->u.socket_i);
-
-        if (sock->type != SOCK_DGRAM)
-	{
-                printk("ncp_catch_message: did not get SOCK_DGRAM\n");
-                return -EINVAL;
-        }
-
-        sk = sock->sk;
-
-        if (sk == NULL)
-	{
-                printk("ncp_catch_message: sk == NULL");
-                return -EINVAL;
-        }
-
-        DDPRINTK("ncp_catch_message: sk->d_r = %x\n",
-                 (unsigned int)(sk->data_ready));
-
-        if (sk->data_ready == ncp_msg_data_ready)
-	{
-                printk("ncp_catch_message: already done\n");
-                return -EINVAL;
-        }
-
-        sk->data_ready = ncp_msg_data_ready;
-	sk->protinfo.af_ipx.ncp_server = server;
-        return 0;
-}
-                
 #define NCP_SLACK_SPACE 1024
 
 #define _S(nr) (1<<((nr)-1))
 
-static int
-do_ncp_rpc_call(struct ncp_server *server, int size)
+static int do_ncp_rpc_call(struct ncp_server *server, int size)
 {
 	struct file *file;
 	struct inode *inode;
@@ -343,29 +87,24 @@
 	char *start = server->packet;
 	poll_table wait_table;
 	struct poll_table_entry entry;
-	int (*select) (struct inode *, poll_table *);
 	int init_timeout, max_timeout;
 	int timeout;
 	int retrans;
 	int major_timeout_seen;
 	int acknowledge_seen;
-	char *server_name;
 	int n;
 	unsigned long old_mask;
 
 	/* We have to check the result, so store the complete header */
 	struct ncp_request_header request =
-		*((struct ncp_request_header *)(server->packet));
-
-	struct ncp_reply_header reply;	
+	*((struct ncp_request_header *) (server->packet));
 
+	struct ncp_reply_header reply;
 
 	file = server->ncp_filp;
 	inode = file->f_inode;
-	select = file->f_op->poll;
 	sock = &inode->u.socket_i;
-	if (!sock)
-	{
+	if (!sock) {
 		printk("ncp_rpc_call: socki_lookup failed\n");
 		return -EBADF;
 	}
@@ -374,61 +113,53 @@
 	retrans = server->m.retry_count;
 	major_timeout_seen = 0;
 	acknowledge_seen = 0;
-	server_name = server->m.server_name;
 	old_mask = current->blocked;
 	current->blocked |= ~(_S(SIGKILL)
 #if 0
-		| _S(SIGSTOP)
+			      | _S(SIGSTOP)
 #endif
-		| ((server->m.flags & NCP_MOUNT_INTR)
-		? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL
-			? _S(SIGINT) : 0)
-		| (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL
-			? _S(SIGQUIT) : 0))
-		: 0));
+			      | ((server->m.flags & NCP_MOUNT_INTR)
+	       ? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL
+		   ? _S(SIGINT) : 0)
+	       | (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL
+		  ? _S(SIGQUIT) : 0))
+				 : 0));
 	fs = get_fs();
 	set_fs(get_ds());
-	for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1)
-	{
+	for (n = 0, timeout = init_timeout;; n++, timeout <<= 1) {
 		DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
-			htonl(server->m.serv_addr.sipx_network),
-			server->m.serv_addr.sipx_node[0],
-			server->m.serv_addr.sipx_node[1],
-			server->m.serv_addr.sipx_node[2],
-			server->m.serv_addr.sipx_node[3],
-			server->m.serv_addr.sipx_node[4],
-			server->m.serv_addr.sipx_node[5],
-			ntohs(server->m.serv_addr.sipx_port));
+			 htonl(server->m.serv_addr.sipx_network),
+			 server->m.serv_addr.sipx_node[0],
+			 server->m.serv_addr.sipx_node[1],
+			 server->m.serv_addr.sipx_node[2],
+			 server->m.serv_addr.sipx_node[3],
+			 server->m.serv_addr.sipx_node[4],
+			 server->m.serv_addr.sipx_node[5],
+			 ntohs(server->m.serv_addr.sipx_port));
 		DDPRINTK("ncpfs: req.typ: %04X, con: %d, "
-			"seq: %d",
-			request.type,
-			(request.conn_high << 8) + request.conn_low,
-			request.sequence);
+			 "seq: %d",
+			 request.type,
+			 (request.conn_high << 8) + request.conn_low,
+			 request.sequence);
 		DDPRINTK(" func: %d\n",
 			 request.function);
 
-		result = _sendto(sock, (void *) start, size, 0, 0,
-				 &(server->m.serv_addr));
-		if (result < 0)
-		{
+		result = _send(sock, (void *) start, size);
+		if (result < 0) {
 			printk("ncp_rpc_call: send error = %d\n", result);
 			break;
 		}
-	re_select:
+	      re_select:
 		wait_table.nr = 0;
 		wait_table.entry = &entry;
 		current->state = TASK_INTERRUPTIBLE;
-		if (!select(inode, &wait_table))
-		{
-			if (timeout > max_timeout)
-			{
+		if (!(file->f_op->poll(file, &wait_table) & POLLIN)) {
+			if (timeout > max_timeout) {
 				/* JEJB/JSP 2/7/94
 				 * This is useful to see if the system is
 				 * hanging */
-				if (acknowledge_seen == 0)
-				{
-					printk("NCP max timeout reached on "
-					       "%s\n", server_name);
+				if (acknowledge_seen == 0) {
+					printk("NCP max timeout\n");
 				}
 				timeout = max_timeout;
 			}
@@ -436,102 +167,87 @@
 			schedule();
 			remove_wait_queue(entry.wait_address, &entry.wait);
 			current->state = TASK_RUNNING;
-			if (current->signal & ~current->blocked)
-			{
+			if (current->signal & ~current->blocked) {
 				current->timeout = 0;
 				result = -ERESTARTSYS;
 				break;
 			}
-			if (!current->timeout)
-			{
+			if (!current->timeout) {
 				if (n < retrans)
 					continue;
-				if (server->m.flags & NCP_MOUNT_SOFT)
-				{
-					printk("NCP server %s not responding, "
-						"timed out\n", server_name);
+				if (server->m.flags & NCP_MOUNT_SOFT) {
+					printk("NCP server not responding\n");
 					result = -EIO;
 					break;
 				}
 				n = 0;
 				timeout = init_timeout;
 				init_timeout <<= 1;
-				if (!major_timeout_seen)
-				{
-					printk("NCP server %s not responding, "
-					       "still trying\n", server_name);
+				if (!major_timeout_seen) {
+					printk("NCP server not responding\n");
 				}
 				major_timeout_seen = 1;
 				continue;
-			}
-			else
+			} else
 				current->timeout = 0;
-		}
-		else if (wait_table.nr)
+		} else if (wait_table.nr)
 			remove_wait_queue(entry.wait_address, &entry.wait);
 		current->state = TASK_RUNNING;
 
 		/* Get the header from the next packet using a peek, so keep it
 		 * on the recv queue.  If it is wrong, it will be some reply
 		 * we don't now need, so discard it */
-		result = _recvfrom(sock, (void *)&reply,
-				   sizeof(reply), 1, MSG_PEEK, NULL);
-		if (result < 0)
-		{
-			if (result == -EAGAIN)
-			{
+		result = _recv(sock, (void *) &reply, sizeof(reply),
+			       MSG_PEEK | MSG_DONTWAIT);
+		if (result < 0) {
+			if (result == -EAGAIN) {
 				DPRINTK("ncp_rpc_call: bad select ready\n");
 				goto re_select;
 			}
-			if (result == -ECONNREFUSED)
-			{
+			if (result == -ECONNREFUSED) {
 				DPRINTK("ncp_rpc_call: server playing coy\n");
 				goto re_select;
 			}
-			if (result != -ERESTARTSYS)
-			{
+			if (result != -ERESTARTSYS) {
 				printk("ncp_rpc_call: recv error = %d\n",
-					-result);
+				       -result);
 			}
 			break;
 		}
-		if (   (result     == sizeof(reply))
-		    && (reply.type == NCP_POSITIVE_ACK))
-		{
+		if ((result == sizeof(reply))
+		    && (reply.type == NCP_POSITIVE_ACK)) {
 			/* Throw away the packet */
 			DPRINTK("ncp_rpc_call: got positive acknowledge\n");
-			_recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0,
-				  NULL);
+			_recv(sock, (void *) &reply, sizeof(reply),
+			      MSG_DONTWAIT);
 			n = 0;
 			timeout = max_timeout;
 			acknowledge_seen = 1;
 			goto re_select;
 		}
-
 		DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d,"
-			"seq: %d\n",
-			reply.type,
-			(reply.conn_high << 8) + reply.conn_low,
-			reply.task,
-			reply.sequence);
-		
-		if (   (result          >= sizeof(reply))
-		    && (reply.type      == NCP_REPLY)
-		    && (   (request.type    == NCP_ALLOC_SLOT_REQUEST)
-			|| (   (reply.sequence  == request.sequence)
-			    && (reply.conn_low  == request.conn_low)
-/* seem to get wrong task from NW311 && (reply.task      == request.task)*/
-			    && (reply.conn_high == request.conn_high))))
-		{
+			 "seq: %d\n",
+			 reply.type,
+			 (reply.conn_high << 8) + reply.conn_low,
+			 reply.task,
+			 reply.sequence);
+
+		if ((result >= sizeof(reply))
+		    && (reply.type == NCP_REPLY)
+		    && ((request.type == NCP_ALLOC_SLOT_REQUEST)
+			|| ((reply.sequence == request.sequence)
+			    && (reply.conn_low == request.conn_low)
+/* seem to get wrong task from NW311 && (reply.task      == request.task) */
+			    && (reply.conn_high == request.conn_high)))) {
 			if (major_timeout_seen)
-				printk("NCP server %s OK\n", server_name);
+				printk("NCP server OK\n");
 			break;
 		}
 		/* JEJB/JSP 2/7/94
 		 * we have xid mismatch, so discard the packet and start
 		 * again.  What a hack! but I can't call recvfrom with
 		 * a null buffer yet. */
-		_recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0, NULL);
+		_recv(sock, (void *) &reply, sizeof(reply), MSG_DONTWAIT);
 
 		DPRINTK("ncp_rpc_call: reply mismatch\n");
 		goto re_select;
@@ -540,54 +256,42 @@
 	 * we have the correct reply, so read into the correct place and
 	 * return it
 	 */
-	result = _recvfrom(sock, (void *)start, server->packet_size,
-			   1, 0, NULL);
-	if (result < 0)
-	{
+	result = _recv(sock, (void *) start, server->packet_size, MSG_DONTWAIT);
+	if (result < 0) {
 		printk("NCP: notice message: result=%d\n", result);
-	}
-	else if (result < sizeof(struct ncp_reply_header))
-	{
+	} else if (result < sizeof(struct ncp_reply_header)) {
 		printk("NCP: just caught a too small read memory size..., "
 		       "email to NET channel\n");
 		printk("NCP: result=%d\n", result);
 		result = -EIO;
 	}
-
 	current->blocked = old_mask;
 	set_fs(fs);
 	return result;
 }
 
-
 /*
  * We need the server to be locked here, so check!
  */
 
-static int
-ncp_do_request(struct ncp_server *server, int size)
+static int ncp_do_request(struct ncp_server *server, int size)
 {
 	int result;
 
-	if (server->lock == 0)
-	{
+	if (server->lock == 0) {
 		printk("ncpfs: Server not locked!\n");
 		return -EIO;
 	}
-
-	if (!ncp_conn_valid(server))
-	{
+	if (!ncp_conn_valid(server)) {
 		return -EIO;
 	}
-
 	result = do_ncp_rpc_call(server, size);
 
 	DDPRINTK("do_ncp_rpc_call returned %d\n", result);
 
-	if (result < 0)
-	{
+	if (result < 0) {
 		/* There was a problem with I/O, so the connections is
-                 * no longer usable. */
+		 * no longer usable. */
 		ncp_invalidate_conn(server);
 	}
 	return result;
@@ -596,121 +300,105 @@
 /* ncp_do_request assures that at least a complete reply header is
  * received. It assumes that server->current_size contains the ncp
  * request size */
-int
-ncp_request(struct ncp_server *server, int function)
+int ncp_request(struct ncp_server *server, int function)
 {
 	struct ncp_request_header *h
-		= (struct ncp_request_header *)(server->packet);
+	= (struct ncp_request_header *) (server->packet);
 	struct ncp_reply_header *reply
-		= (struct ncp_reply_header *)(server->packet);
+	= (struct ncp_reply_header *) (server->packet);
 
 	int request_size = server->current_size
-		- sizeof(struct ncp_request_header);
+	- sizeof(struct ncp_request_header);
 
 	int result;
 
-	if (server->has_subfunction != 0)
-	{
-		*(__u16 *)&(h->data[0]) = htons(request_size - 2);
+	if (server->has_subfunction != 0) {
+		*(__u16 *) & (h->data[0]) = htons(request_size - 2);
 	}
-
 	h->type = NCP_REQUEST;
-	
+
 	server->sequence += 1;
-	h->sequence  = server->sequence;
-	h->conn_low  = (server->connection) & 0xff;
+	h->sequence = server->sequence;
+	h->conn_low = (server->connection) & 0xff;
 	h->conn_high = ((server->connection) & 0xff00) >> 8;
-	h->task      = (current->pid) & 0xff;
-	h->function  = function;
+	h->task = (current->pid) & 0xff;
+	h->function = function;
 
-	if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0)
-	{
+	if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0) {
 		DPRINTK("ncp_request_error: %d\n", result);
 		return result;
 	}
-
-	server->completion  = reply->completion_code;
+	server->completion = reply->completion_code;
 	server->conn_status = reply->connection_state;
-	server->reply_size  = result;
+	server->reply_size = result;
 	server->ncp_reply_size = result - sizeof(struct ncp_reply_header);
 
 	result = reply->completion_code;
 
-	if (result != 0)
-	{
+	if (result != 0) {
 		DPRINTK("ncp_completion_code: %x\n", result);
 	}
-	return result;	
+	return result;
 }
 
-int
-ncp_connect(struct ncp_server *server)
+int ncp_connect(struct ncp_server *server)
 {
 	struct ncp_request_header *h
-		= (struct ncp_request_header *)(server->packet);
+	= (struct ncp_request_header *) (server->packet);
 	int result;
 
 	h->type = NCP_ALLOC_SLOT_REQUEST;
-	
+
 	server->sequence = 0;
-	h->sequence  = server->sequence;
-	h->conn_low  = 0xff;
+	h->sequence = server->sequence;
+	h->conn_low = 0xff;
 	h->conn_high = 0xff;
-	h->task      = (current->pid) & 0xff;
-	h->function  = 0;
+	h->task = (current->pid) & 0xff;
+	h->function = 0;
 
-	if ((result = ncp_do_request(server, sizeof(*h))) < 0)
-	{
+	if ((result = ncp_do_request(server, sizeof(*h))) < 0) {
 		return result;
 	}
-
 	server->sequence = 0;
 	server->connection = h->conn_low + (h->conn_high * 256);
 	return 0;
 }
-	
-int
-ncp_disconnect(struct ncp_server *server)
+
+int ncp_disconnect(struct ncp_server *server)
 {
 	struct ncp_request_header *h
-		= (struct ncp_request_header *)(server->packet);
+	= (struct ncp_request_header *) (server->packet);
 
 	h->type = NCP_DEALLOC_SLOT_REQUEST;
-	
+
 	server->sequence += 1;
-	h->sequence  = server->sequence;
-	h->conn_low  = (server->connection) & 0xff;
+	h->sequence = server->sequence;
+	h->conn_low = (server->connection) & 0xff;
 	h->conn_high = ((server->connection) & 0xff00) >> 8;
-	h->task      = (current->pid) & 0xff;
-	h->function  = 0;
+	h->task = (current->pid) & 0xff;
+	h->function = 0;
 
 	return ncp_do_request(server, sizeof(*h));
 }
 
-void
-ncp_lock_server(struct ncp_server *server)
+void ncp_lock_server(struct ncp_server *server)
 {
 #if 0
 	/* For testing, only 1 process */
-	if (server->lock != 0)
-	{
+	if (server->lock != 0) {
 		DPRINTK("ncpfs: server locked!!!\n");
 	}
 #endif
-        while (server->lock)
+	while (server->lock)
 		sleep_on(&server->wait);
 	server->lock = 1;
 }
 
-void
-ncp_unlock_server(struct ncp_server *server)
+void ncp_unlock_server(struct ncp_server *server)
 {
-        if (server->lock != 1)
-	{
-                printk("ncp_unlock_server: was not locked!\n");
-        }
-
-        server->lock = 0;
-        wake_up(&server->wait);
+	if (server->lock != 1) {
+		printk("ncp_unlock_server: was not locked!\n");
+	}
+	server->lock = 0;
+	wake_up(&server->wait);
 }
-        
diff -u --recursive --new-file v2.1.30/linux/fs/open.c linux/fs/open.c
--- v2.1.30/linux/fs/open.c	Sun Jan 26 02:07:44 1997
+++ linux/fs/open.c	Wed Apr  2 17:43:22 1997
@@ -675,14 +675,17 @@
 
 #endif
 
-void __fput(struct file *filp, struct inode *inode)
+int __fput(struct file *filp, struct inode *inode)
 {
+	int	error = 0;
+
 	if (filp->f_op && filp->f_op->release)
-		filp->f_op->release(inode,filp);
+		error = filp->f_op->release(inode,filp);
 	filp->f_inode = NULL;
 	if (filp->f_mode & FMODE_WRITE)
 		put_write_access(inode);
 	iput(inode);
+	return error;
 }
 
 int close_fp(struct file *filp)
@@ -696,8 +699,7 @@
 	inode = filp->f_inode;
 	if (inode)
 		locks_remove_locks(current, filp);
-	fput(filp, inode);
-	return 0;
+	return fput(filp, inode);
 }
 
 asmlinkage int sys_close(unsigned int fd)
diff -u --recursive --new-file v2.1.30/linux/fs/pipe.c linux/fs/pipe.c
--- v2.1.30/linux/fs/pipe.c	Sat Jan 25 13:46:13 1997
+++ linux/fs/pipe.c	Wed Apr  2 17:43:22 1997
@@ -228,25 +228,28 @@
 	return POLLOUT | POLLWRNORM;
 }
 
-static void pipe_read_release(struct inode * inode, struct file * filp)
+static int pipe_read_release(struct inode * inode, struct file * filp)
 {
 	PIPE_READERS(*inode)--;
 	wake_up_interruptible(&PIPE_WAIT(*inode));
+	return 0;
 }
 
-static void pipe_write_release(struct inode * inode, struct file * filp)
+static int pipe_write_release(struct inode * inode, struct file * filp)
 {
 	PIPE_WRITERS(*inode)--;
 	wake_up_interruptible(&PIPE_WAIT(*inode));
+	return 0;
 }
 
-static void pipe_rdwr_release(struct inode * inode, struct file * filp)
+static int pipe_rdwr_release(struct inode * inode, struct file * filp)
 {
 	if (filp->f_mode & FMODE_READ)
 		PIPE_READERS(*inode)--;
 	if (filp->f_mode & FMODE_WRITE)
 		PIPE_WRITERS(*inode)--;
 	wake_up_interruptible(&PIPE_WAIT(*inode));
+	return 0;
 }
 
 static int pipe_read_open(struct inode * inode, struct file * filp)
diff -u --recursive --new-file v2.1.30/linux/fs/proc/kmsg.c linux/fs/proc/kmsg.c
--- v2.1.30/linux/fs/proc/kmsg.c	Sat Jan 25 13:46:13 1997
+++ linux/fs/proc/kmsg.c	Wed Apr  2 17:43:22 1997
@@ -24,9 +24,10 @@
 	return sys_syslog(1,NULL,0);
 }
 
-static void kmsg_release(struct inode * inode, struct file * file)
+static int kmsg_release(struct inode * inode, struct file * file)
 {
 	(void) sys_syslog(0,NULL,0);
+	return 0;
 }
 
 static long kmsg_read(struct inode * inode, struct file * file,
diff -u --recursive --new-file v2.1.30/linux/fs/proc/openpromfs.c linux/fs/proc/openpromfs.c
--- v2.1.30/linux/fs/proc/openpromfs.c	Sun Jan 26 02:07:45 1997
+++ linux/fs/proc/openpromfs.c	Wed Apr  2 17:43:22 1997
@@ -405,7 +405,7 @@
 	return filp->f_pos - k;
 }
 
-void property_release (struct inode *inode, struct file *filp)
+int property_release (struct inode *inode, struct file *filp)
 {
 	openprom_property *op = (openprom_property *)filp->private_data;
 	unsigned long flags;
@@ -413,7 +413,7 @@
 	u32 node;
 	
 	if (!op)
-		return;
+		return 0;
 	node = nodes[(u16)((uint)inode->u.generic_ip)].node;
 	if ((u16)((uint)inode->u.generic_ip) == aliases) {
 		if ((op->flag & OPP_DIRTY) && (op->flag & OPP_STRING)) {
@@ -456,6 +456,7 @@
 		}
 	}
 	kfree (filp->private_data);
+	return 0;
 }
 
 static struct file_operations openpromfs_prop_ops = {
diff -u --recursive --new-file v2.1.30/linux/fs/stat.c linux/fs/stat.c
--- v2.1.30/linux/fs/stat.c	Sun Jan 26 02:07:45 1997
+++ linux/fs/stat.c	Wed Apr  2 17:43:22 1997
@@ -16,6 +16,18 @@
 
 #include <asm/uaccess.h>
 
+/*
+ * Revalidate the inode. This is required for proper NFS attribute caching.
+ */
+static __inline__ int
+do_revalidate(struct inode *inode)
+{
+	if (inode->i_op && inode->i_op->revalidate)
+		return inode->i_op->revalidate(inode);
+	return 0;
+}
+
+
 #if !defined(__alpha__) && !defined(__sparc__)
 
 /*
@@ -118,7 +130,8 @@
 	error = namei(filename,&inode);
 	if (error)
 		goto out;
-	error = cp_old_stat(inode,statbuf);
+	if ((error = do_revalidate(inode)) == 0)
+		error = cp_old_stat(inode,statbuf);
 	iput(inode);
 out:
 	unlock_kernel();
@@ -135,7 +148,8 @@
 	error = namei(filename,&inode);
 	if (error)
 		goto out;
-	error = cp_new_stat(inode,statbuf);
+	if ((error = do_revalidate(inode)) == 0)
+		error = cp_new_stat(inode,statbuf);
 	iput(inode);
 out:
 	unlock_kernel();
@@ -157,7 +171,8 @@
 	error = lnamei(filename,&inode);
 	if (error)
 		goto out;
-	error = cp_old_stat(inode,statbuf);
+	if ((error = do_revalidate(inode)) == 0)
+		error = cp_old_stat(inode,statbuf);
 	iput(inode);
 out:
 	unlock_kernel();
@@ -175,7 +190,8 @@
 	error = lnamei(filename,&inode);
 	if (error)
 		goto out;
-	error = cp_new_stat(inode,statbuf);
+	if ((error = do_revalidate(inode)) == 0)
+		error = cp_new_stat(inode,statbuf);
 	iput(inode);
 out:
 	unlock_kernel();
@@ -197,7 +213,8 @@
 	lock_kernel();
 	if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
 		goto out;
-	ret = cp_old_stat(inode,statbuf);
+	if ((ret = do_revalidate(inode)) == 0)
+		ret = cp_old_stat(inode,statbuf);
 out:
 	unlock_kernel();
 	return ret;
@@ -214,7 +231,8 @@
 	lock_kernel();
 	if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
 		goto out;
-	err = cp_new_stat(inode,statbuf);
+	if ((err = do_revalidate(inode)) == 0)
+		err = cp_new_stat(inode,statbuf);
 out:
 	unlock_kernel();
 	return err;
@@ -235,7 +253,8 @@
 	if (error)
 		goto out;
 	error = -EINVAL;
-	if (!inode->i_op || !inode->i_op->readlink) {
+	if (!inode->i_op || !inode->i_op->readlink
+	 || (error = do_revalidate(inode)) < 0) {
 		iput(inode);
 		goto out;
 	}
diff -u --recursive --new-file v2.1.30/linux/fs/super.c linux/fs/super.c
--- v2.1.30/linux/fs/super.c	Thu Mar 27 14:40:06 1997
+++ linux/fs/super.c	Wed Apr  2 17:43:22 1997
@@ -48,7 +48,6 @@
 
 extern void wait_for_keypress(void);
 extern struct file_operations * get_blkfops(unsigned int major);
-extern void blkdev_release (struct inode *);
 
 extern int root_mountflags;
 
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h
--- v2.1.30/linux/include/asm-alpha/atomic.h	Wed Sep 11 11:41:51 1996
+++ linux/include/asm-alpha/atomic.h	Fri Mar 28 10:52:25 1997
@@ -1,14 +1,16 @@
-#ifndef __ARCH_ALPHA_ATOMIC__
-#define __ARCH_ALPHA_ATOMIC__
+#ifndef _ALPHA_ATOMIC_H
+#define _ALPHA_ATOMIC_H
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
  * resource counting etc...
  *
- * But use these as seldom as possible since they are much more slower
+ * But use these as seldom as possible since they are much slower
  * than regular operations.
  */
 
+typedef int atomic_t;
+
 /*
  * Make sure gcc doesn't try to be clever and move things around
  * on us. We need to use _exactly_ the address the user gave us,
@@ -16,38 +18,40 @@
  */
 #define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
 
-typedef int atomic_t;
+/*
+ * To get proper branch prediction for the main line, we must branch
+ * forward to code at the end of this object's .text section, then
+ * branch back to restart the operation.
+ */
 
 extern __inline__ void atomic_add(atomic_t i, atomic_t * v)
 {
 	unsigned long temp;
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%1\n\t"
-		"addl %0,%2,%0\n\t"
-		"stl_c %0,%1\n\t"
-		"beq %0,1b\n"
-		"2:"
-		:"=&r" (temp),
-		 "=m" (__atomic_fool_gcc(v))
-		:"Ir" (i),
-		 "m" (__atomic_fool_gcc(v)));
+	"1:	ldl_l %0,%1\n"
+	"	addl %0,%2,%0\n"
+	"	stl_c %0,%1\n"
+	"	beq %0,2f\n"
+	".text 2\n"
+	"2:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (__atomic_fool_gcc(v))
+	:"Ir" (i), "m" (__atomic_fool_gcc(v)));
 }
 
 extern __inline__ void atomic_sub(atomic_t i, atomic_t * v)
 {
 	unsigned long temp;
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%1\n\t"
-		"subl %0,%2,%0\n\t"
-		"stl_c %0,%1\n\t"
-		"beq %0,1b\n"
-		"2:"
-		:"=&r" (temp),
-		 "=m" (__atomic_fool_gcc(v))
-		:"Ir" (i),
-		 "m" (__atomic_fool_gcc(v)));
+	"1:	ldl_l %0,%1\n"
+	"	subl %0,%2,%0\n"
+	"	stl_c %0,%1\n"
+	"	beq %0,2f\n"
+	".text 2\n"
+	"2:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (__atomic_fool_gcc(v))
+	:"Ir" (i), "m" (__atomic_fool_gcc(v)));
 }
 
 /*
@@ -57,18 +61,16 @@
 {
 	long temp, result;
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%1\n\t"
-		"addl %0,%3,%0\n\t"
-		"bis %0,%0,%2\n\t"
-		"stl_c %0,%1\n\t"
-		"beq %0,1b\n"
-		"2:"
-		:"=&r" (temp),
-		 "=m" (__atomic_fool_gcc(v)),
-		 "=&r" (result)
-		:"Ir" (i),
-		 "m" (__atomic_fool_gcc(v)));
+	"1:	ldl_l %0,%1\n"
+	"	addl %0,%3,%0\n"
+	"	mov %0,%2\n"
+	"	stl_c %0,%1\n"
+	"	beq %0,2f\n"
+	".text 2\n"
+	"2:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
+	:"Ir" (i), "m" (__atomic_fool_gcc(v)));
 	return result;
 }
 
@@ -76,18 +78,16 @@
 {
 	long temp, result;
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%1\n\t"
-		"subl %0,%3,%0\n\t"
-		"bis %0,%0,%2\n\t"
-		"stl_c %0,%1\n\t"
-		"beq %0,1b\n"
-		"2:"
-		:"=&r" (temp),
-		 "=m" (__atomic_fool_gcc(v)),
-		 "=&r" (result)
-		:"Ir" (i),
-		 "m" (__atomic_fool_gcc(v)));
+	"1:	ldl_l %0,%1\n"
+	"	subl %0,%3,%0\n"
+	"	mov %0,%2\n"
+	"	stl_c %0,%1\n"
+	"	beq %0,2f\n"
+	".text 2\n"
+	"2:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
+	:"Ir" (i), "m" (__atomic_fool_gcc(v)));
 	return result;
 }
 
@@ -100,4 +100,4 @@
 #define atomic_inc(v) atomic_add(1,(v))
 #define atomic_dec(v) atomic_sub(1,(v))
 
-#endif
+#endif /* _ALPHA_ATOMIC_H */
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h
--- v2.1.30/linux/include/asm-alpha/bitops.h	Fri Dec 20 01:24:38 1996
+++ linux/include/asm-alpha/bitops.h	Fri Mar 28 10:52:25 1997
@@ -10,6 +10,10 @@
  * is guaranteed to be atomic. All bit operations return 0 if the bit
  * was cleared before the operation and != 0 if it was not.
  *
+ * To get proper branch prediction for the main line, we must branch
+ * forward to code at the end of this object's .text section, then
+ * branch back to restart the operation.
+ *
  * bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1).
  */
 
@@ -20,19 +24,19 @@
 	unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%1\n\t"
-		"and %0,%3,%2\n\t"
-		"bne %2,2f\n\t"
-		"xor %0,%3,%0\n\t"
-		"stl_c %0,%1\n\t"
-		"beq %0,1b\n"
-		"2:"
-		:"=&r" (temp),
-		 "=m" (*m),
-		 "=&r" (oldbit)
-		:"Ir" (1UL << (nr & 31)),
-		 "m" (*m));
+	"1:	ldl_l %0,%1\n"
+	"	and %0,%3,%2\n"
+	"	bne %2,2f\n"
+	"	xor %0,%3,%0\n"
+	"	stl_c %0,%1\n"
+	"	beq %0,3f\n"
+	"2:\n"
+	".text 2\n"
+	"3:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+	:"Ir" (1UL << (nr & 31)), "m" (*m));
+
 	return oldbit != 0;
 }
 
@@ -43,19 +47,19 @@
 	unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%1\n\t"
-		"and %0,%3,%2\n\t"
-		"beq %2,2f\n\t"
-		"xor %0,%3,%0\n\t"
-		"stl_c %0,%1\n\t"
-		"beq %0,1b\n"
-		"2:"
-		:"=&r" (temp),
-		 "=m" (*m),
-		 "=&r" (oldbit)
-		:"Ir" (1UL << (nr & 31)),
-		 "m" (*m));
+	"1:	ldl_l %0,%1\n"
+	"	and %0,%3,%2\n\t"
+	"	beq %2,2f\n\t"
+	"	xor %0,%3,%0\n\t"
+	"	stl_c %0,%1\n\t"
+	"	beq %0,3f\n"
+	"2:\n"
+	".text 2\n"
+	"3:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+	:"Ir" (1UL << (nr & 31)), "m" (*m));
+
 	return oldbit != 0;
 }
 
@@ -66,17 +70,17 @@
 	unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%1\n\t"
-		"and %0,%3,%2\n\t"
-		"xor %0,%3,%0\n\t"
-		"stl_c %0,%1\n\t"
-		"beq %0,1b\n"
-		:"=&r" (temp),
-		 "=m" (*m),
-		 "=&r" (oldbit)
-		:"Ir" (1UL << (nr & 31)),
-		 "m" (*m));
+	"1:	ldl_l %0,%1\n"
+	"	and %0,%3,%2\n\t"
+	"	xor %0,%3,%0\n\t"
+	"	stl_c %0,%1\n\t"
+	"	beq %0,3f\n"
+	".text 2\n"
+	"3:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+	:"Ir" (1UL << (nr & 31)), "m" (*m));
+
 	return oldbit != 0;
 }
 
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/hardirq.h linux/include/asm-alpha/hardirq.h
--- v2.1.30/linux/include/asm-alpha/hardirq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-alpha/hardirq.h	Fri Mar 28 11:14:41 1997
@@ -0,0 +1,20 @@
+#ifndef _ALPHA_HARDIRQ_H
+#define _ALPHA_HARDIRQ_H
+
+extern unsigned int local_irq_count[NR_CPUS];
+#define in_interrupt()  (local_irq_count[smp_processor_id()] != 0)
+
+#ifndef __SMP__
+
+#define hardirq_trylock(cpu)	((cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define hardirq_enter(cpu)	(local_irq_count[cpu]++)
+#define hardirq_exit(cpu)	(local_irq_count[cpu]--)
+
+#else
+
+#error FIXME
+
+#endif /* __SMP__ */
+#endif /* _ALPHA_HARDIRQ_H */
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/smp_lock.h linux/include/asm-alpha/smp_lock.h
--- v2.1.30/linux/include/asm-alpha/smp_lock.h	Sun Jan 26 03:40:46 1997
+++ linux/include/asm-alpha/smp_lock.h	Fri Mar 28 11:03:25 1997
@@ -3,8 +3,10 @@
 
 #ifndef __SMP__
 
-#define lock_kernel()		do { } while(0)
-#define unlock_kernel()		do { } while(0)
+#define lock_kernel()				do { } while(0)
+#define unlock_kernel()				do { } while(0)
+#define release_kernel_lock(task, cpu, depth)	((depth) = 1)
+#define reaquire_kernel_lock(task, cpu, depth)	do { } while (0)
 
 #else
 
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h
--- v2.1.30/linux/include/asm-alpha/softirq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-alpha/softirq.h	Fri Mar 28 11:16:22 1997
@@ -0,0 +1,35 @@
+#ifndef _ALPHA_SOFTIRQ_H
+#define _ALPHA_SOFTIRQ_H
+
+/*
+ * Software interrupts..
+ */
+#define get_active_bhs()	(bh_mask & bh_active)
+
+static inline void clear_active_bhs(unsigned long x)
+{
+	unsigned long temp;
+	__asm__ __volatile__(
+	"1:	ldq_l %0,%1\n"
+	"	and %0,%2,%0\n"
+	"	stq_c %0,%1\n"
+	"	beq %0,2f\n"
+	".text 2\n"
+	"2:	br 1b\n"
+	".text"
+	:"=&r" (temp), "=m" (bh_active)
+	:"Ir" (x), "m" (bh_active));
+}
+
+#ifndef __SMP__
+
+/* These are for the irq's testing the lock */
+#define softirq_trylock()	(intr_count ? 0 : ((intr_count=1),1))
+#define softirq_endlock()	(intr_count = 0)
+
+#else
+
+#error FIXME
+
+#endif /* __SMP__ */
+#endif /* _ALPHA_SOFTIRQ_H */
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h
--- v2.1.30/linux/include/asm-alpha/spinlock.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-alpha/spinlock.h	Fri Mar 28 11:13:21 1997
@@ -0,0 +1,92 @@
+#ifndef _ALPHA_SPINLOCK_H
+#define _ALPHA_SPINLOCK_H
+
+#ifndef __SMP__
+
+typedef struct { } spinlock_t;
+#define SPIN_LOCK_UNLOCKED { }
+
+#define spin_lock_init(lock)			do { } while(0)
+#define spin_lock(lock)				do { } while(0)
+#define spin_trylock(lock)			do { } while(0)
+#define spin_unlock(lock)			do { } while(0)
+#define spin_lock_irq(lock)			setipl(7)
+#define spin_unlock_irq(lock)			setipl(0)
+
+#define spin_lock_irqsave(lock, flags)		swpipl(flags,7)
+#define spin_unlock_irqrestore(lock, flags)	setipl(flags)
+
+#else
+
+/* Simple spin lock operations.  There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions. They have a cost.
+ */
+
+typedef struct {
+	volatile unsigned long lock;
+	unsigned long previous;
+} spinlock_t;
+
+#define SPIN_LOCK_UNLOCKED { 0, 0 }
+
+typedef struct { unsigned long a[100]; } __dummy_lock_t;
+#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
+
+#define spin_unlock(lock)				\
+	__asm__ __volatile__(				\
+	"mb; stq $31,%0"				\
+	:"=m" (__dummy_lock(lock)))
+
+static inline void spin_lock(spinlock_t * lock)
+{
+	__label__ l1;
+	long tmp;
+	long stuck = 0x100000000;
+l1:
+	/* Use sub-sections to put the actual loop at the end
+	   of this object file's text section so as to perfect
+	   branch prediction.  */
+	__asm__ __volatile__(
+	"1:	ldq_l	%0,%1\n"
+	"	subq	%2,1,%2\n"
+	"	blbs	%0,2f\n"
+	"	or	%0,1,%0\n"
+	"	stq_c	%0,%1\n"
+	"	beq	%0,3f\n"
+	"4:	mb\n"
+	".text 2\n"
+	"2:	ldq	%0,%1\n"
+	"	subq	%2,1,%2\n"
+	"3:	blt	%2,4b\n"
+	"	blbs	%0,2b\n"
+	"	br	1b\n"
+	".text"
+	: "=r" (tmp),
+	  "=m" (__dummy_lock(lock)),
+	  "=r" (stuck)
+	: "2" (stuck));
+
+	if (stuck < 0)
+		printk("spinlock stuck at %p (%lx)\n",&&l1,lock->previous);
+	else
+		lock->previous = (unsigned long) &&l1;
+}
+
+#define spin_trylock(lock) (!set_bit(0,(lock)))
+
+#define spin_lock_irq(lock) \
+	do { __cli(); spin_lock(lock); } while (0)
+
+#define spin_unlock_irq(lock) \
+	do { spin_unlock(lock); __sti(); } while (0)
+
+#define spin_lock_irqsave(lock, flags) \
+	do { swpipl(flags,7); spin_lock(lock); } while (0)
+
+#define spin_unlock_irqrestore(lock, flags) \
+	do { spin_unlock(lock); setipl(flags); } while (0)
+
+#endif /* SMP */
+#endif /* _ALPHA_SPINLOCK_H */
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v2.1.30/linux/include/asm-alpha/system.h	Thu Feb  6 04:42:35 1997
+++ linux/include/asm-alpha/system.h	Fri Mar 28 11:13:21 1997
@@ -70,14 +70,12 @@
 #define draina() \
 __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_draina) : "memory")
 
-#define getipl() \
-({ unsigned long __old_ipl; \
+#define getipl(__old_ipl) \
 __asm__ __volatile__( \
 	"call_pal 54\n\t" \
 	"bis $0,$0,%0" \
 	: "=r" (__old_ipl) \
-	: : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); \
-__old_ipl; })
+	: : "$0", "$1", "$16", "$22", "$23", "$24", "$25")
 
 #define setipl(__new_ipl) \
 __asm__ __volatile__( \
@@ -86,20 +84,23 @@
 	: : "r" (__new_ipl) \
 	: "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory")
 
-#define swpipl(__new_ipl) \
-({ unsigned long __old_ipl; \
+#define swpipl(__old_ipl,__new_ipl) \
 __asm__ __volatile__( \
 	"bis %1,%1,$16\n\t" \
 	"call_pal 53\n\t" \
 	"bis $0,$0,%0" \
 	: "=r" (__old_ipl) \
 	: "r" (__new_ipl) \
-	: "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory"); \
-__old_ipl; })
+	: "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory")
+
+#define __cli()			setipl(7)
+#define __sti()			setipl(0)
+#define __save_flags(flags)	getipl(flags)
+#define __restore_flags(flags)	setipl(flags)
 
 #define cli()			setipl(7)
 #define sti()			setipl(0)
-#define save_flags(flags)	do { flags = getipl(); } while (0)
+#define save_flags(flags)	getipl(flags)
 #define restore_flags(flags)	setipl(flags)
 
 /*
@@ -122,28 +123,36 @@
 extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
 {
 	unsigned long dummy;
+
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldl_l %0,%2\n\t"
-		"bis %3,%3,%1\n\t"
-		"stl_c %1,%2\n\t"
-		"beq %1,1b\n"
-		: "=&r" (val), "=&r" (dummy), "=m" (*m)
-		: "r" (val), "m" (*m));
+	"1:	ldl_l %0,%2\n"
+	"	bis %3,%3,%1\n"
+	"	stl_c %1,%2\n"
+	"	beq %1,2f\n"
+	".text 2\n"
+	"2:	br 1b\n"
+	".text"
+	: "=&r" (val), "=&r" (dummy), "=m" (*m)
+	: "r" (val), "m" (*m));
+
 	return val;
 }
 
 extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
 {
 	unsigned long dummy;
+
 	__asm__ __volatile__(
-		"\n1:\t"
-		"ldq_l %0,%2\n\t"
-		"bis %3,%3,%1\n\t"
-		"stq_c %1,%2\n\t"
-		"beq %1,1b\n"
-		: "=&r" (val), "=&r" (dummy), "=m" (*m)
-		: "r" (val), "m" (*m));
+	"1:	ldq_l %0,%2\n"
+	"	bis %3,%3,%1\n"
+	"	stq_c %1,%2\n"
+	"	beq %1,2f\n"
+	".text 2\n"
+	"2:	br 1b\n"
+	".text"
+	: "=&r" (val), "=&r" (dummy), "=m" (*m)
+	: "r" (val), "m" (*m));
+
 	return val;
 }
 
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/termios.h linux/include/asm-alpha/termios.h
--- v2.1.30/linux/include/asm-alpha/termios.h	Mon Dec 30 02:48:07 1996
+++ linux/include/asm-alpha/termios.h	Fri Mar 28 11:02:43 1997
@@ -85,58 +85,68 @@
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
-	unsigned short __tmp; \
-	get_user(__tmp,&(termio)->x); \
-	*(unsigned short *) &(termios)->x = __tmp; \
-}
 
-#define user_termio_to_kernel_termios(termios, termio) \
-do { \
-	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
-	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
-	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
-	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
-	get_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
-	get_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
-	get_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
-	get_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
-	get_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
-	get_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
-	get_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
-	get_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
-	get_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
-	get_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
-} while(0)
+#define user_termio_to_kernel_termios(a_termios, u_termio)			\
+({										\
+	struct termios *k_termios = (a_termios);				\
+	struct termio k_termio;							\
+	int canon, ret;								\
+										\
+	ret = copy_from_user(&k_termio, u_termio, sizeof(k_termio));		\
+	if (!ret) {								\
+		/* Overwrite only the low bits.  */				\
+		*(unsigned short *)&k_termios->c_iflag = k_termio.c_iflag;	\
+		*(unsigned short *)&k_termios->c_oflag = k_termio.c_oflag;	\
+		*(unsigned short *)&k_termios->c_cflag = k_termio.c_cflag;	\
+		*(unsigned short *)&k_termios->c_lflag = k_termio.c_lflag;	\
+		canon = k_termio.c_lflag & ICANON;				\
+										\
+		k_termios->c_cc[VINTR]  = k_termio.c_cc[_VINTR];		\
+		k_termios->c_cc[VQUIT]  = k_termio.c_cc[_VQUIT];		\
+		k_termios->c_cc[VERASE] = k_termio.c_cc[_VERASE];		\
+		k_termios->c_cc[VKILL]  = k_termio.c_cc[_VKILL];		\
+		k_termios->c_cc[VEOL2]  = k_termio.c_cc[_VEOL2];		\
+		k_termios->c_cc[VSWTC]  = k_termio.c_cc[_VSWTC];		\
+		k_termios->c_cc[canon ? VEOF : VMIN]  = k_termio.c_cc[_VEOF];	\
+		k_termios->c_cc[canon ? VEOL : VTIME] = k_termio.c_cc[_VEOL];	\
+	}									\
+	ret;									\
+})
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  *
  * Note the "fun" _VMIN overloading.
  */
-#define kernel_termios_to_user_termio(termio, termios) \
-do { \
-	put_user((termios)->c_iflag, &(termio)->c_iflag); \
-	put_user((termios)->c_oflag, &(termio)->c_oflag); \
-	put_user((termios)->c_cflag, &(termio)->c_cflag); \
-	put_user((termios)->c_lflag, &(termio)->c_lflag); \
-	put_user((termios)->c_line, &(termio)->c_line); \
-	put_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
-	put_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
-	put_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
-	put_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
-	put_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
-	put_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
-	put_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
-	put_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
-	if (!((termios)->c_lflag & ICANON)) { \
-		put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
-		put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
-	} \
-} while(0)
+#define kernel_termios_to_user_termio(u_termio, a_termios)		\
+({									\
+	struct termios *k_termios = (a_termios);			\
+	struct termio k_termio;						\
+	int canon;							\
+									\
+	k_termio.c_iflag = k_termios->c_iflag;				\
+	k_termio.c_oflag = k_termios->c_oflag;				\
+	k_termio.c_cflag = k_termios->c_cflag;				\
+	canon = (k_termio.c_lflag = k_termios->c_lflag) & ICANON;	\
+									\
+	k_termio.c_line = k_termios->c_line;				\
+	k_termio.c_cc[_VINTR]  = k_termios->c_cc[VINTR];		\
+	k_termio.c_cc[_VQUIT]  = k_termios->c_cc[VQUIT];		\
+	k_termio.c_cc[_VERASE] = k_termios->c_cc[VERASE];		\
+	k_termio.c_cc[_VKILL]  = k_termios->c_cc[VKILL];		\
+	k_termio.c_cc[_VEOF]   = k_termios->c_cc[canon ? VEOF : VMIN];	\
+	k_termio.c_cc[_VEOL]   = k_termios->c_cc[canon ? VEOL : VTIME];	\
+	k_termio.c_cc[_VEOL2]  = k_termios->c_cc[VEOL2];		\
+	k_termio.c_cc[_VSWTC]  = k_termios->c_cc[VSWTC];		\
+									\
+	copy_to_user(u_termio, &k_termio, sizeof(k_termio));		\
+})
 
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#define user_termios_to_kernel_termios(k, u) \
+	copy_from_user(k, u, sizeof(struct termios))
+
+#define kernel_termios_to_user_termios(u, k) \
+	copy_to_user(u, k, sizeof(struct termios))
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- v2.1.30/linux/include/asm-alpha/unistd.h	Thu Jan 23 11:01:28 1997
+++ linux/include/asm-alpha/unistd.h	Wed Apr  2 17:43:22 1997
@@ -279,7 +279,7 @@
 #define __NR_uname			339
 #define __NR_nanosleep			340
 #define __NR_mremap			341
-#define __NR_nfsctl			342
+#define __NR_nfsservctl			342
 #define __NR_setresuid			343
 #define __NR_getresuid			344
 #define __NR_pciconfig_read		345
diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/io.h linux/include/asm-i386/io.h
--- v2.1.30/linux/include/asm-i386/io.h	Mon Oct 14 23:31:45 1996
+++ linux/include/asm-i386/io.h	Wed Apr  2 17:51:57 1997
@@ -1,6 +1,8 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
+#include <linux/vmalloc.h>
+
 /*
  * This file contains the definitions for the x86 IO instructions
  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
@@ -184,7 +186,23 @@
 	return __io_virt(address);
 }
 
-extern void * ioremap(unsigned long offset, unsigned long size);
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+extern inline void * ioremap (unsigned long offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that area.
+ * it's useful if some control registers are in such an area and write combining
+ * or read caching is not desirable:
+ */
+extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
+{
+        return __ioremap(offset, size, _PAGE_PCD);
+}
+
 extern void iounmap(void *addr);
 
 /*
diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/smp_lock.h linux/include/asm-i386/smp_lock.h
--- v2.1.30/linux/include/asm-i386/smp_lock.h	Thu Mar 27 14:40:06 1997
+++ linux/include/asm-i386/smp_lock.h	Mon Mar 31 12:52:31 1997
@@ -1,6 +1,8 @@
 #ifndef __I386_SMPLOCK_H
 #define __I386_SMPLOCK_H
 
+#define __STR(x) #x
+
 #ifndef __SMP__
 
 #define lock_kernel()				do { } while(0)
@@ -77,9 +79,9 @@
 	cli
 	decl	%0
 	jnz	1f
-	movb	%1, active_kernel_processor
+	movb	%1, " __STR(active_kernel_processor) "
 	lock
-	btrl	$0, kernel_flag
+	btrl	$0, " __STR(kernel_flag) "
 1:
 	popfl
 "	: /* no outputs */
diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/termios.h linux/include/asm-i386/termios.h
--- v2.1.30/linux/include/asm-i386/termios.h	Thu Mar 27 14:40:06 1997
+++ linux/include/asm-i386/termios.h	Mon Mar 31 12:52:31 1997
@@ -45,6 +45,7 @@
 #define N_PPP		3
 #define N_STRIP		4
 #define N_AX25		5
+#define N_X25		6	/* X.25 async */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.1.30/linux/include/asm-i386/unistd.h	Thu Jan 23 11:01:28 1997
+++ linux/include/asm-i386/unistd.h	Wed Apr  2 17:43:22 1997
@@ -174,6 +174,7 @@
 #define __NR_vm86		166
 #define __NR_query_module	167
 #define __NR_poll		168
+#define __NR_nfsservctl		169
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
diff -u --recursive --new-file v2.1.30/linux/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h
--- v2.1.30/linux/include/asm-m68k/unistd.h	Fri Nov 22 05:56:36 1996
+++ linux/include/asm-m68k/unistd.h	Wed Apr  2 17:43:22 1997
@@ -171,6 +171,7 @@
 #define __NR_mremap		163
 #define __NR_setresuid		164
 #define __NR_getresuid		165
+#define __NR_nfsservctl		166
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
diff -u --recursive --new-file v2.1.30/linux/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h
--- v2.1.30/linux/include/asm-mips/unistd.h	Wed Dec 13 02:39:47 1995
+++ linux/include/asm-mips/unistd.h	Wed Apr  2 17:43:22 1997
@@ -1143,6 +1143,7 @@
 #define __NR_munlock			(__NR_Linux + 155)
 #define __NR_mlockall			(__NR_Linux + 156)
 #define __NR_munlockall			(__NR_Linux + 157)
+#define __NR_nfsservctl			(__NR_Linux + 158)
 
 
 /*
diff -u --recursive --new-file v2.1.30/linux/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h
--- v2.1.30/linux/include/asm-ppc/unistd.h	Wed Dec 18 00:54:10 1996
+++ linux/include/asm-ppc/unistd.h	Wed Apr  2 17:43:22 1997
@@ -175,6 +175,7 @@
 #define __NR_mremap		163
 #define __NR_setresuid		164
 #define __NR_getresuid		165
+#define __NR_nfsservctl		166
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
diff -u --recursive --new-file v2.1.30/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h
--- v2.1.30/linux/include/asm-sparc/unistd.h	Mon Mar 17 14:54:33 1997
+++ linux/include/asm-sparc/unistd.h	Wed Apr  2 17:43:22 1997
@@ -270,7 +270,7 @@
 #define __NR__sysctl            251
 #define __NR_getsid             252
 #define __NR_fdatasync          253
-#define __NR_nfsctl             254
+#define __NR_nfsservctl         254
 #define __NR_aplib              255
 
 #define _syscall0(type,name) \
diff -u --recursive --new-file v2.1.30/linux/include/linux/auto_fs.h linux/include/linux/auto_fs.h
--- v2.1.30/linux/include/linux/auto_fs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/auto_fs.h	Wed Apr  2 17:55:03 1997
@@ -0,0 +1,177 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/include/linux/auto_fs.h
+ *
+ *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+
+#ifndef _LINUX_AUTO_FS_H
+#define _LINUX_AUTO_FS_H
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+#include <asm/types.h>
+
+#define AUTOFS_PROTO_VERSION 2
+
+enum autofs_packet_type {
+	autofs_ptype_missing,	/* Missing entry (create wait queue) */
+	/* ...need more in the future... */
+};
+
+struct autofs_packet_hdr {
+	int proto_version;	      /* Protocol version */
+	enum autofs_packet_type type; /* Type of packet */
+};
+
+struct autofs_packet_missing {
+	struct autofs_packet_hdr hdr;
+        unsigned long wait_queue_token;
+	int len;
+	char name[NAME_MAX+1];
+};	
+
+#define AUTOFS_IOC_READY     _IO(0x93,0x60)
+#define AUTOFS_IOC_FAIL      _IO(0x93,0x61)
+#define AUTOFS_IOC_CATATONIC _IO(0x93,0x62)
+
+#ifdef __KERNEL__
+
+#include <linux/wait.h>
+#include <linux/sched.h>
+
+#if LINUX_VERSION_CODE < 0x20100
+
+#include <asm/segment.h>
+#define copy_to_user	memcpy_tofs
+#define copy_from_user	memcpy_fromfs
+
+#else
+
+#include <asm/uaccess.h>
+#define register_symtab(x)	do { } while (0)
+
+#endif
+
+#ifndef DPRINTK
+#ifdef DEBUG
+#define DPRINTK(D) printk D;
+#else
+#define DPRINTK(D)
+#endif
+#endif
+
+#define AUTOFS_SUPER_MAGIC 0x0187
+
+/* Structures associated with the root directory hash */
+
+#define AUTOFS_HASH_SIZE 67
+
+typedef u32 autofs_hash_t;	/* Type returned by autofs_hash() */
+
+struct autofs_dir_ent {
+	autofs_hash_t hash;
+	struct autofs_dir_ent *next;
+	struct autofs_dir_ent **back;
+	char *name;
+	int len;
+	ino_t ino;
+	time_t expiry;		/* Reserved for use in failed-lookup cache */
+};
+
+struct autofs_dirhash {
+	struct autofs_dir_ent *h[AUTOFS_HASH_SIZE];
+};
+
+struct autofs_wait_queue {
+	unsigned long wait_queue_token;
+	struct wait_queue *queue;
+	struct autofs_wait_queue *next;
+	/* We use the following to see what we are waiting for */
+	autofs_hash_t hash;
+	int len;
+	char *name;
+	/* This is for status reporting upon return */
+	int status;
+	int wait_ctr;
+};
+
+struct autofs_symlink {
+	int len;
+	char *data;
+	time_t mtime;
+};
+
+#define AUTOFS_MAX_SYMLINKS 256
+
+#define AUTOFS_ROOT_INO      1
+#define AUTOFS_FIRST_SYMLINK 2
+#define AUTOFS_FIRST_DIR_INO (AUTOFS_FIRST_SYMLINK+AUTOFS_MAX_SYMLINKS)
+
+#define AUTOFS_SYMLINK_BITMAP_LEN ((AUTOFS_MAX_SYMLINKS+31)/32)
+
+#ifndef END_OF_TIME
+#define END_OF_TIME ((time_t)((unsigned long)((time_t)(~0UL)) >> 1))
+#endif
+
+struct autofs_sb_info {
+	struct file *pipe;
+	pid_t oz_pgrp;
+	int catatonic;
+	ino_t next_dir_ino;
+	struct autofs_wait_queue *queues; /* Wait queue pointer */
+	struct autofs_dirhash dirhash; /* Root directory hash */
+	struct autofs_symlink symlink[AUTOFS_MAX_SYMLINKS];
+	u32 symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN];
+};
+
+/* autofs_oz_mode(): do we see the man behind the curtain? */
+static inline int autofs_oz_mode(struct autofs_sb_info *sbi) {
+	return sbi->catatonic || current->pgrp == sbi->oz_pgrp;
+}
+
+/* Init function */
+int init_autofs_fs(void);
+
+/* Hash operations */
+
+autofs_hash_t autofs_hash(const char *,int);
+void autofs_initialize_hash(struct autofs_dirhash *);
+struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *,autofs_hash_t,const char *,int);
+void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *);
+void autofs_hash_delete(struct autofs_dir_ent *);
+struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *);
+void autofs_hash_nuke(struct autofs_dirhash *);
+
+/* Operations structures */
+
+extern struct inode_operations autofs_root_inode_operations;
+extern struct inode_operations autofs_symlink_inode_operations;
+extern struct inode_operations autofs_dir_inode_operations;
+
+/* Initializing function */
+
+struct super_block *autofs_read_super(struct super_block *, void *,int);
+
+/* Queue management functions */
+
+int autofs_wait(struct autofs_sb_info *,autofs_hash_t,const char *,int);
+int autofs_wait_release(struct autofs_sb_info *,unsigned long,int);
+void autofs_catatonic_mode(struct autofs_sb_info *);
+
+#ifdef DEBUG
+void autofs_say(const char *name, int len);
+#else
+#define autofs_say(n,l)
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_AUTO_FS_H */
diff -u --recursive --new-file v2.1.30/linux/include/linux/console.h linux/include/linux/console.h
--- v2.1.30/linux/include/linux/console.h	Sun May 19 21:54:29 1996
+++ linux/include/linux/console.h	Thu Mar 27 14:36:39 1997
@@ -16,70 +16,7 @@
 
 #define NPAR 16
 
-struct vc_data {
-	unsigned long	vc_screenbuf_size;
-	unsigned short	vc_num;			/* Console number */
-	unsigned short	vc_video_erase_char;	/* Background erase character */
-	unsigned char	vc_attr;		/* Current attributes */
-	unsigned char	vc_def_color;		/* Default colors */
-	unsigned char	vc_color;		/* Foreground & background */
-	unsigned char	vc_s_color;		/* Saved foreground & background */
-	unsigned char	vc_ulcolor;		/* Colour for underline mode */
-	unsigned char	vc_halfcolor;		/* Colour for half intensity mode */
-	unsigned long	vc_origin;		/* Used for EGA/VGA fast scroll	*/
-	unsigned long	vc_scr_end;		/* Used for EGA/VGA fast scroll	*/
-	unsigned short	*vc_pos;
-	unsigned long	vc_x,vc_y;
-	unsigned long	vc_top,vc_bottom;
-	unsigned long	vc_rows,vc_cols;
-	unsigned long	vc_size_row;
-	unsigned long	vc_state;
-	unsigned long	vc_npar,vc_par[NPAR];
-	unsigned short	*vc_video_mem_start;
-	unsigned long	vc_video_mem_end;	/* End of video RAM (sort of)	*/
-	unsigned long	vc_saved_x;
-	unsigned long	vc_saved_y;
-	/* mode flags */
-	unsigned long	vc_charset	: 1;	/* Character set G0 / G1 */
-	unsigned long	vc_s_charset	: 1;	/* Saved character set */
-	unsigned long	vc_disp_ctrl	: 1;	/* Display chars < 32? */
-	unsigned long	vc_toggle_meta	: 1;	/* Toggle high bit? */
-	unsigned long	vc_decscnm	: 1;	/* Screen Mode */
-	unsigned long	vc_decom	: 1;	/* Origin Mode */
-	unsigned long	vc_decawm	: 1;	/* Autowrap Mode */
-	unsigned long	vc_deccm	: 1;	/* Cursor Visible */
-	unsigned long	vc_decim	: 1;	/* Insert Mode */
-	unsigned long	vc_deccolm	: 1;	/* 80/132 Column Mode */
-	/* attribute flags */
-	unsigned long	vc_intensity	: 2;	/* 0=half-bright, 1=normal, 2=bold */
-	unsigned long	vc_underline	: 1;
-	unsigned long	vc_blink	: 1;
-	unsigned long	vc_reverse	: 1;
-	unsigned long	vc_s_intensity	: 2;	/* saved rendition */
-	unsigned long	vc_s_underline	: 1;
-	unsigned long	vc_s_blink	: 1;
-	unsigned long	vc_s_reverse	: 1;
-	/* misc */
-	unsigned long	vc_ques		: 1;
-	unsigned long	vc_need_wrap	: 1;
-	unsigned long	vc_can_do_color	: 1;
-	unsigned long	vc_has_scrolled : 1;	/* Info for unblank_screen */
-	unsigned long	vc_kmalloced	: 1;	/* kfree_s() needed */
-	unsigned long	vc_report_mouse : 2;
-	unsigned char	vc_utf		: 1;	/* Unicode UTF-8 encoding */
-	unsigned char	vc_utf_count;
-	unsigned long	vc_utf_char;
-	unsigned long	vc_tab_stop[5];		/* Tab stops. 160 columns. */
-	unsigned short  *vc_translate;
-	unsigned char 	vc_G0_charset;
-	unsigned char 	vc_G1_charset;
-	unsigned char 	vc_saved_G0;
-	unsigned char 	vc_saved_G1;
-	unsigned int	vc_bell_pitch;		/* Console bell pitch */
-	unsigned int	vc_bell_duration;	/* Console bell duration */
-	struct consw 	*vc_sw;
-	/* additional information is in vt_kern.h */
-};
+struct vc_data;
 
 /*
  * this is what the terminal answers to a ESC-Z or csi0c query.
@@ -120,5 +57,43 @@
 #define CM_DRAW     (1)
 #define CM_ERASE    (2)
 #define CM_MOVE     (3)
+
+struct tty_struct;
+int tioclinux(struct tty_struct *tty, unsigned long arg);
+
+/* The interface for /dev/console(s) and printk output */
+
+struct console
+{
+	/*
+	 * This function should not return before the string is written.
+	 */
+	void (*write)(const char*, unsigned);
+
+        /* To unblank the console in case of panic */
+        void (*unblank)(void);
+
+	/*
+         * Only the console that was registered last with wait_key !=
+	 * NULL will be used. This blocks until there is a character
+	 * to give back, it does not schedule.
+         */
+	void (*wait_key)(void);
+
+	/*
+	 * Return the device to use when opening /dev/console. Only the
+	 * last registered console will do.
+	 */
+	int (*device)(void);
+
+	/* 
+	 * For a linked list of consoles for multiple output. Any console
+         * not at the head of the list is used only for output.
+	 */
+	struct console *next;
+};
+
+extern void register_console(struct console *);
+extern struct console *console_drivers;
 
 #endif /* linux/console.h */
diff -u --recursive --new-file v2.1.30/linux/include/linux/file.h linux/include/linux/file.h
--- v2.1.30/linux/include/linux/file.h	Tue Aug 20 02:14:31 1996
+++ linux/include/linux/file.h	Wed Apr  2 17:43:22 1997
@@ -12,14 +12,17 @@
 	return file;
 }
 
-extern void __fput(struct file *, struct inode *);
+extern int __fput(struct file *, struct inode *);
 
-extern inline void fput(struct file *file, struct inode *inode)
+extern inline int fput(struct file *file, struct inode *inode)
 {
 	int count = file->f_count-1;
+	int error = 0;
+
 	if (!count)
-		__fput(file, inode);
+		error = __fput(file, inode);
 	file->f_count = count;
+	return error;
 }
 
 #endif
diff -u --recursive --new-file v2.1.30/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.1.30/linux/include/linux/fs.h	Thu Feb  6 02:53:33 1997
+++ linux/include/linux/fs.h	Wed Apr  2 17:51:57 1997
@@ -342,6 +342,7 @@
 #define FL_FLOCK	2
 #define FL_BROKEN	4	/* broken flock() emulation */
 #define FL_ACCESS	8	/* for processes suspended by mandatory locking */
+#define FL_LOCKD	16	/* lock held by rpc.lockd */
 
 struct file_lock {
 	struct file_lock *fl_next;	/* singly linked list for this inode  */
@@ -349,20 +350,33 @@
 	struct file_lock *fl_prevlink;	/* used to simplify lock removal */
 	struct file_lock *fl_nextblock; /* circular list of blocked processes */
 	struct file_lock *fl_prevblock;
-	struct task_struct *fl_owner;
+	void *fl_owner;			/* usu. the process' task_struct */
+	unsigned int fl_pid;
 	struct wait_queue *fl_wait;
 	struct file *fl_file;
 	unsigned char fl_flags;
 	unsigned char fl_type;
 	off_t fl_start;
 	off_t fl_end;
+
+	void (*fl_notify)(struct file_lock *);	/* unblock callback */
+
+	union {
+		struct nfs_lock_info	nfs_fl;
+	} fl_u;
 };
 
+extern struct file_lock		*file_lock_table;
+
 #include <linux/fcntl.h>
 
 extern int fcntl_getlk(unsigned int fd, struct flock *l);
 extern int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l);
 extern void locks_remove_locks(struct task_struct *task, struct file *filp);
+extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
+extern int posix_lock_file(struct file *, struct file_lock *, unsigned int);
+extern void posix_block_lock(struct file_lock *, struct file_lock *);
+extern void posix_unblock_lock(struct file_lock *);
 
 #include <linux/stat.h>
 
@@ -467,11 +481,12 @@
 	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
 	int (*mmap) (struct inode *, struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
-	void (*release) (struct inode *, struct file *);
+	int (*release) (struct inode *, struct file *);
 	int (*fsync) (struct inode *, struct file *);
 	int (*fasync) (struct inode *, struct file *, int);
 	int (*check_media_change) (kdev_t dev);
 	int (*revalidate) (kdev_t dev);
+	int (*lock) (struct inode *, struct file *, int, struct file_lock *);
 };
 
 struct inode_operations {
@@ -493,6 +508,9 @@
 	void (*truncate) (struct inode *);
 	int (*permission) (struct inode *, int);
 	int (*smap) (struct inode *,int);
+	int (*updatepage) (struct inode *, struct page *, const char *,
+				unsigned long, unsigned int, int);
+	int (*revalidate) (struct inode *);
 };
 
 struct super_operations {
@@ -537,7 +555,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 int blkdev_release (struct inode * inode);
 extern struct file_operations def_blk_fops;
 extern struct inode_operations blkdev_inode_operations;
 
@@ -658,6 +676,7 @@
 extern int generic_readpage(struct inode *, struct page *);
 extern int generic_file_mmap(struct inode *, struct file *, struct vm_area_struct *);
 extern long generic_file_read(struct inode *, struct file *, char *, unsigned long);
+extern long generic_file_write(struct inode *, struct file *, const char *, unsigned long);
 
 extern void put_super(kdev_t dev);
 unsigned long generate_cluster(kdev_t dev, int b[], int size);
diff -u --recursive --new-file v2.1.30/linux/include/linux/interrupt.h linux/include/linux/interrupt.h
--- v2.1.30/linux/include/linux/interrupt.h	Thu Mar 27 14:40:10 1997
+++ linux/include/linux/interrupt.h	Mon Mar 31 11:10:41 1997
@@ -3,8 +3,10 @@
 #define _LINUX_INTERRUPT_H
 
 #include <linux/kernel.h>
+
 #include <asm/bitops.h>
 #include <asm/atomic.h>
+#include <asm/hardirq.h>
 
 struct irqaction {
 	void (*handler)(int, void *, struct pt_regs *);
@@ -77,15 +79,24 @@
  */
 extern inline void start_bh_atomic(void)
 {
+#ifdef __SMP__
 	cli();
 	atomic_inc(&intr_count);
 	sti();
+#else
+	intr_count++;
+	barrier();
+#endif
 }
 
 extern inline void end_bh_atomic(void)
 {
-	barrier();
+#ifdef __SMP__
 	atomic_dec(&intr_count);
+#else
+	barrier();
+	intr_count--;
+#endif
 }
 
 /*
diff -u --recursive --new-file v2.1.30/linux/include/linux/ipx.h linux/include/linux/ipx.h
--- v2.1.30/linux/include/linux/ipx.h	Thu Dec 12 07:14:38 1996
+++ linux/include/linux/ipx.h	Fri Mar 28 10:42:22 1997
@@ -1,6 +1,7 @@
 #ifndef _IPX_H_
 #define _IPX_H_
 #include <linux/sockios.h>
+#include <linux/socket.h>
 #define IPX_NODE_LEN	6
 #define IPX_MTU		576
 
diff -u --recursive --new-file v2.1.30/linux/include/linux/keyboard.h linux/include/linux/keyboard.h
--- v2.1.30/linux/include/linux/keyboard.h	Thu Nov  7 01:25:56 1996
+++ linux/include/linux/keyboard.h	Thu Mar 27 14:36:39 1997
@@ -19,10 +19,13 @@
 	may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
 #define MAX_NR_OF_USER_KEYMAPS 256 	/* should be at least 7 */
 
+#ifdef __KERNEL__
 extern const int NR_TYPES;
 extern const int max_vals[];
 extern unsigned short *key_maps[MAX_NR_KEYMAPS];
 extern unsigned short plain_map[NR_KEYS];
+extern struct wait_queue * keypress_wait;
+#endif
 
 #define MAX_NR_FUNC	256	/* max nr of strings assigned to keys */
 
diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp.h linux/include/linux/ncp.h
--- v2.1.30/linux/include/linux/ncp.h	Thu Feb  6 02:58:49 1997
+++ linux/include/linux/ncp.h	Fri Mar 28 10:42:23 1997
@@ -20,78 +20,42 @@
 #define NCP_DEALLOC_SLOT_REQUEST (0x5555)
 
 struct ncp_request_header {
-	__u16   type      __attribute__ ((packed));
-	__u8    sequence  __attribute__ ((packed));
-	__u8    conn_low  __attribute__ ((packed));
-	__u8    task      __attribute__ ((packed));
-	__u8    conn_high __attribute__ ((packed));
-	__u8    function  __attribute__ ((packed));
-	__u8    data[0]   __attribute__ ((packed));
+	__u16 type __attribute__((packed));
+	__u8 sequence __attribute__((packed));
+	__u8 conn_low __attribute__((packed));
+	__u8 task __attribute__((packed));
+	__u8 conn_high __attribute__((packed));
+	__u8 function __attribute__((packed));
+	__u8 data[0] __attribute__((packed));
 };
 
 #define NCP_REPLY                (0x3333)
 #define NCP_POSITIVE_ACK         (0x9999)
 
 struct ncp_reply_header {
-	__u16   type             __attribute__ ((packed));
-	__u8    sequence         __attribute__ ((packed));
-	__u8    conn_low         __attribute__ ((packed));
-	__u8    task             __attribute__ ((packed));
-	__u8    conn_high        __attribute__ ((packed));
-	__u8    completion_code  __attribute__ ((packed));
-	__u8    connection_state __attribute__ ((packed));
-	__u8    data[0]          __attribute__ ((packed));
-};
-
-
-#define NCP_BINDERY_USER (0x0001)
-#define NCP_BINDERY_UGROUP (0x0002)
-#define NCP_BINDERY_PQUEUE (0x0003)
-#define NCP_BINDERY_FSERVER (0x0004)
-#define NCP_BINDERY_NAME_LEN (48)
-struct ncp_bindery_object {
-	__u32   object_id;
-	__u16   object_type;
-	__u8    object_name[NCP_BINDERY_NAME_LEN];
-	__u8    object_flags;
-	__u8    object_security;
-	__u8    object_has_prop;
-};
-
-struct nw_property {
-	__u8    value[128];
-	__u8    more_flag;
-	__u8    property_flag;
-};
-
-struct prop_net_address {
-	__u32 network                __attribute__ ((packed));
-	__u8  node[IPX_NODE_LEN]     __attribute__ ((packed));
-	__u16 port                   __attribute__ ((packed));
+	__u16 type __attribute__((packed));
+	__u8 sequence __attribute__((packed));
+	__u8 conn_low __attribute__((packed));
+	__u8 task __attribute__((packed));
+	__u8 conn_high __attribute__((packed));
+	__u8 completion_code __attribute__((packed));
+	__u8 connection_state __attribute__((packed));
+	__u8 data[0] __attribute__((packed));
 };
 
 #define NCP_VOLNAME_LEN (16)
 #define NCP_NUMBER_OF_VOLUMES (64)
 struct ncp_volume_info {
-	__u32   total_blocks;
-	__u32   free_blocks;
-	__u32   purgeable_blocks;
-	__u32   not_yet_purgeable_blocks;
-	__u32   total_dir_entries;
-	__u32   available_dir_entries;
-	__u8    sectors_per_block;
-	char    volume_name[NCP_VOLNAME_LEN+1];
-};
-
-struct ncp_filesearch_info {
-	__u8    volume_number;
-	__u16   directory_id;
-	__u16   sequence_no;
-	__u8    access_rights;
+	__u32 total_blocks;
+	__u32 free_blocks;
+	__u32 purgeable_blocks;
+	__u32 not_yet_purgeable_blocks;
+	__u32 total_dir_entries;
+	__u32 available_dir_entries;
+	__u8 sectors_per_block;
+	char volume_name[NCP_VOLNAME_LEN + 1];
 };
 
-#define NCP_MAX_FILENAME 14
-
 /* these define the attribute byte as seen by NCP */
 #define aRONLY     (ntohl(0x01000000))
 #define aHIDDEN    (ntohl(0x02000000))
@@ -105,17 +69,6 @@
 #define AR_EXCLUSIVE (ntohs(0x2000))
 
 #define NCP_FILE_ID_LEN 6
-struct ncp_file_info {
-	__u8    file_id[NCP_FILE_ID_LEN];
-        char    file_name[NCP_MAX_FILENAME+1];
-	__u8    file_attributes;
-	__u8    file_mode;
-	__u32   file_length;
-	__u16   creation_date;
-	__u16   access_date;
-	__u16   update_date;
-	__u16   update_time;
-};
 
 /* Defines for Name Spaces */
 #define NW_NS_DOS     0
@@ -164,34 +117,33 @@
 #define AR_OPEN_COMPRESSED 0x0100
 #endif
 
-struct nw_info_struct
-{
-	__u32 spaceAlloc                  __attribute__ ((packed));
-	__u32 attributes                  __attribute__ ((packed));
-	__u16 flags                       __attribute__ ((packed));
-	__u32 dataStreamSize              __attribute__ ((packed));
-	__u32 totalStreamSize             __attribute__ ((packed));
-	__u16 numberOfStreams             __attribute__ ((packed));
-	__u16 creationTime                __attribute__ ((packed));
-	__u16 creationDate                __attribute__ ((packed));
-	__u32 creatorID                   __attribute__ ((packed));
-	__u16 modifyTime                  __attribute__ ((packed));
-	__u16 modifyDate                  __attribute__ ((packed));
-	__u32 modifierID                  __attribute__ ((packed));
-	__u16 lastAccessDate              __attribute__ ((packed));
-	__u16 archiveTime                 __attribute__ ((packed));
-	__u16 archiveDate                 __attribute__ ((packed));
-	__u32 archiverID                  __attribute__ ((packed));
-	__u16 inheritedRightsMask         __attribute__ ((packed));
-	__u32 dirEntNum                   __attribute__ ((packed));
-	__u32 DosDirNum                   __attribute__ ((packed));
-	__u32 volNumber                   __attribute__ ((packed));
-	__u32 EADataSize                  __attribute__ ((packed));
-	__u32 EAKeyCount                  __attribute__ ((packed));
-	__u32 EAKeySize                   __attribute__ ((packed));
-	__u32 NSCreator                   __attribute__ ((packed));
-	__u8  nameLen                     __attribute__ ((packed));
-	__u8  entryName[256]              __attribute__ ((packed));
+struct nw_info_struct {
+	__u32 spaceAlloc __attribute__((packed));
+	__u32 attributes __attribute__((packed));
+	__u16 flags __attribute__((packed));
+	__u32 dataStreamSize __attribute__((packed));
+	__u32 totalStreamSize __attribute__((packed));
+	__u16 numberOfStreams __attribute__((packed));
+	__u16 creationTime __attribute__((packed));
+	__u16 creationDate __attribute__((packed));
+	__u32 creatorID __attribute__((packed));
+	__u16 modifyTime __attribute__((packed));
+	__u16 modifyDate __attribute__((packed));
+	__u32 modifierID __attribute__((packed));
+	__u16 lastAccessDate __attribute__((packed));
+	__u16 archiveTime __attribute__((packed));
+	__u16 archiveDate __attribute__((packed));
+	__u32 archiverID __attribute__((packed));
+	__u16 inheritedRightsMask __attribute__((packed));
+	__u32 dirEntNum __attribute__((packed));
+	__u32 DosDirNum __attribute__((packed));
+	__u32 volNumber __attribute__((packed));
+	__u32 EADataSize __attribute__((packed));
+	__u32 EAKeyCount __attribute__((packed));
+	__u32 EAKeySize __attribute__((packed));
+	__u32 NSCreator __attribute__((packed));
+	__u8 nameLen __attribute__((packed));
+	__u8 entryName[256] __attribute__((packed));
 };
 
 /* modify mask - use with MODIFY_DOS_INFO structure */
@@ -209,97 +161,36 @@
 #define DM_INHERITED_RIGHTS_MASK  (ntohl(0x00100000L))
 #define DM_MAXIMUM_SPACE	  (ntohl(0x00200000L))
 
-struct nw_modify_dos_info
-{
-	__u32 attributes                  __attribute__ ((packed));
-	__u16 creationDate                __attribute__ ((packed));
-	__u16 creationTime                __attribute__ ((packed));
-	__u32 creatorID                   __attribute__ ((packed));
-	__u16 modifyDate                  __attribute__ ((packed));
-	__u16 modifyTime                  __attribute__ ((packed));
-	__u32 modifierID                  __attribute__ ((packed));
-	__u16 archiveDate                 __attribute__ ((packed));
-	__u16 archiveTime                 __attribute__ ((packed));
-	__u32 archiverID                  __attribute__ ((packed));
-	__u16 lastAccessDate              __attribute__ ((packed));
-	__u16 inheritanceGrantMask        __attribute__ ((packed));
-	__u16 inheritanceRevokeMask       __attribute__ ((packed));
-	__u32 maximumSpace                __attribute__ ((packed));
+struct nw_modify_dos_info {
+	__u32 attributes __attribute__((packed));
+	__u16 creationDate __attribute__((packed));
+	__u16 creationTime __attribute__((packed));
+	__u32 creatorID __attribute__((packed));
+	__u16 modifyDate __attribute__((packed));
+	__u16 modifyTime __attribute__((packed));
+	__u32 modifierID __attribute__((packed));
+	__u16 archiveDate __attribute__((packed));
+	__u16 archiveTime __attribute__((packed));
+	__u32 archiverID __attribute__((packed));
+	__u16 lastAccessDate __attribute__((packed));
+	__u16 inheritanceGrantMask __attribute__((packed));
+	__u16 inheritanceRevokeMask __attribute__((packed));
+	__u32 maximumSpace __attribute__((packed));
 };
 
 struct nw_file_info {
 	struct nw_info_struct i;
-	int   opened;
-	int   access;
-	__u32 server_file_handle          __attribute__ ((packed));
-	__u8  open_create_action          __attribute__ ((packed));
-	__u8  file_handle[6]              __attribute__ ((packed));
+	int opened;
+	int access;
+	__u32 server_file_handle __attribute__((packed));
+	__u8 open_create_action __attribute__((packed));
+	__u8 file_handle[6] __attribute__((packed));
 };
 
 struct nw_search_sequence {
-	__u8  volNumber                   __attribute__ ((packed));
-	__u32 dirBase                     __attribute__ ((packed));
-	__u32 sequence                    __attribute__ ((packed));
+	__u8 volNumber __attribute__((packed));
+	__u32 dirBase __attribute__((packed));
+	__u32 sequence __attribute__((packed));
 };
 
-struct nw_queue_job_entry {
-	__u16 InUse                       __attribute__ ((packed));
-	__u32 prev                        __attribute__ ((packed));
-	__u32 next                        __attribute__ ((packed));
-	__u32 ClientStation               __attribute__ ((packed));
-	__u32 ClientTask                  __attribute__ ((packed));
-	__u32 ClientObjectID              __attribute__ ((packed));
-	__u32 TargetServerID              __attribute__ ((packed));
-	__u8  TargetExecTime[6]           __attribute__ ((packed));
-	__u8  JobEntryTime[6]             __attribute__ ((packed));
-	__u32 JobNumber                   __attribute__ ((packed));
-	__u16 JobType                     __attribute__ ((packed));
-	__u16 JobPosition                 __attribute__ ((packed));
-	__u16 JobControlFlags             __attribute__ ((packed));
-	__u8  FileNameLen                 __attribute__ ((packed));
-	char  JobFileName[13]             __attribute__ ((packed));
-	__u32 JobFileHandle               __attribute__ ((packed));
-	__u32 ServerStation               __attribute__ ((packed));
-	__u32 ServerTaskNumber            __attribute__ ((packed));
-	__u32 ServerObjectID              __attribute__ ((packed));
-	char  JobTextDescription[50]      __attribute__ ((packed));
-	char  ClientRecordArea[152]       __attribute__ ((packed));
-};
-
-struct queue_job {
-	struct nw_queue_job_entry j;
-	__u8 file_handle[6];
-};
-
-#define QJE_OPER_HOLD	0x80
-#define QJE_USER_HOLD	0x40
-#define QJE_ENTRYOPEN	0x20
-#define QJE_SERV_RESTART    0x10
-#define QJE_SERV_AUTO	    0x08
-
-/* ClientRecordArea for print jobs */
-
-#define   KEEP_ON        0x0400
-#define   NO_FORM_FEED   0x0800
-#define   NOTIFICATION   0x1000
-#define   DELETE_FILE    0x2000
-#define   EXPAND_TABS    0x4000
-#define   PRINT_BANNER   0x8000
-
-struct print_job_record {
-    __u8  Version                         __attribute__ ((packed));
-    __u8  TabSize                         __attribute__ ((packed));
-    __u16 Copies                          __attribute__ ((packed));
-    __u16 CtrlFlags                       __attribute__ ((packed));
-    __u16 Lines                           __attribute__ ((packed));
-    __u16 Rows                            __attribute__ ((packed));
-    char  FormName[16]                    __attribute__ ((packed));
-    __u8  Reserved[6]                     __attribute__ ((packed));
-    char  BannerName[13]                  __attribute__ ((packed));
-    char  FnameBanner[13]                 __attribute__ ((packed));
-    char  FnameHeader[14]                 __attribute__ ((packed));
-    char  Path[80]                        __attribute__ ((packed));
-};
-
-
-#endif /* _LINUX_NCP_H */
+#endif				/* _LINUX_NCP_H */
diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h
--- v2.1.30/linux/include/linux/ncp_fs.h	Thu Feb  6 02:58:49 1997
+++ linux/include/linux/ncp_fs.h	Wed Apr  2 17:55:28 1997
@@ -21,22 +21,22 @@
  */
 
 struct ncp_ioctl_request {
-	unsigned int   function;
-	unsigned int   size;
-	char          *data;
+	unsigned int function;
+	unsigned int size;
+	char *data;
 };
 
 struct ncp_fs_info {
-	int    version;
+	int version;
 	struct sockaddr_ipx addr;
-	uid_t  mounted_uid;
-	int    connection;	/* Connection number the server assigned us */
-	int    buffer_size;	/* The negotiated buffer size, to be
+	uid_t mounted_uid;
+	int connection;		/* Connection number the server assigned us */
+	int buffer_size;	/* The negotiated buffer size, to be
 				   used for read/write requests! */
 
-	int    volume_number;
-	__u32  directory_id;
-};	
+	int volume_number;
+	__u32 directory_id;
+};
 
 #define	NCP_IOC_NCPREQUEST		_IOR('n', 1, struct ncp_ioctl_request)
 #define	NCP_IOC_GETMOUNTUID		_IOW('n', 2, uid_t)
@@ -53,8 +53,6 @@
 #define NCP_MAXPATHLEN 255
 #define NCP_MAXNAMELEN 14
 
-#define NCP_MSG_COMMAND "/sbin/nwmsg"
-
 #ifdef __KERNEL__
 
 /* The readdir cache size controls how many directory entries are
@@ -62,7 +60,6 @@
  */
 #define NCP_READDIR_CACHE_SIZE        64
 
-
 #define NCP_MAX_RPC_TIMEOUT (6*HZ)
 
 /* Guess, what 0x564c is :-) */
@@ -84,26 +81,25 @@
 extern int ncp_current_malloced;
 
 static inline void *
-ncp_kmalloc(unsigned int size, int priority)
+ ncp_kmalloc(unsigned int size, int priority)
 {
-        ncp_malloced += 1;
-        ncp_current_malloced += 1;
-        return kmalloc(size, priority);
+	ncp_malloced += 1;
+	ncp_current_malloced += 1;
+	return kmalloc(size, priority);
 }
 
-static inline void
-ncp_kfree_s(void *obj, int size)
+static inline void ncp_kfree_s(void *obj, int size)
 {
-        ncp_current_malloced -= 1;
-        kfree_s(obj, size);
+	ncp_current_malloced -= 1;
+	kfree_s(obj, size);
 }
 
-#else /* DEBUG_NCP_MALLOC */
+#else				/* DEBUG_NCP_MALLOC */
 
 #define ncp_kmalloc(s,p) kmalloc(s,p)
 #define ncp_kfree_s(o,s) kfree_s(o,s)
 
-#endif /* DEBUG_NCP_MALLOC */
+#endif				/* DEBUG_NCP_MALLOC */
 
 #if DEBUG_NCP > 0
 #define DPRINTK(format, args...) printk(format , ## args)
@@ -127,39 +123,35 @@
 void ncp_free_inode_info(struct ncp_inode_info *i);
 void ncp_free_all_inodes(struct ncp_server *server);
 void ncp_init_root(struct ncp_server *server);
-int  ncp_conn_logged_in(struct ncp_server *server);
+int ncp_conn_logged_in(struct ncp_server *server);
 void ncp_init_dir_cache(void);
 void ncp_invalid_dir_cache(struct inode *ino);
 struct ncp_inode_info *ncp_find_inode(struct inode *inode);
 ino_t ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info);
 void ncp_free_dir_cache(void);
-int  ncp_date_dos2unix(__u16 time, __u16 date);
-void ncp_date_unix2dos(int unix_date, __u16 *time, __u16 *date);
+int ncp_date_dos2unix(__u16 time, __u16 date);
+void ncp_date_unix2dos(int unix_date, __u16 * time, __u16 * date);
 
 
 /* linux/fs/ncpfs/ioctl.c */
-int ncp_ioctl (struct inode * inode, struct file * filp,
-               unsigned int cmd, unsigned long arg);
+int ncp_ioctl(struct inode *inode, struct file *filp,
+	      unsigned int cmd, unsigned long arg);
 
 /* linux/fs/ncpfs/inode.c */
 struct super_block *ncp_read_super(struct super_block *sb,
-                                   void *raw_data, int silent);
+				   void *raw_data, int silent);
 extern int init_ncp_fs(void);
-void ncp_trigger_message(struct ncp_server *server);
 
 /* linux/fs/ncpfs/sock.c */
 int ncp_request(struct ncp_server *server, int function);
 int ncp_connect(struct ncp_server *server);
 int ncp_disconnect(struct ncp_server *server);
-int ncp_catch_watchdog(struct ncp_server *server);
-int ncp_dont_catch_watchdog(struct ncp_server *server);
-int ncp_catch_message(struct ncp_server *server);
 void ncp_lock_server(struct ncp_server *server);
 void ncp_unlock_server(struct ncp_server *server);
 
 /* linux/fs/ncpfs/mmap.c */
-int ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma);
+int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma);
 
-#endif /* __KERNEL__ */
+#endif				/* __KERNEL__ */
 
-#endif /* _LINUX_NCP_FS_H */
+#endif				/* _LINUX_NCP_FS_H */
diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_fs_i.h linux/include/linux/ncp_fs_i.h
--- v2.1.30/linux/include/linux/ncp_fs_i.h	Thu Feb  6 02:58:49 1997
+++ linux/include/linux/ncp_fs_i.h	Fri Mar 28 10:42:23 1997
@@ -13,21 +13,21 @@
 #ifdef __KERNEL__
 
 enum ncp_inode_state {
-        NCP_INODE_VALID = 19,	/* Inode currently in use */
-        NCP_INODE_LOOKED_UP,	/* directly before iget */
-        NCP_INODE_CACHED,	/* in a path to an inode which is in use */
-        NCP_INODE_INVALID
+	NCP_INODE_VALID = 19,	/* Inode currently in use */
+	NCP_INODE_LOOKED_UP,	/* directly before iget */
+	NCP_INODE_CACHED,	/* in a path to an inode which is in use */
+	NCP_INODE_INVALID
 };
 
 /*
  * ncp fs inode data (in memory only)
  */
 struct ncp_inode_info {
-        enum ncp_inode_state state;
-        int nused;              /* for directories:
-                                   number of references in memory */
-        struct ncp_inode_info *dir;
-        struct ncp_inode_info *next, *prev;
+	enum ncp_inode_state state;
+	int nused;		/* for directories:
+				   number of references in memory */
+	struct ncp_inode_info *dir;
+	struct ncp_inode_info *next, *prev;
 	struct inode *inode;
 	struct nw_file_info finfo;
 };
diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h
--- v2.1.30/linux/include/linux/ncp_fs_sb.h	Thu Feb  6 02:58:49 1997
+++ linux/include/linux/ncp_fs_sb.h	Fri Mar 28 10:42:23 1997
@@ -17,60 +17,52 @@
 
 struct ncp_server {
 
-	struct ncp_mount_data m; /* Nearly all of the mount data is of
-				    interest for us later, so we store
-				    it completely. */
+	struct ncp_mount_data m;	/* Nearly all of the mount data is of
+					   interest for us later, so we store
+					   it completely. */
 
 	__u8 name_space[NCP_NUMBER_OF_VOLUMES];
 
 	struct file *ncp_filp;	/* File pointer to ncp socket */
-	struct file *wdog_filp;	/* File pointer to wdog socket */
-	struct file *msg_filp;	/* File pointer to message socket */
-	void *data_ready;	/* The wdog socket gets a new
-				   data_ready callback. We store the
-				   old one for checking purposes and
-				   to reset it on unmounting. */
-
-	u8         sequence;
-	u8         task;
-	u16        connection;	/* Remote connection number */
 
-	u8         completion;	/* Status message from server */
-	u8         conn_status;	/* Bit 4 = 1 ==> Server going down, no
+	u8 sequence;
+	u8 task;
+	u16 connection;		/* Remote connection number */
+
+	u8 completion;		/* Status message from server */
+	u8 conn_status;		/* Bit 4 = 1 ==> Server going down, no
 				   requests allowed anymore.
 				   Bit 0 = 1 ==> Server is down. */
 
-	int        buffer_size;	/* Negotiated bufsize */
+	int buffer_size;	/* Negotiated bufsize */
 
-	int        reply_size;	/* Size of last reply */
+	int reply_size;		/* Size of last reply */
 
-	int        packet_size;
+	int packet_size;
 	unsigned char *packet;	/* Here we prepare requests and
 				   receive replies */
 
-	int        lock;	/* To prevent mismatch in protocols. */
+	int lock;		/* To prevent mismatch in protocols. */
 	struct wait_queue *wait;
 
-	int        current_size; /* for packet preparation */
-	int        has_subfunction;
-	int        ncp_reply_size;
+	int current_size;	/* for packet preparation */
+	int has_subfunction;
+	int ncp_reply_size;
 
-        struct ncp_inode_info root;
-	char       root_path;	/* '\0' */
+	struct ncp_inode_info root;
+	char root_path;		/* '\0' */
 };
 
-static inline int
-ncp_conn_valid(struct ncp_server *server)
+static inline int ncp_conn_valid(struct ncp_server *server)
 {
 	return ((server->conn_status & 0x11) == 0);
 }
 
-static inline void
-ncp_invalidate_conn(struct ncp_server *server)
+static inline void ncp_invalidate_conn(struct ncp_server *server)
 {
 	server->conn_status |= 0x01;
 }
 
-#endif /* __KERNEL__ */
+#endif				/* __KERNEL__ */
 
 #endif
diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_mount.h linux/include/linux/ncp_mount.h
--- v2.1.30/linux/include/linux/ncp_mount.h	Thu Feb  6 02:58:49 1997
+++ linux/include/linux/ncp_mount.h	Fri Mar 28 10:42:23 1997
@@ -13,40 +13,28 @@
 #include <linux/ncp.h>
 #include <linux/ncp_fs_i.h>
 
-#define NCP_MOUNT_VERSION 2
-
-#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN)
-#define NCP_PASSWORD_LEN 20
+#define NCP_MOUNT_VERSION 3
 
 /* Values for flags */
 #define NCP_MOUNT_SOFT 0x0001
 #define NCP_MOUNT_INTR 0x0002
 
-/* Gosh... */
-#define NCP_PATH_MAX 1024
-
 struct ncp_mount_data {
 	int version;
 	unsigned int ncp_fd;	/* The socket to the ncp port */
-	unsigned int wdog_fd;	/* Watchdog packets come here */
-	unsigned int message_fd; /* Message notifications come here */
-        uid_t mounted_uid;      /* Who may umount() this filesystem? */
-
-	struct sockaddr_ipx serv_addr;
-	unsigned char server_name[NCP_BINDERY_NAME_LEN];
-
-	unsigned char mount_point[NCP_PATH_MAX+1];
-	unsigned char mounted_vol[NCP_VOLNAME_LEN+1];
+	uid_t mounted_uid;	/* Who may umount() this filesystem? */
+	pid_t wdog_pid;		/* Who cares for our watchdog packets? */
 
+	unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
 	unsigned int time_out;	/* How long should I wait after
 				   sending a NCP request? */
-	unsigned int retry_count; /* And how often should I retry? */
+	unsigned int retry_count;	/* And how often should I retry? */
 	unsigned int flags;
 
-        uid_t uid;
-        gid_t gid;
-        mode_t file_mode;
-        mode_t dir_mode;
+	uid_t uid;
+	gid_t gid;
+	mode_t file_mode;
+	mode_t dir_mode;
 };
 
 #endif
diff -u --recursive --new-file v2.1.30/linux/include/linux/net.h linux/include/linux/net.h
--- v2.1.30/linux/include/linux/net.h	Thu Mar 27 14:40:10 1997
+++ linux/include/linux/net.h	Wed Apr  2 17:43:22 1997
@@ -130,6 +130,7 @@
 extern int	sock_register(struct net_proto_family *fam);
 extern int	sock_unregister(int family);
 extern struct socket *sock_alloc(void);
+extern int	sock_create(int family, int type, int proto, struct socket **);
 extern void	sock_release(struct socket *);
 extern int   	sock_sendmsg(struct socket *, struct msghdr *m, int len);
 extern int	sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags);
diff -u --recursive --new-file v2.1.30/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v2.1.30/linux/include/linux/netdevice.h	Thu Mar 27 14:40:10 1997
+++ linux/include/linux/netdevice.h	Wed Apr  2 17:53:04 1997
@@ -309,6 +309,8 @@
 extern void		dev_add_pack(struct packet_type *pt);
 extern void		dev_remove_pack(struct packet_type *pt);
 extern struct device	*dev_get(const char *name);
+extern struct device	*dev_alloc(const char *name, int *err);
+extern int		dev_alloc_name(struct device *dev, const char *name);
 extern int		dev_open(struct device *dev);
 extern int		dev_close(struct device *dev);
 extern int		dev_queue_xmit(struct sk_buff *skb);
diff -u --recursive --new-file v2.1.30/linux/include/linux/nfs_fs_i.h linux/include/linux/nfs_fs_i.h
--- v2.1.30/linux/include/linux/nfs_fs_i.h	Fri Jul 19 22:56:51 1996
+++ linux/include/linux/nfs_fs_i.h	Wed Apr  2 17:43:22 1997
@@ -34,4 +34,9 @@
 	unsigned long attrtimeo;
 };
 
+struct nfs_lock_info {
+	u32		state;
+	unsigned int	flags;
+};
+
 #endif
diff -u --recursive --new-file v2.1.30/linux/include/linux/notifier.h linux/include/linux/notifier.h
--- v2.1.30/linux/include/linux/notifier.h	Thu Mar 27 14:40:10 1997
+++ linux/include/linux/notifier.h	Thu Mar 27 14:29:43 1997
@@ -13,7 +13,7 @@
 
 struct notifier_block
 {
-	int (*notifier_call)(struct notifier_block *this, unsigned long, void *);
+	int (*notifier_call)(struct notifier_block *self, unsigned long, void *);
 	struct notifier_block *next;
 	int priority;
 };
diff -u --recursive --new-file v2.1.30/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.1.30/linux/include/linux/pci.h	Mon Mar 17 14:54:35 1997
+++ linux/include/linux/pci.h	Mon Mar 31 12:52:31 1997
@@ -304,6 +304,7 @@
 #define PCI_VENDOR_ID_MATROX		0x102B
 #define PCI_DEVICE_ID_MATROX_MGA_2	0x0518
 #define PCI_DEVICE_ID_MATROX_MIL	0x0519
+#define PCI_DEVICE_ID_MATROX_MYS	0x051A
 #define PCI_DEVICE_ID_MATROX_MGA_IMP	0x0d10
 
 #define PCI_VENDOR_ID_CT		0x102c
diff -u --recursive --new-file v2.1.30/linux/include/linux/personality.h linux/include/linux/personality.h
--- v2.1.30/linux/include/linux/personality.h	Sun Jan 26 02:07:48 1997
+++ linux/include/linux/personality.h	Thu Mar 27 14:29:43 1997
@@ -23,7 +23,7 @@
 #define PER_XENIX		(0x0007 | STICKY_TIMEOUTS)
 
 /* Prototype for an lcall7 syscall handler. */
-typedef asmlinkage void (*lcall7_func)(struct pt_regs *);
+typedef void (*lcall7_func)(struct pt_regs *);
 
 
 /* Description of an execution domain - personality range supported,
diff -u --recursive --new-file v2.1.30/linux/include/linux/skbuff.h linux/include/linux/skbuff.h
--- v2.1.30/linux/include/linux/skbuff.h	Thu Mar 27 14:40:11 1997
+++ linux/include/linux/skbuff.h	Wed Apr  2 17:51:58 1997
@@ -448,7 +448,7 @@
 	{
 		__label__ here;
 		panic(skb_put_errstr,&&here,len);
-here:
+here:          ;
 	}
 	return tmp;
 }
@@ -462,7 +462,7 @@
 	{
 		__label__ here;
 		panic(skb_push_errstr, &&here,len);
-here:
+here:          ;
 	}
 	return skb->data;
 }
@@ -538,7 +538,6 @@
 
 #endif
 
-extern struct sk_buff *		skb_realloc_headroom(struct sk_buff *skb, int newheadroom);
 extern struct sk_buff *		skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err);
 extern unsigned int		datagram_poll(struct socket *sock, poll_table *wait);
 extern int			skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size);
diff -u --recursive --new-file v2.1.30/linux/include/linux/tty.h linux/include/linux/tty.h
--- v2.1.30/linux/include/linux/tty.h	Tue Mar  4 10:25:26 1997
+++ linux/include/linux/tty.h	Wed Apr  2 17:51:57 1997
@@ -280,7 +280,6 @@
 extern int fg_console, last_console, want_console;
 
 extern int kmsg_redirect;
-extern struct wait_queue * keypress_wait;
 
 extern unsigned long con_init(unsigned long);
 
@@ -328,14 +327,20 @@
 extern int n_tty_ioctl(struct tty_struct * tty, struct file * file,
 		       unsigned int cmd, unsigned long arg);
 
+/* serial.c */
+
+extern long serial_console_init(long kmem_start, long kmem_end);
+
 /* pcxx.c */
 
 extern int pcxe_open(struct tty_struct *tty, struct file *filp);
 
 /* console.c */
 
-extern int con_open(struct tty_struct * tty, struct file * filp);
 extern void update_screen(int new_console);
+
+/* printk.c */
+
 extern void console_print(const char *);
 
 /* vt.c */
diff -u --recursive --new-file v2.1.30/linux/include/net/sock.h linux/include/net/sock.h
--- v2.1.30/linux/include/net/sock.h	Thu Mar 27 14:40:12 1997
+++ linux/include/net/sock.h	Wed Apr  2 17:53:07 1997
@@ -500,6 +500,11 @@
   */
   
 	struct socket		*socket;
+
+  /*
+   *	RPC layer private data
+   */
+	void			*user_data;
   
   /*
    *	Callbacks 
diff -u --recursive --new-file v2.1.30/linux/include/scsi/scsi.h linux/include/scsi/scsi.h
--- v2.1.30/linux/include/scsi/scsi.h	Fri Feb  7 04:34:19 1997
+++ linux/include/scsi/scsi.h	Mon Mar 31 13:27:27 1997
@@ -132,6 +132,7 @@
 #define TYPE_SCANNER        0x06
 #define TYPE_MOD            0x07    /* Magneto-optical disk - 
 				     * - treated as TYPE_DISK */
+#define TYPE_MEDIUM_CHANGER 0x08
 #define TYPE_NO_LUN         0x7f
 
 
diff -u --recursive --new-file v2.1.30/linux/init/main.c linux/init/main.c
--- v2.1.30/linux/init/main.c	Thu Mar 27 14:40:12 1997
+++ linux/init/main.c	Thu Mar 27 14:36:39 1997
@@ -298,7 +298,9 @@
 	{ "swap=", swap_setup },
 	{ "buff=", buff_setup },
 	{ "panic=", panic_setup },
+#ifdef CONFIG_VT
 	{ "no-scroll", no_scroll },
+#endif
 #ifdef CONFIG_BUGi386
 	{ "no-hlt", no_halt },
 	{ "no387", no_387 },
@@ -1014,17 +1016,9 @@
 	}
 #endif
 
-#ifdef __sparc__
-        if (serial_console == 1) {
-                (void) open("/dev/cua0", O_RDWR, 0);
-        } else if (serial_console == 2) {
-                (void) open("/dev/cua1", O_RDWR, 0);
-        } else {
-#endif
-                (void) open("/dev/tty1", O_RDWR, 0);
-#ifdef __sparc__
-        }
-#endif
+	if (open("/dev/console",O_RDWR,0) < 0)
+		printk("Unable to open an initial console.\n");
+
 	(void) dup(0);
 	(void) dup(0);
 	
diff -u --recursive --new-file v2.1.30/linux/kernel/fork.c linux/kernel/fork.c
--- v2.1.30/linux/kernel/fork.c	Sun Jan 26 03:40:46 1997
+++ linux/kernel/fork.c	Mon Mar 31 12:52:31 1997
@@ -292,7 +292,16 @@
 	/* ok, now we should be set up.. */
 	p->swappable = 1;
 	p->exit_signal = clone_flags & CSIGNAL;
-	p->counter = current->counter >> 1;
+
+	/*
+	 * "share" dynamic priority between parent and child, thus the
+	 * total amount of dynamic priorities in the system doesnt change,
+	 * more scheduling fairness. This is only important in the first
+	 * timeslice, on the long run the scheduling behaviour is unchanged.
+	 */
+	current->counter >>= 1;
+	p->counter = current->counter;
+
 	if(p->pid) {
 		wake_up_process(p);		/* do this last, just in case */
 	} else {
diff -u --recursive --new-file v2.1.30/linux/kernel/info.c linux/kernel/info.c
--- v2.1.30/linux/kernel/info.c	Sun Jan 26 02:07:49 1997
+++ linux/kernel/info.c	Mon Mar 31 12:52:31 1997
@@ -20,11 +20,10 @@
 asmlinkage int sys_sysinfo(struct sysinfo *info)
 {
 	struct sysinfo val;
-	int err;
 
-	lock_kernel();
 	memset((char *)&val, 0, sizeof(struct sysinfo));
 
+	lock_kernel();
 	val.uptime = jiffies / HZ;
 
 	val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
@@ -35,11 +34,9 @@
 
 	si_meminfo(&val);
 	si_swapinfo(&val);
+	unlock_kernel();
 
 	if (copy_to_user(info, &val, sizeof(struct sysinfo)))
-		err = -EFAULT;
-	else
-		err = 0;
-	unlock_kernel();
-	return err;
+		return -EFAULT;
+	return 0;
 }
diff -u --recursive --new-file v2.1.30/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.1.30/linux/kernel/ksyms.c	Thu Mar 27 14:40:12 1997
+++ linux/kernel/ksyms.c	Wed Apr  2 17:43:23 1997
@@ -49,6 +49,7 @@
 #include <linux/genhd.h>
 #include <linux/swap.h>
 #include <linux/ctype.h>
+#include <linux/file.h>
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
 extern struct drive_info_struct drive_info;
@@ -74,7 +75,7 @@
 extern char *get_options(char *str, int *ints);
 extern void set_device_ro(int dev,int flag);
 extern struct file_operations * get_blkfops(unsigned int);
-extern void blkdev_release(struct inode * inode);
+extern int blkdev_release(struct inode * inode);
 
 extern void *sys_call_table;
 
@@ -114,6 +115,7 @@
 EXPORT_SYMBOL(do_mmap);
 EXPORT_SYMBOL(do_munmap);
 EXPORT_SYMBOL(exit_mm);
+EXPORT_SYMBOL(exit_files);
 
 /* internal kernel memory management */
 EXPORT_SYMBOL(__get_free_pages);
@@ -132,6 +134,7 @@
 /* filesystem internal functions */
 EXPORT_SYMBOL(getname);
 EXPORT_SYMBOL(putname);
+EXPORT_SYMBOL(__fput);
 EXPORT_SYMBOL(__iget);
 EXPORT_SYMBOL(iput);
 EXPORT_SYMBOL(namei);
@@ -161,8 +164,14 @@
 EXPORT_SYMBOL(dcache_add);
 EXPORT_SYMBOL(add_blkdev_randomness);
 EXPORT_SYMBOL(generic_file_read);
+EXPORT_SYMBOL(generic_file_write);
 EXPORT_SYMBOL(generic_file_mmap);
 EXPORT_SYMBOL(generic_readpage);
+EXPORT_SYMBOL(file_lock_table);
+EXPORT_SYMBOL(posix_lock_file);
+EXPORT_SYMBOL(posix_test_lock);
+EXPORT_SYMBOL(posix_block_lock);
+EXPORT_SYMBOL(posix_unblock_lock);
 
 /* device registration */
 EXPORT_SYMBOL(register_chrdev);
@@ -308,6 +317,7 @@
 EXPORT_SYMBOL(unregister_reboot_notifier);
 EXPORT_SYMBOL(_ctype);
 EXPORT_SYMBOL(secure_tcp_sequence_number);
+EXPORT_SYMBOL(get_random_bytes);
 
 /* Signal interfaces */
 EXPORT_SYMBOL(send_sig);
@@ -352,7 +362,9 @@
 
 /* psaux mouse */
 EXPORT_SYMBOL(aux_device_present);
+#ifdef CONFIG_VT
 EXPORT_SYMBOL(kbd_read_mask);
+#endif
 
 #ifdef CONFIG_BLK_DEV_MD
 EXPORT_SYMBOL(disk_name);	/* for md.c */
diff -u --recursive --new-file v2.1.30/linux/kernel/module.c linux/kernel/module.c
--- v2.1.30/linux/kernel/module.c	Wed Jan 29 03:40:34 1997
+++ linux/kernel/module.c	Fri Mar 28 10:53:02 1997
@@ -65,10 +65,7 @@
 	kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
 
 #ifdef __alpha__
-	{
-		register unsigned long gp __asm__("$29");
-		kernel_module.gp = gp;
-	}
+	__asm__("stq $29,%0" : "=m"(kernel_module.gp));
 #endif
 }
 
diff -u --recursive --new-file v2.1.30/linux/kernel/panic.c linux/kernel/panic.c
--- v2.1.30/linux/kernel/panic.c	Thu Mar 27 14:40:12 1997
+++ linux/kernel/panic.c	Thu Mar 27 14:36:39 1997
@@ -17,7 +17,7 @@
 #include <linux/reboot.h>
 
 asmlinkage void sys_sync(void);	/* it's really int */
-extern void do_unblank_screen(void);
+extern void unblank_console(void);
 extern int C_A_D;
 
 int panic_timeout = 0;
@@ -43,7 +43,7 @@
 	else
 		sys_sync();
 
-	do_unblank_screen();
+	unblank_console();
 
 #ifdef __SMP__
 	smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0);
diff -u --recursive --new-file v2.1.30/linux/kernel/printk.c linux/kernel/printk.c
--- v2.1.30/linux/kernel/printk.c	Thu Mar 27 14:40:12 1997
+++ linux/kernel/printk.c	Thu Mar 27 14:36:39 1997
@@ -23,6 +23,7 @@
 #include <linux/tty_driver.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/console.h>
 
 #include <asm/uaccess.h>
 
@@ -30,8 +31,6 @@
 
 static char buf[1024];
 
-extern void console_print(const char *);
-
 /* printk's without a loglevel use this.. */
 #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
 
@@ -43,7 +42,7 @@
 struct wait_queue * log_wait = NULL;
 int console_loglevel = DEFAULT_CONSOLE_LOGLEVEL;
 
-static void (*console_print_proc)(const char *) = 0;
+struct console *console_drivers = NULL;
 static char log_buf[LOG_BUF_LEN];
 static unsigned long log_start = 0;
 static unsigned long logged_chars = 0;
@@ -209,11 +208,13 @@
 			if (*p == '\n')
 				break;
 		}
-		if (msg_level < console_loglevel && console_print_proc) {
-			char tmp = p[1];
-			p[1] = '\0';
-			(*console_print_proc)(msg);
-			p[1] = tmp;
+		if (msg_level < console_loglevel && console_drivers) {
+			struct console *c = console_drivers;
+			while(c) {
+				if (c->write)
+					c->write(msg, p - msg + 1);
+				c = c->next;
+			}
 		}
 		if (*p == '\n')
 			msg_level = -1;
@@ -223,21 +224,43 @@
 	return i;
 }
 
+void console_print(const char *s)
+{
+	struct console *c = console_drivers;
+	int len = strlen(s);
+	while(c) {
+		if (c->write)
+			c->write(s, len);
+		c = c->next;
+	}
+}
+
+void unblank_console(void)
+{
+	struct console *c = console_drivers;
+	while(c) {
+		if (c->unblank)
+			c->unblank();
+		c = c->next;
+	}
+}
+
 /*
  * The console driver calls this routine during kernel initialization
  * to register the console printing procedure with printk() and to
  * print any messages that were printed by the kernel before the
  * console driver was initialized.
  */
-void register_console(void (*proc)(const char *))
+void register_console(struct console * console)
 {
-	int	i,j;
+	int	i,j,len;
 	int	p = log_start;
 	char	buf[16];
 	signed char msg_level = -1;
 	char	*q;
 
-	console_print_proc = proc;
+	console->next = console_drivers;
+	console_drivers = console;
 
 	for (i=0,j=0; i < log_size; i++) {
 		buf[j++] = log_buf[p];
@@ -246,12 +269,14 @@
 			continue;
 		buf[j] = 0;
 		q = buf;
+		len = j;
 		if (msg_level < 0) {
 			msg_level = buf[1] - '0';
 			q = buf + 3;
+			len -= 3;
 		}
 		if (msg_level < console_loglevel)
-			(*proc)(q);
+			console->write(q, len);
 		if (buf[j-1] == '\n')
 			msg_level = -1;
 		j = 0;
diff -u --recursive --new-file v2.1.30/linux/kernel/sched.c linux/kernel/sched.c
--- v2.1.30/linux/kernel/sched.c	Thu Mar 27 14:40:12 1997
+++ linux/kernel/sched.c	Mon Mar 31 12:52:31 1997
@@ -1553,11 +1553,11 @@
 
 asmlinkage int sys_sched_yield(void)
 {
-	spin_unlock(&scheduler_lock);
+	spin_lock(&scheduler_lock);
 	spin_lock_irq(&runqueue_lock);
 	move_last_runqueue(current);
 	spin_unlock_irq(&runqueue_lock);
-	spin_lock(&scheduler_lock);
+	spin_unlock(&scheduler_lock);
 	need_resched = 1;
 	return 0;
 }
@@ -1629,48 +1629,46 @@
 
 asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
 {
-	int error = -EFAULT;
 	struct timespec t;
 	unsigned long expire;
 
-	lock_kernel();
 	if(copy_from_user(&t, rqtp, sizeof(struct timespec)))
-		goto out;
+		return -EFAULT;
 
-	error = -EINVAL;
 	if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
-		goto out;
+		return -EINVAL;
+
 
 	if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
-	    current->policy != SCHED_OTHER) {
+	    current->policy != SCHED_OTHER) 
+	{
 		/*
 		 * Short delay requests up to 2 ms will be handled with
 		 * high precision by a busy wait for all real-time processes.
+		 *
+		 * Its important on SMP not to do this holding locks.
 		 */
 		udelay((t.tv_nsec + 999) / 1000);
-		error = 0;
-		goto out;
+		return 0;
 	}
 
 	expire = timespectojiffies(&t) + (t.tv_sec || t.tv_nsec) + jiffies;
+	lock_kernel();
 	current->timeout = expire;
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
+	unlock_kernel();
 
-	error = 0;
 	if (expire > jiffies) {
 		if (rmtp) {
 			jiffiestotimespec(expire - jiffies -
 					  (expire > jiffies + 1), &t);
-			error = -EFAULT;
 			if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
-				goto out;
+				return -EFAULT;
 		}
-		error = -EINTR;
+		return -EINTR;
 	}
-out:
-	unlock_kernel();
-	return error;
+	return 0;
 }
 
 static void show_task(int nr,struct task_struct * p)
diff -u --recursive --new-file v2.1.30/linux/kernel/sys.c linux/kernel/sys.c
--- v2.1.30/linux/kernel/sys.c	Thu Mar 27 14:40:12 1997
+++ linux/kernel/sys.c	Mon Mar 31 12:52:31 1997
@@ -893,14 +893,13 @@
 			gid_t *groups = current->groups;
 			do {
 				if (*groups == grp)
-					goto out;
+					break;
 				groups++;
 				i--;
 			} while (i);
 		}
 		return 0;
 	}
-out:
 	return 1;
 }
 
diff -u --recursive --new-file v2.1.30/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.1.30/linux/kernel/sysctl.c	Mon Mar 17 14:54:35 1997
+++ linux/kernel/sysctl.c	Mon Mar 31 12:52:32 1997
@@ -197,25 +197,17 @@
 	if (nlen == 0 || nlen >= CTL_MAXNAME)
 		return -ENOTDIR;
 	
-	error = verify_area(VERIFY_READ,name,nlen*sizeof(int));
-	if (error) return error;
-	if (oldval) {
+	if (oldval) 
+	{
 		int old_len;
 		if (!oldlenp)
 			return -EFAULT;
-		error = verify_area(VERIFY_WRITE,oldlenp,sizeof(size_t));
-		if (error) return error;
-		get_user(old_len, oldlenp);
-		error = verify_area(VERIFY_WRITE,oldval,old_len);
-		if (error) return error;
-	}
-	if (newval) {
-		error = verify_area(VERIFY_READ,newval,newlen);
-		if (error) return error;
+		if(get_user(old_len, oldlenp))
+			return -EFAULT;
 	}
 	tmp = &root_table_header;
 	do {
-		context = 0;
+		context = NULL;
 		error = parse_table(name, nlen, oldval, oldlenp, 
 				    newval, newlen, tmp->ctl_table, &context);
 		if (context)
@@ -232,14 +224,12 @@
 	struct __sysctl_args tmp;
 	int error;
 
+	if(copy_from_user(&tmp, args, sizeof(tmp)))
+		return -EFAULT;
+		
 	lock_kernel();
-	error = verify_area(VERIFY_READ, args, sizeof(*args));
-	if (error)
-		goto out;
-	copy_from_user(&tmp, args, sizeof(tmp));
 	error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
 			  tmp.newval, tmp.newlen);
-out:
 	unlock_kernel();
 	return error;
 }
@@ -266,6 +256,7 @@
 
 /* ctl_perm does NOT grant the superuser all rights automatically, because
    some sysctl variables are readonly even to root. */
+
 static int test_perm(int mode, int op)
 {
 	if (!current->euid)
@@ -276,6 +267,7 @@
 		return 0;
 	return -EACCES;
 }
+
 static inline int ctl_perm(ctl_table *table, int op)
 {
 	return test_perm(table->mode, op);
@@ -293,7 +285,8 @@
 
 	for ( ; table->ctl_name; table++) {
 		int n;
-		get_user(n,name);
+		if(get_user(n,name))
+			return -EFAULT;
 		if (n == table->ctl_name ||
 		    table->ctl_name == CTL_ANY) {
 			if (table->child) {
@@ -353,15 +346,18 @@
 			if (len) {
 				if (len > table->maxlen)
 					len = table->maxlen;
-				copy_to_user(oldval, table->data, len);
-				put_user(len, oldlenp);
+				if(copy_to_user(oldval, table->data, len))
+					return -EFAULT;
+				if(put_user(len, oldlenp))
+					return -EFAULT;
 			}
 		}
 		if (newval && newlen) {
 			len = newlen;
 			if (len > table->maxlen)
 				len = table->maxlen;
-			copy_from_user(table->data, newval, len);
+			if(copy_from_user(table->data, newval, len))
+				return -EFAULT;
 		}
 	}
 	return 0;
@@ -382,7 +378,8 @@
 	if (newval && newlen) {
 		if (newlen != sizeof (int))
 			return -EINVAL;
-		copy_from_user (&level, newval, newlen);
+		if(copy_from_user (&level, newval, newlen))
+			return -EFAULT;
 		if (level < securelevel && current->pid != 1)
 			return -EPERM;
 	}
@@ -499,10 +496,6 @@
 	size_t res;
 	long error;
 	
-	error = verify_area(write ? VERIFY_READ : VERIFY_WRITE, buf, count);
-	if (error)
-		return error;
-
 	de = (struct proc_dir_entry*) inode->u.generic_ip;
 	if (!de || !de->data)
 		return -ENOTDIR;
@@ -553,14 +546,16 @@
 		len = 0;
 		p = buffer;
 		while (len < *lenp) {
-			get_user(c, p++);
+			if(get_user(c, p++))
+				return -EFAULT;
 			if (c == 0 || c == '\n')
 				break;
 			len++;
 		}
 		if (len >= table->maxlen)
 			len = table->maxlen-1;
-		copy_from_user(table->data, buffer, len);
+		if(copy_from_user(table->data, buffer, len))
+			return -EFAULT;
 		((char *) table->data)[len] = 0;
 		filp->f_pos += *lenp;
 	} else {
@@ -570,9 +565,11 @@
 		if (len > *lenp)
 			len = *lenp;
 		if (len)
-			copy_to_user(buffer, table->data, len);
+			if(copy_to_user(buffer, table->data, len))
+				return -EFAULT;
 		if (len < *lenp) {
-			put_user('\n', ((char *) buffer) + len);
+			if(put_user('\n', ((char *) buffer) + len))
+				return -EFAULT;
 			len++;
 		}
 		*lenp = len;
@@ -602,7 +599,8 @@
 		if (write) {
 			while (left) {
 				char c;
-				get_user(c,(char *) buffer);
+				if(get_user(c,(char *) buffer))
+					return -EFAULT;
 				if (!isspace(c))
 					break;
 				left--;
@@ -614,7 +612,8 @@
 			len = left;
 			if (len > TMPBUFLEN-1)
 				len = TMPBUFLEN-1;
-			copy_from_user(buf, buffer, len);
+			if(copy_from_user(buf, buffer, len))
+				return -EFAULT;
 			buf[len] = 0;
 			p = buf;
 			if (*p == '-' && left > 1) {
@@ -640,21 +639,24 @@
 			len = strlen(buf);
 			if (len > left)
 				len = left;
-			copy_to_user(buffer, buf, len);
+			if(copy_to_user(buffer, buf, len))
+				return -EFAULT;
 			left -= len;
 			buffer += len;
 		}
 	}
 
 	if (!write && !first && left) {
-		put_user('\n', (char *) buffer);
+		if(put_user('\n', (char *) buffer))
+			return -EFAULT;
 		left--, buffer++;
 	}
 	if (write) {
 		p = (char *) buffer;
 		while (left) {
 			char c;
-			get_user(c, p++);
+			if(get_user(c, p++))
+				return -EFAULT;
 			if (!isspace(c))
 				break;
 			left--;
@@ -690,7 +692,8 @@
 		if (write) {
 			while (left) {
 				char c;
-				get_user(c, (char *) buffer);
+				if(get_user(c, (char *) buffer))
+					return -EFAULT;
 				if (!isspace(c))
 					break;
 				left--;
@@ -702,7 +705,8 @@
 			len = left;
 			if (len > TMPBUFLEN-1)
 				len = TMPBUFLEN-1;
-			copy_from_user(buf, buffer, len);
+			if(copy_from_user(buf, buffer, len))
+				return -EFAULT;
 			buf[len] = 0;
 			p = buf;
 			if (*p == '-' && left > 1) {
@@ -733,21 +737,24 @@
 			len = strlen(buf);
 			if (len > left)
 				len = left;
-			copy_to_user(buffer, buf, len);
+			if(copy_to_user(buffer, buf, len))
+				return -EFAULT;
 			left -= len;
 			buffer += len;
 		}
 	}
 
 	if (!write && !first && left) {
-		put_user('\n', (char *) buffer);
+		if(put_user('\n', (char *) buffer))
+			return -EFAULT;
 		left--, buffer++;
 	}
 	if (write) {
 		p = (char *) buffer;
 		while (left) {
 			char c;
-			get_user(c, p++);
+			if(get_user(c, p++))
+				return -EFAULT;
 			if (!isspace(c))
 				break;
 			left--;
@@ -798,22 +805,27 @@
 		return -ENOTDIR;
 	
 	if (oldval && oldlenp) {
-		get_user(len, oldlenp);
+		if(get_user(len, oldlenp))
+			return -EFAULT;
 		if (len) {
 			l = strlen(table->data);
 			if (len > l) len = l;
 			if (len >= table->maxlen)
 				len = table->maxlen;
-			copy_to_user(oldval, table->data, len);
-			put_user(0, ((char *) oldval) + len);
-			put_user(len, oldlenp);
+			if(copy_to_user(oldval, table->data, len))
+				return -EFAULT;
+			if(put_user(0, ((char *) oldval) + len))
+				return -EFAULT;
+			if(put_user(len, oldlenp))
+				return -EFAULT;
 		}
 	}
 	if (newval && newlen) {
 		len = newlen;
 		if (len > table->maxlen)
 			len = table->maxlen;
-		copy_from_user(table->data, newval, len);
+		if(copy_from_user(table->data, newval, len))
+			return -EFAULT;
 		if (len == table->maxlen)
 			len--;
 		((char *) table->data)[len] = 0;
@@ -870,14 +882,16 @@
 		return -EINVAL;
 	if (oldval) {
 		int old_l;
-		get_user(old_l, oldlenp);
+		if(get_user(old_l, oldlenp))
+			return -EFAULT;
 		if (l > old_l)
 			return -ENOMEM;
-		put_user(l, oldlenp);
-		copy_to_user(oldval, data, l);
+		if(put_user(l, oldlenp) || copy_to_user(oldval, data, l))
+			return -EFAULT;
 	}
 	if (newval) {
-		copy_from_user(data, newval, newlen);
+		if(copy_from_user(data, newval, newlen))
+			return -EFAULT;
 		data[newlen] = 0;
 	}
 	return 0;
@@ -893,14 +907,16 @@
 		return -EINVAL;
 	if (oldval) {
 		int old_l;
-		get_user(old_l, oldlenp);
+		if(get_user(old_l, oldlenp))
+			return -EFAULT;
 		if (old_l < sizeof(int))
 			return -ENOMEM;
-		put_user(sizeof(int), oldlenp);
-		copy_to_user(oldval, data, sizeof(int));
+		if(put_user(sizeof(int), oldlenp)||copy_to_user(oldval, data, sizeof(int)))
+			return -EFAULT;
 	}
 	if (newval)
-		copy_from_user(data, newval, sizeof(int));
+		if(copy_from_user(data, newval, sizeof(int)))
+			return -EFAULT;
 	return 0;
 }
 
@@ -914,14 +930,16 @@
 		return -EINVAL;
 	if (oldval) {
 		int old_l;
-		get_user(old_l, oldlenp);
+		if(get_user(old_l, oldlenp))
+			return -EFAULT;
 		if (old_l < len)
 			return -ENOMEM;
-		put_user(len, oldlenp);
-		copy_to_user(oldval, data, len);
+		if(put_user(len, oldlenp) || copy_to_user(oldval, data, len))
+			return -EFAULT;
 	}
 	if (newval)
-		copy_from_user(data, newval, len);
+		if(copy_from_user(data, newval, len))
+			return -EFAULT;
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.30/linux/kernel/time.c linux/kernel/time.c
--- v2.1.30/linux/kernel/time.c	Thu Mar 27 14:40:12 1997
+++ linux/kernel/time.c	Mon Mar 31 12:52:32 1997
@@ -156,32 +156,33 @@
 	static int	firsttime = 1;
 	struct timeval	new_tv;
 	struct timezone new_tz;
-	int err = -EPERM;
 
-	lock_kernel();
 	if (!suser())
-		goto out;
-	err = -EFAULT;
+		return -EPERM;
+		
 	if (tv) {
 		if (copy_from_user(&new_tv, tv, sizeof(*tv)))
-			goto out;
+			return -EFAULT;
 	}
 	if (tz) {
 		if (copy_from_user(&new_tz, tz, sizeof(*tz)))
-			goto out;
+			return -EFAULT;
+		lock_kernel();
 		sys_tz = new_tz;
 		if (firsttime) {
 			firsttime = 0;
 			if (!tv)
 				warp_clock();
 		}
+		unlock_kernel();
 	}
 	if (tv)
+	{
+		lock_kernel();
 		do_settimeofday(&new_tv);
-	err = 0;
-out:
-	unlock_kernel();
-	return err;
+		unlock_kernel();
+	}
+	return 0;
 }
 
 long pps_offset = 0;		/* pps time offset (us) */
@@ -208,33 +209,32 @@
 asmlinkage int sys_adjtimex(struct timex *txc_p)
 {
         long ltemp, mtemp, save_adjust;
-	int error = -EFAULT;
 	struct timex txc;		/* Local copy of parameter */
 
-	lock_kernel();
 	/* Copy the user data space into the kernel copy
 	 * structure. But bear in mind that the structures
 	 * may change
 	 */
 	if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
-		goto out;	
+		return -EFAULT;
 
 	/* In order to modify anything, you gotta be super-user! */
-	error = -EPERM;
 	if (txc.modes && !suser())
-		goto out;
-
+		return -EPERM;
+		
 	/* Now we validate the data before disabling interrupts */
-	error = -EINVAL;
+
 	if (txc.modes != ADJ_OFFSET_SINGLESHOT && (txc.modes & ADJ_OFFSET))
 	  /* adjustment Offset limited to +- .512 seconds */
-	  if (txc.offset <= - MAXPHASE || txc.offset >= MAXPHASE )
-	    goto out;
+		if (txc.offset <= - MAXPHASE || txc.offset >= MAXPHASE )
+			return -EINVAL;	
 
 	/* if the quartz is off by more than 10% something is VERY wrong ! */
 	if (txc.modes & ADJ_TICK)
-	  if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ)
-	    goto out;
+		if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ)
+			return -EINVAL;
+
+	lock_kernel();
 
 	cli();
 
@@ -351,9 +351,6 @@
 	txc.stbcnt	   = pps_stbcnt;
 
 	sti();
-
-	error = copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state;
-out:
 	unlock_kernel();
-	return error;
+	return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state;
 }
diff -u --recursive --new-file v2.1.30/linux/mm/filemap.c linux/mm/filemap.c
--- v2.1.30/linux/mm/filemap.c	Thu Mar 27 14:40:12 1997
+++ linux/mm/filemap.c	Wed Apr  2 17:43:23 1997
@@ -1275,3 +1275,118 @@
 	unlock_kernel();
 	return error;
 }
+
+/*
+ * Write to a file through the page cache. This is mainly for the
+ * benefit of NFS and possibly other network-based file systems.
+ *
+ * We currently put everything into the page cache prior to writing it.
+ * This is not a problem when writing full pages. With partial pages,
+ * however, we first have to read the data into the cache, then
+ * dirty the page, and finally schedule it for writing. Alternatively, we
+ * could write-through just the portion of data that would go into that
+ * page, but that would kill performance for applications that write data
+ * line by line, and it's prone to race conditions.
+ *
+ * Note that this routine doesn't try to keep track of dirty pages. Each
+ * file system has to do this all by itself, unfortunately.
+ *							okir@monad.swb.de
+ */
+long
+generic_file_write(struct inode *inode, struct file *file, const char *buf, unsigned long count)
+{
+	struct page	*page, **hash;
+	unsigned long	page_cache = 0;
+	unsigned long	ppos, offset;
+	unsigned int	bytes, written;
+	unsigned long	pos;
+	int		status, sync, didread = 0;
+
+	if (!inode->i_op || !inode->i_op->updatepage)
+		return -EIO;
+
+	sync    = file->f_flags & O_SYNC;
+	pos     = file->f_pos;
+	written = 0;
+	status  = 0;
+
+	if (file->f_flags & O_APPEND)
+		pos = inode->i_size;
+
+	while (count) {
+		/*
+		 * Try to find the page in the cache. If it isn't there,
+		 * allocate a free page.
+		 */
+		offset = (pos & ~PAGE_MASK);
+		ppos = pos & PAGE_MASK;
+
+		if ((bytes = PAGE_SIZE - offset) > count)
+			bytes = count;
+
+		hash = page_hash(inode, ppos);
+		if (!(page = __find_page(inode, ppos, *hash))) {
+			if (!page_cache) {
+				page_cache = __get_free_page(GFP_KERNEL);
+				if (!page_cache) {
+					status = -ENOMEM;
+					break;
+				}
+				continue;
+			}
+			page = mem_map + MAP_NR(page_cache);
+			add_to_page_cache(page, inode, ppos, hash);
+			page_cache = 0;
+		}
+
+lockit:
+		while (set_bit(PG_locked, &page->flags))
+			wait_on_page(page);
+
+		/*
+		 * If the page is not uptodate, and we're writing less
+		 * than a full page of data, we may have to read it first.
+		 * However, don't bother with reading the page when it's
+		 * after the current end of file.
+		 */
+		if (!PageUptodate(page)) {
+			/* Already tried to read it twice... too bad */
+			if (didread > 1) {
+				status = -EIO;
+				break;
+			}
+			if (bytes < PAGE_SIZE && ppos < inode->i_size) {
+				/* readpage implicitly unlocks the page */
+				status = inode->i_op->readpage(inode, page);
+				if (status < 0)
+					break;
+				didread++;
+				goto lockit;
+			}
+			set_bit(PG_uptodate, &page->flags);
+		}
+		didread = 0;
+
+		/* Alright, the page is there, and we've locked it. Now
+		 * update it. */
+		status = inode->i_op->updatepage(inode, page, buf,
+							offset, bytes, sync);
+		free_page(page_address(page));
+		if (status < 0)
+			break;
+
+		written += status;
+		count -= status;
+		pos += status;
+		buf += status;
+	}
+	file->f_pos = pos;
+	if (pos > inode->i_size)
+		inode->i_size = pos;
+
+	if (page_cache)
+		free_page(page_cache);
+	if (written)
+		return written;
+	return status;
+}
diff -u --recursive --new-file v2.1.30/linux/net/802/fddi.c linux/net/802/fddi.c
--- v2.1.30/linux/net/802/fddi.c	Thu Feb 27 10:57:32 1997
+++ linux/net/802/fddi.c	Mon Mar 31 12:52:32 1997
@@ -132,7 +132,7 @@
 	if(fddi->hdr.llc_8022_1.dsap==0xe0)
 	{
 		skb_pull(skb, FDDI_K_8022_HLEN-3);
-		type=htons(ETH_P_8022);
+		type=htons(ETH_P_802_2);
 	}
 	else
 	{
diff -u --recursive --new-file v2.1.30/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v2.1.30/linux/net/appletalk/ddp.c	Thu Mar 27 14:40:13 1997
+++ linux/net/appletalk/ddp.c	Mon Mar 31 12:52:32 1997
@@ -259,6 +259,7 @@
 		else
 			iface = &tmp->next;
 	}
+	MOD_DEC_USE_COUNT;
 }
 
 static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *sa)
@@ -277,6 +278,7 @@
 	iface->next=atalk_iface_list;
 	atalk_iface_list=iface;
 	restore_flags(flags);
+	MOD_INC_USE_COUNT;
 	return iface;
 }
 
@@ -705,6 +707,8 @@
 			else
 			{
 				atif=atif_add_device(dev, &sa->sat_addr);
+				if (atif == NULL)
+					return -ENOMEM;
 			}
 			atif->nets= *nr;
 
diff -u --recursive --new-file v2.1.30/linux/net/core/dev.c linux/net/core/dev.c
--- v2.1.30/linux/net/core/dev.c	Sun Feb  2 05:18:49 1997
+++ linux/net/core/dev.c	Mon Mar 31 12:52:32 1997
@@ -250,7 +250,46 @@
 	}
 	return(NULL);
 }
-	
+
+/*
+ *	Passed a format string - eg "lt%d" it will try and find a suitable
+ *	id. Not efficient for many devices, not called a lot..
+ */
+
+int dev_alloc_name(struct device *dev, const char *name)
+{
+	int i;
+	/*
+	 *	If you need over 100 please also fix the algorithm...
+	 */
+	for(i=0;i<100;i++)
+	{
+		sprintf(dev->name,name,i);
+		if(dev_get(dev->name)==NULL)
+			return i;
+	}
+	return -ENFILE;	/* Over 100 of the things .. bail out! */
+}
+ 
+struct device *dev_alloc(const char *name, int *err)
+{
+	struct device *dev=kmalloc(sizeof(struct device)+16, GFP_KERNEL);
+	if(dev==NULL)
+	{
+		*err=-ENOBUFS;
+		return NULL;
+	}
+	dev->name=(char *)(dev+1);	/* Name string space */
+	*err=dev_alloc_name(dev,name);
+	if(*err<0)
+	{
+		kfree(dev);
+		return NULL;
+	}
+	return dev;
+}
+
+
 /*
  *	Find and possibly load an interface.
  */
@@ -560,7 +599,7 @@
 			}
 		} 
 		else
-			printk("%s: !skb->arp & !rebuild_header!\n", dev->name);
+			printk(KERN_DEBUG "%s: !skb->arp & !rebuild_header!\n", dev->name);
 	}
 
 	/*
@@ -592,7 +631,7 @@
 	skb_pull(newskb, newskb->nh.raw - newskb->data);
 	newskb->ip_summed = CHECKSUM_UNNECESSARY;
 	if (newskb->dst==NULL)
-		printk("BUG: packet without dst looped back 1\n");
+		printk(KERN_DEBUG "BUG: packet without dst looped back 1\n");
 	netif_rx(newskb);
 }
 
@@ -880,7 +919,7 @@
 	 */
 
 	if (net_alias_is(dev)) {
-		printk("net alias %s transmits\n", dev->name);
+		printk(KERN_DEBUG "net alias %s transmits\n", dev->name);
 		return;
 	}
 
@@ -1010,7 +1049,7 @@
 	int size;
 	
 	if (stats)
-		size = sprintf(buffer, "%6s:%8ld %7ld %4ld %4ld %4ld %4ld %8ld %8ld %4ld %4ld %4ld %5ld %4ld\n",
+		size = sprintf(buffer, "%6s:%8lu %7lu %4lu %4lu %4lu %4lu %8lu %8lu %4lu %4lu %4lu %5lu %4lu\n",
 		   dev->name,
 		   stats->rx_bytes,
 		   stats->rx_packets, stats->rx_errors,
diff -u --recursive --new-file v2.1.30/linux/net/core/sock.c linux/net/core/sock.c
--- v2.1.30/linux/net/core/sock.c	Thu Mar 27 14:40:15 1997
+++ linux/net/core/sock.c	Wed Apr  2 17:43:23 1997
@@ -322,9 +322,15 @@
 		    char *optval, int *optlen)
 {
 	struct sock *sk = sock->sk;
-  	int val;
-  	struct linger ling;
-  	int len;
+	
+	union
+	{
+  		int val;
+  		struct linger ling;
+		struct timeval tm;
+	} v;
+	
+	int lv=sizeof(int),len;
   	
   	if(get_user(len,optlen))
   		return -EFAULT;
@@ -332,119 +338,110 @@
   	switch(optname) 
   	{
 		case SO_DEBUG:		
-			val = sk->debug;
+			v.val = sk->debug;
 			break;
 		
 		case SO_DONTROUTE:
-			val = sk->localroute;
+			v.val = sk->localroute;
 			break;
 		
 		case SO_BROADCAST:
-			val= sk->broadcast;
+			v.val= sk->broadcast;
 			break;
 
 		case SO_SNDBUF:
-			val=sk->sndbuf;
+			v.val=sk->sndbuf;
 			break;
 		
 		case SO_RCVBUF:
-			val =sk->rcvbuf;
+			v.val =sk->rcvbuf;
 			break;
 
 		case SO_REUSEADDR:
-			val = sk->reuse;
+			v.val = sk->reuse;
 			break;
 
 		case SO_KEEPALIVE:
-			val = sk->keepopen;
+			v.val = sk->keepopen;
 			break;
 
 		case SO_TYPE:
-			val = sk->type;		  		
+			v.val = sk->type;		  		
 			break;
 
 		case SO_ERROR:
-			val = -sock_error(sk);
-			if(val==0)
-				val=xchg(&sk->err_soft,0);
+			v.val = -sock_error(sk);
+			if(v.val==0)
+				v.val=xchg(&sk->err_soft,0);
 			break;
 
 		case SO_OOBINLINE:
-			val = sk->urginline;
+			v.val = sk->urginline;
 			break;
 	
 		case SO_NO_CHECK:
-			val = sk->no_check;
+			v.val = sk->no_check;
 			break;
 
 		case SO_PRIORITY:
-			val = sk->priority;
+			v.val = sk->priority;
 			break;
 		
 		case SO_LINGER:	
-		  {
-			len=min(len,sizeof(ling));
-			if (put_user(len, optlen)) 
-				return -EFAULT;
-			ling.l_onoff=sk->linger;
-			ling.l_linger=sk->lingertime;
-			if (copy_to_user(optval,&ling,len))
-				return -EFAULT;
-			return 0;
-		  }
-		
+			lv=sizeof(v.ling);
+			v.ling.l_onoff=sk->linger;
+ 			v.ling.l_linger=sk->lingertime;
+			break;
+					
 		case SO_BSDCOMPAT:
-			val = sk->bsdism;
+			v.val = sk->bsdism;
 			break;
 			
 		case SO_RCVTIMEO:
 		case SO_SNDTIMEO:
-		{
-			static struct timeval tm={0,0};
-			len=min(len, sizeof(struct timeval));
-			if(put_user(len,optlen))
-				return -EFAULT;
-			if(copy_to_user(optval,&tm,len))
-				return -EFAULT;
-			return 0;
-		}
+			lv=sizeof(struct timeval);
+			v.tm.tv_sec=0;
+			v.tm.tv_usec=0;
+			break;
+
 		case SO_RCVLOWAT:
 		case SO_SNDLOWAT:
-			val=1;
+			v.val=1;
 
 		case SO_PASSCRED:
-			val = sock->passcred;
+			v.val = sock->passcred;
 			break;
 
 		case SO_PEERCRED:
-			len=min(len, sizeof(sk->peercred));
-			if(put_user(len, optlen))
-				return -EFAULT;
+			lv=sizeof(sk->peercred);
+			len=min(len, lv);
 			if(copy_to_user((void*)optval, &sk->peercred, len))
 				return -EFAULT;
-			return 0;
+			goto lenout;
+			
+#ifdef CONFIG_NET_SECURITY			
 			
 		case SO_SECURITY_AUTHENTICATION:
-			val = sk->authentication;
+			v.val = sk->authentication;
 			break;
 			
 		case SO_SECURITY_ENCRYPTION_TRANSPORT:
-			val = sk->encryption;
+			v.val = sk->encryption;
 			break;
 			
 		case SO_SECURITY_ENCRYPTION_NETWORK:
-			val = sk->encrypt_net;
+			v.val = sk->encrypt_net;
 			break;
-			
+#endif
 		default:
 			return(-ENOPROTOOPT);
 	}
-	len=min(len,sizeof(int));
+	len=min(len,lv);
+	if(copy_to_user(optval,&v,len))
+		return -EFAULT;
+lenout:
   	if(put_user(len, optlen))
   		return -EFAULT;
-	if(copy_to_user(optval,&val,len))
-		return -EFAULT;
-
   	return 0;
 }
 
@@ -487,7 +484,7 @@
 #endif
 #if 1
 	if (!sk) {
-		printk("sock_wfree: sk==NULL\n");
+		printk(KERN_DEBUG "sock_wfree: sk==NULL\n");
 		return;
 	}
 #endif
@@ -505,7 +502,7 @@
 #endif	
 #if 1
 	if (!sk) {
-		printk("sock_rfree: sk==NULL\n");
+		printk(KERN_DEBUG "sock_rfree: sk==NULL\n");
 		return;
 	}
 #endif
@@ -581,17 +578,12 @@
 struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, unsigned long fallback, int noblock, int *errcode)
 {
 	struct sk_buff *skb;
-	int err;
 
 	do
 	{
 		if(sk->err!=0)
 		{
-			cli();
-			err= -sk->err;
-			sk->err=0;
-			sti();
-			*errcode=err;
+			*errcode=xchg(&sk->err,0);
 			return NULL;
 		}
 		
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.1.30/linux/net/ipv4/af_inet.c	Tue Mar  4 10:25:26 1997
+++ linux/net/ipv4/af_inet.c	Mon Mar 31 12:52:32 1997
@@ -183,7 +183,7 @@
 	 * [PR]
 	 */
 		  
-	printk("Socket destroy delayed (r=%d w=%d)\n",
+	printk(KERN_DEBUG "Socket destroy delayed (r=%d w=%d)\n",
 	       sk->rmem_alloc, sk->wmem_alloc);
 
 	sk->destroy = 1;
@@ -1067,7 +1067,7 @@
 	struct sk_buff *dummy_skb;
 	struct inet_protocol *p;
 
-	printk("Swansea University Computer Society TCP/IP for NET3.037\n");
+	printk(KERN_INFO "Swansea University Computer Society TCP/IP for NET3.037\n");
 
 	if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb))
 	{
@@ -1087,7 +1087,7 @@
 	 *	Add all the protocols. 
 	 */
 
-	printk("IP Protocols: ");
+	printk(KERN_INFO "IP Protocols: ");
 	for(p = inet_protocol_base; p != NULL;) 
 	{
 		struct inet_protocol *tmp = (struct inet_protocol *) p->next;
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v2.1.30/linux/net/ipv4/arp.c	Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/arp.c	Mon Mar 31 12:52:32 1997
@@ -348,7 +348,7 @@
 	return;
 }
 
-static void __inline__ arp_free(struct arp_table **entryp)
+static void arp_free(struct arp_table **entryp)
 {
 	struct arp_table *entry = *entryp;
 	*entryp = entry->u.next;
@@ -802,7 +802,7 @@
 	if (how > 1 && arp_unres_size >= ARP_MAX_UNRES) {
 		arp_unres_expire();
 		if (arp_unres_size >= ARP_MAX_UNRES) {
-			printk("arp_unres_size=%d\n", arp_unres_size);
+			printk(KERN_DEBUG "arp_unres_size=%d\n", arp_unres_size);
 			return NULL;
 		}
 	}
@@ -1817,16 +1817,6 @@
 			if (err)
 				return -EFAULT;
 			break;
-		case OLD_SIOCDARP:
-		case OLD_SIOCSARP:
-			if (!suser())
-				return -EPERM;
-		case OLD_SIOCGARP:
-			err = copy_from_user(&r, arg, sizeof(struct arpreq_old));
-			if (err)
-				return -EFAULT;
-			memset(&r.arp_dev, 0, sizeof(r.arp_dev));
-			break;
 		default:
 			return -EINVAL;
 	}
@@ -1857,46 +1847,10 @@
 		        return arp_req_delete(&r, dev);
 		case SIOCSARP:
 			return arp_req_set(&r, dev);
-		case OLD_SIOCDARP:
-			/* old  SIOCDARP destroys both
-			 * normal and proxy mappings
-			 */
-			r.arp_flags &= ~ATF_PUBL;
-			err = arp_req_delete(&r, dev);
-			r.arp_flags |= ATF_PUBL;
-			if (!err)
-				arp_req_delete(&r, dev);
-			else
-				err = arp_req_delete(&r, dev);
-			return err;
-		case OLD_SIOCSARP:
-			err = arp_req_set(&r, dev);
-			/* old SIOCSARP works so funny,
-			 * that its behaviour can be emulated
-			 * only approximately 8).
-			 * It should work. --ANK
-			 */
-			if (r.arp_flags & ATF_PUBL)
-			{	
-				r.arp_flags &= ~ATF_PUBL;
-				arp_req_delete(&r, dev);
-			}
-			return err;
 		case SIOCGARP:
 			err = arp_req_get(&r, dev);
 			if (!err)
 				err = copy_to_user(arg, &r, sizeof(r));
-			return err;
-		case OLD_SIOCGARP:
-			r.arp_flags &= ~ATF_PUBL;
-			err = arp_req_get(&r, dev);
-			if (err < 0)
-			{
-				r.arp_flags |= ATF_PUBL;
-				err = arp_req_get(&r, dev);
-			}
-			if (!err)
-				err = copy_to_user(arg, &r, sizeof(struct arpreq_old));
 			return err;
 	}
 	/*NOTREACHED*/
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/fib.c linux/net/ipv4/fib.c
--- v2.1.30/linux/net/ipv4/fib.c	Sun Feb  2 05:18:49 1997
+++ linux/net/ipv4/fib.c	Mon Mar 31 12:52:32 1997
@@ -1600,7 +1600,7 @@
 	} else {
 		u32 mask = ((struct sockaddr_in*)&r.rt_genmask)->sin_addr.s_addr;
 		if (r.rt_genmask.sa_family != AF_INET) {
-			printk(KERN_WARNING "%s forgot to specify route netmask.\n", current->comm);
+			printk(KERN_DEBUG "%s forgot to specify route netmask.\n", current->comm);
 			if (r.rt_genmask.sa_family)
 				return -EAFNOSUPPORT;
 		}
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/igmp.c linux/net/ipv4/igmp.c
--- v2.1.30/linux/net/ipv4/igmp.c	Thu Feb 27 10:57:32 1997
+++ linux/net/ipv4/igmp.c	Mon Mar 31 12:52:32 1997
@@ -210,7 +210,7 @@
 	  im->tm_running=0;
   }
   else
-	  printk(KERN_ERR "igmp_stop_timer() called with timer not running by %p\n",__builtin_return_address(0));
+	  printk(KERN_DEBUG "igmp_stop_timer() called with timer not running by %p\n",__builtin_return_address(0));
 }
 
 extern __inline__ unsigned int random(void)
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c
--- v2.1.30/linux/net/ipv4/ip_forward.c	Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/ip_forward.c	Mon Mar 31 12:52:32 1997
@@ -218,7 +218,7 @@
 			kfree_skb(skb, FREE_WRITE);
 
 			if (skb2 == NULL) {
-				NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
+				NETDEBUG(printk(KERN_ERR "\nIP: No memory available for IP forward\n"));
 				return -1;
 			}
 			skb = skb2;
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c
--- v2.1.30/linux/net/ipv4/ip_fragment.c	Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/ip_fragment.c	Mon Mar 31 12:52:32 1997
@@ -87,7 +87,7 @@
 	fp = (struct ipfrag *) frag_kmalloc(sizeof(struct ipfrag), GFP_ATOMIC);
 	if (fp == NULL)
 	{
-		NETDEBUG(printk("IP: frag_create: no memory left !\n"));
+		NETDEBUG(printk(KERN_ERR "IP: frag_create: no memory left !\n"));
 		return(NULL);
 	}
 	memset(fp, 0, sizeof(struct ipfrag));
@@ -249,7 +249,7 @@
 	qp = (struct ipq *) frag_kmalloc(sizeof(struct ipq), GFP_ATOMIC);
 	if (qp == NULL)
 	{
-		NETDEBUG(printk("IP: create: no memory left !\n"));
+		NETDEBUG(printk(KERN_ERR "IP: create: no memory left !\n"));
 		return(NULL);
 	}
 	memset(qp, 0, sizeof(struct ipq));
@@ -262,7 +262,7 @@
 	qp->iph = (struct iphdr *) frag_kmalloc(64 + 8, GFP_ATOMIC);
 	if (qp->iph == NULL)
 	{
-		NETDEBUG(printk("IP: create: no memory left !\n"));
+		NETDEBUG(printk(KERN_ERR "IP: create: no memory left !\n"));
 		frag_kfree_s(qp, sizeof(struct ipq));
 		return(NULL);
 	}
@@ -343,7 +343,7 @@
 	
 	if(len>65535)
 	{
-		printk("Oversized IP packet from %s.\n", in_ntoa(qp->iph->saddr));
+		printk(KERN_INFO "Oversized IP packet from %s.\n", in_ntoa(qp->iph->saddr));
 		ip_statistics.IpReasmFails++;
 		ip_free(qp);
 		return NULL;
@@ -352,7 +352,7 @@
 	if ((skb = dev_alloc_skb(len)) == NULL)
 	{
 		ip_statistics.IpReasmFails++;
-		NETDEBUG(printk("IP: queue_glue: no memory for gluing queue %p\n", qp));
+		NETDEBUG(printk(KERN_ERR "IP: queue_glue: no memory for gluing queue %p\n", qp));
 		ip_free(qp);
 		return(NULL);
 	}
@@ -373,7 +373,7 @@
 	{
 		if(count+fp->len > skb->len)
 		{
-			NETDEBUG(printk("Invalid fragment list: Fragment over size.\n"));
+			NETDEBUG(printk(KERN_ERR "Invalid fragment list: Fragment over size.\n"));
 			ip_free(qp);
 			kfree_skb(skb,FREE_WRITE);
 			ip_statistics.IpReasmFails++;
@@ -485,7 +485,7 @@
 	 
 	if(ntohs(iph->tot_len)+(int)offset>65535)
 	{
-		printk("Oversized packet received from %s\n",in_ntoa(iph->saddr));
+		printk(KERN_INFO "Oversized packet received from %s\n",in_ntoa(iph->saddr));
 		frag_kfree_skb(skb, FREE_READ);
 		ip_statistics.IpReasmFails++;
 		return NULL;
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq.c linux/net/ipv4/ip_masq.c
--- v2.1.30/linux/net/ipv4/ip_masq.c	Fri Dec 27 02:04:49 1996
+++ linux/net/ipv4/ip_masq.c	Mon Mar 31 12:52:32 1997
@@ -122,7 +122,7 @@
         unsigned hash;
 
         if (ms->flags & IP_MASQ_F_HASHED) {
-                printk("ip_masq_hash(): request for already hashed\n");
+                printk(KERN_INFO "ip_masq_hash(): request for already hashed\n");
                 return 0;
         }
         /*
@@ -155,7 +155,7 @@
         unsigned hash;
         struct ip_masq ** ms_p;
         if (!(ms->flags & IP_MASQ_F_HASHED)) {
-                printk("ip_masq_unhash(): request for unhash flagged\n");
+                printk(KERN_INFO "ip_masq_unhash(): request for unhash flagged\n");
                 return 0;
         }
         /*
@@ -349,14 +349,14 @@
 
         if (*free_ports_p == 0) {
                 if (++n_fails < 5)
-                        printk("ip_masq_new(proto=%s): no free ports.\n",
+                        printk(KERN_ERR "ip_masq_new(proto=%s): no free ports.\n",
                                masq_proto_name(proto));
                 return NULL;
         }
         ms = (struct ip_masq *) kmalloc(sizeof(struct ip_masq), GFP_ATOMIC);
         if (ms == NULL) {
                 if (++n_fails < 5)
-                        printk("ip_masq_new(proto=%s): no memory available.\n",
+                        printk(KERN_ERR "ip_masq_new(proto=%s): no memory available.\n",
                                masq_proto_name(proto));
                 return NULL;
         }
@@ -416,7 +416,7 @@
         }
 
         if (++n_fails < 5)
-                printk("ip_masq_new(proto=%s): could not get free masq entry (free=%d).\n",
+                printk(KERN_ERR "ip_masq_new(proto=%s): could not get free masq entry (free=%d).\n",
                        masq_proto_name(ms->protocol), *free_ports_p);
         kfree_s(ms, sizeof(*ms));
         return NULL;
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_app.c linux/net/ipv4/ip_masq_app.c
--- v2.1.30/linux/net/ipv4/ip_masq_app.c	Fri Dec 27 02:04:49 1996
+++ linux/net/ipv4/ip_masq_app.c	Mon Mar 31 12:52:32 1997
@@ -73,7 +73,7 @@
         unsigned long flags;
         unsigned hash;
         if (!mapp) {
-                printk("register_ip_masq_app(): NULL arg\n");
+                printk(KERN_ERR "register_ip_masq_app(): NULL arg\n");
                 return -EINVAL;
         }
         mapp->type = IP_MASQ_APP_TYPE(proto, port);
@@ -99,14 +99,14 @@
         unsigned hash;
         unsigned long flags;
         if (!mapp) {
-                printk("unregister_ip_masq_app(): NULL arg\n");
+                printk(KERN_ERR "unregister_ip_masq_app(): NULL arg\n");
                 return -EINVAL;
         }
         /*
          * only allow unregistration if it has no attachments
          */
         if (mapp->n_attach)  {
-                printk("unregister_ip_masq_app(): has %d attachments. failed\n",
+                printk(KERN_ERR "unregister_ip_masq_app(): has %d attachments. failed\n",
                        mapp->n_attach);
                 return -EINVAL;
         }
@@ -122,7 +122,7 @@
                 }
 
         restore_flags(flags);
-        printk("unregister_ip_masq_app(proto=%s,port=%u): not hashed!\n",
+        printk(KERN_ERR "unregister_ip_masq_app(proto=%s,port=%u): not hashed!\n",
                masq_proto_name(IP_MASQ_APP_PROTO(mapp->type)), IP_MASQ_APP_PORT(mapp->type));
         return -EINVAL;
 }
@@ -164,7 +164,7 @@
         n_at = mapp->n_attach + delta;
         if (n_at < 0) {
                 restore_flags(flags);
-                printk("ip_masq_app: tried to set n_attach < 0 for (proto=%s,port==%d) ip_masq_app object.\n",
+                printk(KERN_ERR "ip_masq_app: tried to set n_attach < 0 for (proto=%s,port==%d) ip_masq_app object.\n",
                        masq_proto_name(IP_MASQ_APP_PROTO(mapp->type)),
                        IP_MASQ_APP_PORT(mapp->type));
                 return -1;
@@ -189,7 +189,7 @@
                  */
 
                 if (ms->app != NULL) {
-                        printk("ip_masq_bind_app() called for already bound object.\n");
+                        printk(KERN_ERR "ip_masq_bind_app() called for already bound object.\n");
                         return ms->app;
                 }
 
@@ -528,7 +528,7 @@
 
                 n_skb = alloc_skb(MAX_HEADER + skb->len + diff, pri);
                 if (n_skb == NULL) {
-                        printk("skb_replace(): no room left (from %p)\n",
+                        printk(KERN_ERR "skb_replace(): no room left (from %p)\n",
                                __builtin_return_address(0));
                         return skb;
 
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_ftp.c linux/net/ipv4/ip_masq_ftp.c
--- v2.1.30/linux/net/ipv4/ip_masq_ftp.c	Fri Jan  3 01:33:27 1997
+++ linux/net/ipv4/ip_masq_ftp.c	Mon Mar 31 12:52:32 1997
@@ -214,7 +214,7 @@
 void cleanup_module(void)
 {
         if (ip_masq_ftp_done() != 0)
-                printk("ip_masq_ftp: can't remove module");
+                printk(KERN_INFO "ip_masq_ftp: can't remove module");
 }
 
 #endif /* MODULE */
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_irc.c linux/net/ipv4/ip_masq_irc.c
--- v2.1.30/linux/net/ipv4/ip_masq_irc.c	Fri Jan  3 01:33:27 1997
+++ linux/net/ipv4/ip_masq_irc.c	Mon Mar 31 12:52:32 1997
@@ -265,7 +265,7 @@
 void cleanup_module(void)
 {
         if (ip_masq_irc_done() != 0)
-                printk("ip_masq_irc: can't remove module");
+                printk(KERN_INFO "ip_masq_irc: can't remove module");
 }
 
 #endif /* MODULE */
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_raudio.c linux/net/ipv4/ip_masq_raudio.c
--- v2.1.30/linux/net/ipv4/ip_masq_raudio.c	Fri Jan  3 01:33:27 1997
+++ linux/net/ipv4/ip_masq_raudio.c	Mon Mar 31 12:52:32 1997
@@ -227,7 +227,7 @@
 void cleanup_module(void)
 {
         if (ip_masq_raudio_done() != 0)
-                printk("ip_masq_raudio: can't remove module");
+                printk(KERN_INFO "ip_masq_raudio: can't remove module");
 }
 
 #endif /* MODULE */
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- v2.1.30/linux/net/ipv4/ip_output.c	Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/ip_output.c	Mon Mar 31 12:52:32 1997
@@ -836,7 +836,7 @@
 		 */
 
 		if ((skb2 = alloc_skb(len+hlen+15,GFP_ATOMIC)) == NULL) {
-			NETDEBUG(printk("IP: frag: no memory for new fragment!\n"));
+			NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));
 			ip_statistics.IpFragFails++;
 			kfree_skb(skb, FREE_WRITE);
 			return;
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c
--- v2.1.30/linux/net/ipv4/ipmr.c	Thu Feb 27 10:57:32 1997
+++ linux/net/ipv4/ipmr.c	Mon Mar 31 12:52:32 1997
@@ -17,6 +17,9 @@
  *	Malcolm Beattie		:	Buffer handling fixes.
  *	Alexey Kuznetsov	:	Double buffer free and other fixes.
  *	SVR Anand		:	Fixed several multicast bugs and problems.
+ *	Alexey Kuznetsov	:	Status, optimisations and more.
+ *	Brad Parker		:	Better behaviour on mrouted upcall
+ *					overflow.
  *
  *	Status:
  *		Cache manager under test. Forwarding in vague test mode
@@ -264,15 +267,16 @@
  *	expects the following bizarre scheme..
  */
  
-static void ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
+static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
 {
 	struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
 	int ihl = pkt->nh.iph->ihl<<2;
 	struct igmphdr *igmp;
 	struct igmpmsg *msg;
+	int ret;
 
 	if(!skb)
-		return;
+		return -ENOMEM;
 		
 	/*
 	 *	Copy the IP header
@@ -299,9 +303,16 @@
 	/*
 	 *	Deliver to mrouted
 	 */
-	if(sock_queue_rcv_skb(mroute_socket,skb)<0)
+	if((ret=sock_queue_rcv_skb(mroute_socket,skb))<0)
 	{
+		static unsigned long last_warn;
+		if(jiffies-last_warn>10*HZ)
+		{
+			last_warn=jiffies;
+			printk("mroute: pending queue full, dropping entries.\n");
+		}
 		kfree_skb(skb, FREE_READ);
+		return ret;
 	}
 }
 
@@ -342,7 +353,12 @@
 		 *	Reflect first query at mrouted.
 		 */
 		if(mroute_socket)
-			ipmr_cache_report(skb, vifi, 0);
+		{
+			/* If the report failed throw the cache entry 
+			   out - Brad Parker */
+			if(ipmr_cache_report(skb, vifi, 0)<0)
+				impr_cache_delete(cache);
+		}
 	}
 	/*
 	 *	See if we can append the packet
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- v2.1.30/linux/net/ipv4/raw.c	Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/raw.c	Mon Mar 31 12:52:32 1997
@@ -285,7 +285,7 @@
 		if (usin->sin_family != AF_INET) {
 			static int complained;
 			if (!complained++)
-				printk("%s forgot to set AF_INET in raw sendmsg. Fix it!\n", current->comm);
+				printk(KERN_INFO "%s forgot to set AF_INET in raw sendmsg. Fix it!\n", current->comm);
 			if (usin->sin_family)
 				return -EINVAL;
 		}
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.1.30/linux/net/ipv4/tcp.c	Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/tcp.c	Mon Mar 31 12:52:32 1997
@@ -1290,7 +1290,7 @@
 			 * shouldn't happen
 			 */
 			if (before(*seq, skb->seq)) {
-				printk("recvmsg bug: copied %X seq %X\n",
+				printk(KERN_INFO "recvmsg bug: copied %X seq %X\n",
 				       *seq, skb->seq);
 				break;
 			}
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.1.30/linux/net/ipv4/tcp_ipv4.c	Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/tcp_ipv4.c	Mon Mar 31 12:52:32 1997
@@ -1284,7 +1284,7 @@
 	case CHECKSUM_HW:
 		if (tcp_v4_check(th,len,saddr,daddr,skb->csum)) {
 			struct iphdr * iph = skb->nh.iph;
-			printk("TCPv4 bad checksum from %08x:%04x to %08x:%04x, len=%d/%d/%d\n",
+			printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, len=%d/%d/%d\n",
 			       saddr, ntohs(th->source), daddr,
 			       ntohs(th->dest), len, skb->len, ntohs(iph->tot_len));
 					goto discard_it;
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.1.30/linux/net/ipv4/tcp_output.c	Thu Mar 27 14:40:16 1997
+++ linux/net/ipv4/tcp_output.c	Mon Mar 31 12:52:32 1997
@@ -112,7 +112,7 @@
 
 	if (size < sizeof(struct tcphdr) || size > skb->len) 
 	{
-		printk("tcp_send_skb: bad skb (skb = %p, data = %p, th = %p, len = %u)\n",
+		printk(KERN_DEBUG "tcp_send_skb: bad skb (skb = %p, data = %p, th = %p, len = %u)\n",
 			skb, skb->data, th, skb->len);
 		kfree_skb(skb, FREE_WRITE);
 		return 0;
@@ -130,7 +130,7 @@
                  */
 		if(!th->syn && !th->fin) 
 		{
-			printk("tcp_send_skb: attempt to queue a bogon.\n");
+			printk(KERN_DEBUG "tcp_send_skb: attempt to queue a bogon.\n");
 			kfree_skb(skb,FREE_WRITE);
 			return 0;
 		}
@@ -770,7 +770,7 @@
 	if (buff == NULL)
 	{
 		/* This is a disaster if it occurs */
-		printk("tcp_send_fin: Impossible malloc failure");
+		printk(KERN_INFO "tcp_send_fin: Impossible malloc failure");
 		return;
 	}
 
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.1.30/linux/net/ipv4/tcp_timer.c	Thu Mar 27 14:40:16 1997
+++ linux/net/ipv4/tcp_timer.c	Mon Mar 31 12:52:32 1997
@@ -69,7 +69,7 @@
 
 	if((long)when <= 0)
 	{		
-		printk("xmit_timer <= 0 - timer:%d when:%lx\n", what, when);
+		printk(KERN_DEBUG "xmit_timer <= 0 - timer:%d when:%lx\n", what, when);
 		when=HZ/50;
 	}
 
@@ -100,11 +100,11 @@
 		break;	
 
 	case TIME_WRITE:
-		printk("bug: tcp_reset_xmit_timer TIME_WRITE\n");
+		printk(KERN_DEBUG "bug: tcp_reset_xmit_timer TIME_WRITE\n");
 		break;
 
 	default:
-		printk("bug: unknown timer value\n");
+		printk(KERN_DEBUG "bug: unknown timer value\n");
 	}
 }
 
@@ -123,7 +123,7 @@
 		del_timer(&tp->probe_timer);
 		break;	
 	default:
-		printk("bug: unknown timer value\n");
+		printk(KERN_DEBUG "bug: unknown timer value\n");
 	}
 }
 
@@ -142,7 +142,7 @@
 		return tp->probe_timer.next != NULL;
 		break;	
 	default:
-		printk("bug: unknown timer value\n");
+		printk(KERN_DEBUG "bug: unknown timer value\n");
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/timer.c linux/net/ipv4/timer.c
--- v2.1.30/linux/net/ipv4/timer.c	Thu Mar 27 14:40:16 1997
+++ linux/net/ipv4/timer.c	Mon Mar 31 12:52:32 1997
@@ -122,7 +122,7 @@
 
 			if (sk->state != TCP_CLOSE) 
 			{
-				printk ("non CLOSE socket in time_done\n");
+				printk (KERN_DEBUG "non CLOSE socket in time_done\n");
 				break;
 			}
 			destroy_sock (sk);
@@ -148,7 +148,7 @@
 			break;
 
 		default:
-			printk ("net_timer: timer expired - reason %d is unknown\n", why);
+			printk (KERN_DEBUG "net_timer: timer expired - reason %d is unknown\n", why);
 			break;
 	}
 }
diff -u --recursive --new-file v2.1.30/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- v2.1.30/linux/net/ipv4/udp.c	Thu Mar 27 14:40:16 1997
+++ linux/net/ipv4/udp.c	Wed Apr  2 17:45:33 1997
@@ -52,6 +52,7 @@
  *		David S. Miller	:	New socket lookup architecture.
  *					Last socket cache retained as it
  *					does have a high hit rate.
+ *		Olaf Kirch	:	Don't linearise iovec on sendmsg.
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -505,7 +506,8 @@
 	u32 saddr;
 	u32 daddr;
 	u32 other;
-	const char *from;
+	struct iovec *iov;
+	int nriov;
 	u32 wcheck;
 };
 
@@ -519,20 +521,36 @@
 static int udp_getfrag(const void *p, char * to, unsigned int offset, unsigned int fraglen) 
 {
 	struct udpfakehdr *ufh = (struct udpfakehdr *)p;
-	const char *src;
-	char *dst;
+	struct iovec *iov;
+	char *src;
+	char *dst = to;
 	unsigned int len;
 
-	if (offset) {
-		len = fraglen;
-	 	src = ufh->from+(offset-sizeof(struct udphdr));
-	 	dst = to;
-	} else {
-		len = fraglen-sizeof(struct udphdr);
- 		src = ufh->from;
-		dst = to+sizeof(struct udphdr);
+	if (offset == 0) {
+		fraglen -= sizeof(struct udphdr);
+		dst += sizeof(struct udphdr);
 	}
-	ufh->wcheck = csum_partial_copy_fromuser(src, dst, len, ufh->wcheck);
+
+	iov = ufh->iov;
+	do {
+		if ((len = iov->iov_len) > fraglen)
+			len = fraglen;
+		src = (char *) iov->iov_base + iov->iov_len - len;
+		ufh->wcheck = csum_partial_copy_fromuser(src,
+						dst + fraglen - len, len,
+						ufh->wcheck);
+		if ((iov->iov_len -= len) == 0) {
+			if (--(ufh->nriov) < 0) {
+				printk(KERN_NOTICE "udp_getfrag: nriov = %d\n",
+							ufh->nriov);
+				return -EINVAL;
+			}
+			iov--;
+		}
+		fraglen -= len;
+	} while (fraglen);
+	ufh->iov = iov;
+
 	if (offset == 0) {
  		ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr),
  				   ufh->wcheck);
@@ -556,29 +574,42 @@
 static int udp_getfrag_nosum(const void *p, char * to, unsigned int offset, unsigned int fraglen) 
 {
 	struct udpfakehdr *ufh = (struct udpfakehdr *)p;
-	const char *src;
-	char *dst;
+	struct iovec *iov;
+	char *src;
+	char *dst = to;
 	int err;
 	unsigned int len;
 
-	if (offset) {
-		len = fraglen;
-	 	src = ufh->from+(offset-sizeof(struct udphdr));
-	 	dst = to;
-	} else {
-		len = fraglen-sizeof(struct udphdr);
- 		src = ufh->from;
-		dst = to+sizeof(struct udphdr);
+	if (offset == 0) {
+		fraglen -= sizeof(struct udphdr);
+	 	dst += sizeof(struct udphdr);
 	}
-	err = copy_from_user(dst,src,len);
+
+	iov = ufh->iov;
+	do {
+		if ((len = iov->iov_len) > fraglen)
+			len = fraglen;
+		src = (char *) iov->iov_base + iov->iov_len - len;
+		err = copy_from_user(dst + fraglen - len, src, len);
+		fraglen -= len;
+		if ((iov->iov_len -= len) == 0) {
+			if (--(ufh->nriov) < 0) {
+				printk(KERN_NOTICE "udp_getfrag: nriov = %d\n",
+							ufh->nriov);
+				return -EINVAL;
+			}
+			iov--;
+		}
+	} while (fraglen && err >= 0);
+	ufh->iov = iov;
+
 	if (offset == 0) 
 		memcpy(to, ufh, sizeof(struct udphdr));
 	return err;
 }
 
 
-static int udp_sendto(struct sock *sk, const unsigned char *from, int len,
-		      struct msghdr *msg)
+int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len)
 {
 	int ulen = len + sizeof(struct udphdr);
 	struct device *dev = NULL;
@@ -675,7 +706,8 @@
 	ufh.uh.len = htons(ulen);
 	ufh.uh.check = 0;
 	ufh.other = (htons(ulen) << 16) + IPPROTO_UDP*256;
-	ufh.from = from;
+	ufh.iov = msg->msg_iov + msg->msg_iovlen - 1;
+	ufh.nriov = msg->msg_iovlen;
 	ufh.wcheck = 0;
 
 	/* RFC1122: OK.  Provides the checksumming facility (MUST) as per */
@@ -703,44 +735,6 @@
 }
 
 /*
- *	Temporary
- */
- 
-int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len)
-{
-	if(msg->msg_iovlen==1)
-		return udp_sendto(sk,msg->msg_iov[0].iov_base,len, msg);
-	else {
-		/*
-		 *	For awkward cases we linearise the buffer first. In theory this is only frames
-		 *	whose iovec's don't split on 4 byte boundaries, and soon encrypted stuff (to keep
-		 *	skip happy). We are a bit more general about it.
-		 */
-		 
-		unsigned char *buf;
-		int fs;
-		int err;
-		if(len>65515)
-			return -EMSGSIZE;
-		buf=kmalloc(len, GFP_KERNEL);
-		if(buf==NULL)
-			return -ENOBUFS;
-		err = memcpy_fromiovec(buf, msg->msg_iov, len);
-		if (err)
-			err = -EFAULT;
-		if (!err)
-		{
-			fs=get_fs();
-			set_fs(get_ds());
-			err=udp_sendto(sk,buf,len, msg);
-			set_fs(fs);
-		}
-		kfree_s(buf,len);
-		return err;
-	}
-}
-
-/*
  *	IOCTL requests applicable to the UDP protocol
  */
  
@@ -1063,7 +1057,7 @@
 	ulen = ntohs(uh->len);
 	
 	if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) {
-		NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
+		NETDEBUG(printk(KERN_DEBUG "UDP: short packet: %d/%d\n", ulen, len));
 		udp_statistics.UdpInErrors++;
 		kfree_skb(skb, FREE_WRITE);
 		return(0);
@@ -1086,7 +1080,7 @@
 		/* RFC1122: OK.  Discards the bad packet silently (as far as */
 		/* the network is concerned, anyway) as per 4.1.3.4 (MUST). */
 
-		NETDEBUG(printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
+		NETDEBUG(printk(KERN_DEBUG "UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
 		       ntohl(saddr),ntohs(uh->source),
 		       ntohl(daddr),ntohs(uh->dest),
 		       ulen));
diff -u --recursive --new-file v2.1.30/linux/net/netlink.c linux/net/netlink.c
--- v2.1.30/linux/net/netlink.c	Sat Jan 25 13:46:14 1997
+++ linux/net/netlink.c	Wed Apr  2 17:43:23 1997
@@ -151,12 +151,13 @@
 	return -EUNATCH;
 }
 
-static void netlink_release(struct inode * inode, struct file * file)
+static int netlink_release(struct inode * inode, struct file * file)
 {
 	unsigned int minor = MINOR(inode->i_rdev);
 	if (file->f_mode & FMODE_READ)
 		open_map&=~(1<<minor);
 	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 
@@ -462,7 +463,7 @@
 
 int init_module(void)
 {
-	printk(KERN_INFO "Network Kernel/User communications module 0.04\n");
+	printk(KERN_INFO "Network Kernel/User communications module 0.05\n");
 	return init_netlink();
 }
 
diff -u --recursive --new-file v2.1.30/linux/net/netsyms.c linux/net/netsyms.c
--- v2.1.30/linux/net/netsyms.c	Thu Mar 27 14:40:17 1997
+++ linux/net/netsyms.c	Wed Apr  2 17:43:23 1997
@@ -86,6 +86,9 @@
 
 /* Socket layer support routines */
 EXPORT_SYMBOL(memcpy_fromiovec);
+EXPORT_SYMBOL(sock_create);
+EXPORT_SYMBOL(sock_alloc);
+EXPORT_SYMBOL(sock_release);
 EXPORT_SYMBOL(sock_setsockopt);
 EXPORT_SYMBOL(sock_getsockopt);
 EXPORT_SYMBOL(sock_sendmsg);
@@ -147,6 +150,10 @@
 EXPORT_SYMBOL(scm_detach_fds);
 #endif
 
+#ifdef CONFIG_SMB_FS_MODULE
+EXPORT_SYMBOL(scm_detach_fds);
+#endif
+
 #ifdef CONFIG_INET
 /* Internet layer registration */
 EXPORT_SYMBOL(inet_add_protocol);
@@ -257,6 +264,7 @@
 EXPORT_SYMBOL(register_trdev);
 EXPORT_SYMBOL(unregister_trdev);
 EXPORT_SYMBOL(init_trdev);
+EXPORT_SYMBOL(csum_partial_copy);
 #endif
                   
 #ifdef CONFIG_NET_ALIAS
@@ -281,7 +289,7 @@
 #endif
 
 /* support for loadable net drivers */
-#ifdef CONFIG_INET
+#ifdef CONFIG_NET
 EXPORT_SYMBOL(register_netdev);
 EXPORT_SYMBOL(unregister_netdev);
 EXPORT_SYMBOL(ether_setup);
@@ -300,6 +308,8 @@
 EXPORT_SYMBOL(dev_add_pack);
 EXPORT_SYMBOL(dev_remove_pack);
 EXPORT_SYMBOL(dev_get);
+EXPORT_SYMBOL(dev_alloc);
+EXPORT_SYMBOL(dev_alloc_name);
 EXPORT_SYMBOL(dev_ioctl);
 EXPORT_SYMBOL(dev_queue_xmit);
 #ifdef CONFIG_IP_ACCT
@@ -315,7 +325,7 @@
 EXPORT_SYMBOL(kill_fasync);
 EXPORT_SYMBOL(ip_rcv);
 EXPORT_SYMBOL(arp_rcv);
-#endif  /* CONFIG_INET */
+#endif  /* CONFIG_NET */
 
 #ifdef CONFIG_NETLINK
 EXPORT_SYMBOL(netlink_attach);
diff -u --recursive --new-file v2.1.30/linux/net/socket.c linux/net/socket.c
--- v2.1.30/linux/net/socket.c	Thu Mar 27 14:40:18 1997
+++ linux/net/socket.c	Wed Apr  2 17:43:23 1997
@@ -100,7 +100,7 @@
 static long sock_write(struct inode *inode, struct file *file,
 		       const char *buf, unsigned long size);
 
-static void sock_close(struct inode *inode, struct file *file);
+static int sock_close(struct inode *inode, struct file *file);
 static unsigned int sock_poll(struct file *file, poll_table *wait);
 static int sock_ioctl(struct inode *inode, struct file *file,
 		      unsigned int cmd, unsigned long arg);
@@ -467,7 +467,7 @@
 }
 
 
-void sock_close(struct inode *inode, struct file *filp)
+int sock_close(struct inode *inode, struct file *filp)
 {
 	/*
 	 *	It was possible the inode is NULL we were 
@@ -477,10 +477,11 @@
 	if (!inode)
 	{
 		printk(KERN_DEBUG "sock_close: NULL inode\n");
-		return;
+		return 0;
 	}
 	sock_fasync(inode, filp, 0);
 	sock_release(socki_lookup(inode));
+	return 0;
 }
 
 /*
@@ -561,19 +562,16 @@
 }
 
 
-asmlinkage int sys_socket(int family, int type, int protocol)
+int sock_create(int family, int type, int protocol, struct socket **res)
 {
-	int i, fd, err;
+	int i;
 	struct socket *sock;
 
-	lock_kernel();
-
  	/*
  	 *	Check protocol is in range
  	 */
-	err = -EINVAL;
  	if(family<0||family>=NPROTO)
- 		goto out;
+		return -EINVAL;
  		
 #if defined(CONFIG_KERNELD) && defined(CONFIG_NET)
 	/* Attempt to load a protocol module if the find failed. 
@@ -591,7 +589,7 @@
 #endif
 
 	if (net_families[family]==NULL)
-  		goto out;
+  		return -EINVAL;
 
 /*
  *	Check that this is a type that we know how to manipulate and
@@ -602,7 +600,7 @@
 	if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
 	     type != SOCK_SEQPACKET && type != SOCK_RAW &&
 	     type != SOCK_PACKET) || protocol < 0)
-			goto out;
+			return -EINVAL;
 
 /*
  *	Allocate the socket and allow the family to set things up. if
@@ -610,11 +608,10 @@
  *	default.
  */
 
-	err = -ENFILE;
 	if (!(sock = sock_alloc())) 
 	{
 		printk(KERN_WARNING "socket: no more sockets\n");
-		goto out;	/* Not exactly a match, but its the
+		return -ENFILE;		/* Not exactly a match, but its the
 					   closest posix thing */
 	}
 
@@ -623,9 +620,24 @@
 	if ((i = net_families[family]->create(sock, protocol)) < 0) 
 	{
 		sock_release(sock);
-		err = i;
+		return i;
 	}
-	else if ((fd = get_fd(sock->inode)) < 0) 
+
+	*res = sock;
+	return 0;
+}
+
+asmlinkage int sys_socket(int family, int type, int protocol)
+{
+	int fd, err;
+	struct socket *sock;
+
+	lock_kernel();
+
+	if ((err = sock_create(family, type, protocol, &sock)) < 0)
+		goto out;
+
+	if ((fd = get_fd(sock->inode)) < 0) 
 	{
 		sock_release(sock);
 		err = -EINVAL;
@@ -635,6 +647,7 @@
 		sock->file = current->files->fd[fd];
 		err = fd;
 	}
+
 out:
 	unlock_kernel();
 	return err;
@@ -988,35 +1001,6 @@
 }
 
 
-/*
- *	Receive a datagram from a socket. Call the protocol recvmsg method
- */
-
-asmlinkage int sys_recv(int fd, void * ubuf, size_t size, unsigned flags)
-{
-	struct iovec iov;
-	struct msghdr msg;
-	struct socket *sock;
-	int err;
-
-	lock_kernel();
-	if ((sock = sockfd_lookup(fd, &err))!=NULL)
-	{		
-		msg.msg_name=NULL;
-		msg.msg_iov=&iov;
-		msg.msg_iovlen=1;
-		msg.msg_control=NULL;
-		msg.msg_controllen=0;
-		iov.iov_base=ubuf;
-		iov.iov_len=size;
-
-		err=sock_recvmsg(sock, &msg, size,
-			    (current->files->fd[fd]->f_flags & O_NONBLOCK) ? flags | MSG_DONTWAIT : flags);
-		sockfd_put(sock);
-	}
-	unlock_kernel();
-	return err;
-}
 
 /*
  *	Receive a frame from the socket and optionally record the address of the 
@@ -1059,6 +1043,15 @@
 }
 
 /*
+ *	Receive a datagram from a socket. 
+ */
+
+asmlinkage int sys_recv(int fd, void * ubuf, size_t size, unsigned flags)
+{
+	return sys_recvfrom(fd,ubuf,size,flags, NULL, NULL);
+}
+
+/*
  *	Set a socket option. Because we don't know the option lengths we have
  *	to pass the user mode parameter for the protocols to sort out.
  */
@@ -1289,13 +1282,7 @@
 
 
 /*
- *	System call vectors. Since I (RIB) want to rewrite sockets as streams,
- *	we have this level of indirection. Not a lot of overhead, since more of
- *	the work is done via read/write/poll directly.
- *
- *	I'm now expanding this up to a higher level to separate the assorted
- *	kernel/user space manipulations and global assumptions from the protocol
- *	layers proper - AC.
+ *	System call vectors. 
  *
  *	Argument checking cleaned up. Saved 20% in size.
  */
@@ -1434,7 +1421,7 @@
 {
 	int i;
 
-	printk(KERN_INFO "Swansea University Computer Society NET3.038 for Linux 2.1\n");
+	printk(KERN_INFO "Swansea University Computer Society NET3.039 for Linux 2.1\n");
 
 	/*
 	 *	Initialize all address (protocol) families. 
diff -u --recursive --new-file v2.1.30/linux/scripts/mkdep.c linux/scripts/mkdep.c
--- v2.1.30/linux/scripts/mkdep.c	Thu Mar 27 14:40:18 1997
+++ linux/scripts/mkdep.c	Fri Mar 28 10:53:15 1997
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
