diff -u --recursive --new-file v1.3.67/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v1.3.67/linux/Documentation/Configure.help	Sat Feb 17 16:02:43 1996
+++ linux/Documentation/Configure.help	Thu Feb 22 14:40:03 1996
@@ -4,24 +4,32 @@
 # corresponds to the kernel versions 1.3.x. Be aware that these
 # are development kernels.
 #
-# The latest version of these help texts is always available from
-#    http://math-www.uni-paderborn.de/~axel/config_help.html
-#
 # Information about what a kernel is, what it does, how to patch and
 # compile it and much more is contained in the Kernel-HOWTO, available
 # via ftp (user: anonymous) from sunsite.unc.edu in the directory
 # /pub/Linux/docs/HOWTO. 
 #
-# Format: description<nl>variable<nl>helptext<nl><nl>. The help texts
+# Format of this file: description<nl>variable<nl>helptext<nl><nl>. 
+# If the question being documented is of type "choice", we list
+# only the first occuring config variable. The help texts
 # must not contain empty lines. No variable should occur twice; if it
 # does, only the first occurance will be used by Configure. The lines
 # in a help text should be indented two positions. Lines starting with
-# `#' are ignored. Use emacs' kfill.el to edit this file or you lose.
+# `#' are ignored. To be nice to menuconfig, limit your lines to 70
+# chars. Use emacs' kfill.el to edit this file or you lose.
+#
+# If you add a help text to this file, please try to be as gentle as
+# possible. Don't use unexplained acronyms and generally write for the
+# hypothetical user who has just bought a PC, removed Windows,
+# installed Linux and is now recompiling the kernel for the first
+# time. Tell them what to do if they're unsure. Technical information
+# should go in a README in the Documentation directory. Mention all 
+# the relevant READMEs in the help text.
 #
 # All this was shamelessly stolen from several different sources. Many
 # thanks to all the contributors.  Feel free to use these help texts
 # in your own kernel configuration tools. The texts are copyrighted
-# (c) 1995 by Axel Boldt and governed by the GNU Public License.
+# (c) 1995,1996 by Axel Boldt and governed by the GNU Public License.
 #
 # Send comments to Axel Boldt <boldt@math.ucsb.edu>.
 
@@ -30,21 +38,21 @@
   Linux can emulate a math coprocessor (used for floating point
   operations) if you don't have one. 486DX and Pentium processors have
   a math coprocessor built in, 486SX and 386 do not, unless you added
-  a 487DX or 387, respectively.  (The messages during boot time can give
-  you some hints here ["man dmesg"]) Everyone needs either a coprocessor or
-  this emulation. If you enable this emulation even though you have a
-  coprocessor, the coprocessor will be used nevertheless. (This
-  behavior can be changed with the kernel command line option
-  "no387", which comes handy if your coprocessor is broken. See the
-  documentation of your boot loader (lilo or loadlin) about how to
-  pass options to the kernel. The lilo procedure is also explained in
-  the SCSI-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.) This means that it is a good
-  idea to say Y here if you intend to use this kernel on different
-  machines. More information about the internals of Linux math
-  coprocessor emulation can be found in arch/i386/math-emu/README. If
-  you are not sure, say Y; apart from resulting in a 45kB bigger
-  kernel, it won't hurt.
+  a 487DX or 387, respectively.  (The messages during boot time can
+  give you some hints here ["man dmesg"]) Everyone needs either a
+  coprocessor or this emulation. If you enable this emulation even
+  though you have a coprocessor, the coprocessor will be used
+  nevertheless. (This behavior can be changed with the kernel command
+  line option "no387", which comes handy if your coprocessor is
+  broken. See the documentation of your boot loader (lilo or loadlin)
+  about how to pass options to the kernel at boot time. The lilo
+  procedure is also explained in the SCSI-HOWTO, available via ftp
+  (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.) This
+  means that it is a good idea to say Y here if you intend to use this
+  kernel on different machines. More information about the internals
+  of Linux math coprocessor emulation can be found in
+  arch/i386/math-emu/README. If you are not sure, say Y; apart from
+  resulting in a 45kB bigger kernel, it won't hurt.
 
 Normal floppy disk support
 CONFIG_BLK_DEV_FD
@@ -70,6 +78,15 @@
   Most normal users won't need the RAM disk functionality, and can thus say 
   N here.
 
+Loop device support
+CONFIG_BLK_DEV_LOOP
+  Enabling this option will allow you to mount a file as a file system.
+  This is useful if you want to check an ISO9660 file system before
+  burning the CD, or want to use floppy images without first writing
+  them to floppy.
+  This option also allows one to mount a filesystem with encryption.
+  Most users will answer N here.
+
 Enhanced IDE/MFM/RLL disk/cdrom/tape support
 CONFIG_BLK_DEV_IDE 
   This will use the full-featured IDE driver to control up to four IDE
@@ -135,45 +152,48 @@
 
 CMD640 chipset bugfix/support
 CONFIG_BLK_DEV_CMD640
-  The CMD-Technologies CMD640 chip is used on many common 486 and Pentium
-  motherboards, usually in combination with a "Neptune" or "SiS" chipset.
-  Unfortunately, it has a number of rather nasty design flaws that can cause
-  severe data corruption under many common conditions.  Say Y here to include
-  code which tries to automatically detect and correct the problems under Linux.
-  This also provides support for the enhanced features of the CMD640,
-  for improved support/operation under linux, including access to the secondary
-  IDE ports in some systems.  This driver will work automatically in PCI
-  based systems (most new systems have PCI slots).  But if your system uses
-  VESA local bus (VLB) instead of PCI, you must also supply a kernel boot
-  parameter to enable the CMD640 bugfix/support:  "ide0=cmd640_vlb"
-  The CMD640 chip is also used on add-in cards by Acculogic,
-  and on the "CSA-6400E PCI to IDE controller" that some people have.
+  The CMD-Technologies CMD640 chip is used on many common 486 and
+  Pentium motherboards, usually in combination with a "Neptune" or
+  "SiS" chipset.  Unfortunately, it has a number of rather nasty
+  design flaws that can cause severe data corruption under many common
+  conditions.  Say Y here to include code which tries to automatically
+  detect and correct the problems under Linux.  This also provides
+  support for the enhanced features of the CMD640, for improved
+  support/operation under linux, including access to the secondary IDE
+  ports in some systems.  This driver will work automatically in PCI
+  based systems (most new systems have PCI slots).  But if your system
+  uses VESA local bus (VLB) instead of PCI, you must also supply a
+  kernel boot parameter to enable the CMD640 bugfix/support:
+  "ide0=cmd640_vlb" The CMD640 chip is also used on add-in cards by
+  Acculogic, and on the "CSA-6400E PCI to IDE controller" that some
+  people have. If unsure, say Y.
 
 RZ1000 chipset bugfix/support
 CONFIG_BLK_DEV_RZ1000
-  The PC-Technologies RZ1000 chip is used on many common 486 and Pentium
-  motherboards, usually along with the "Neptune" chipset.  Unfortunately,
-  it has a rather nasty design flaw that can cause severe data corruption
-  under many conditions.  Say Y here to include code which automatically
-  detects and corrects the problem under Linux.  This may slow disk throughput
-  by a few percent, but at least things will operate 100% reliably.
+  The PC-Technologies RZ1000 chip is used on many common 486 and
+  Pentium motherboards, usually along with the "Neptune" chipset.
+  Unfortunately, it has a rather nasty design flaw that can cause
+  severe data corruption under many conditions.  Say Y here to include
+  code which automatically detects and corrects the problem under
+  Linux.  This may slow disk throughput by a few percent, but at least
+  things will operate 100% reliably. If unsure, say Y.
 
 Other IDE chipset support
 CONFIG_IDE_CHIPSETS
-  Say Y here if you want to include enhanced support for various
-  IDE interface chipsets used on motherboards and add-on cards.
-  This enhanced support may be necessary for linux to be able to access
-  the 3rd/4th drives in some systems.  It may also enable setting of
-  higher speed I/O rates to improve system performance with these chipsets.
-  Most of these also require special kernel boot parameters to actually
-  turn on the support at runtime.
+  Say Y here if you want to include enhanced support for various IDE
+  interface chipsets used on motherboards and add-on cards.  This
+  enhanced support may be necessary for linux to be able to access the
+  3rd/4th drives in some systems.  It may also enable setting of
+  higher speed I/O rates to improve system performance with these
+  chipsets.  Most of these also require special kernel boot parameters
+  to actually turn on the support at runtime.
 
 DTC-2278 chipset support
 CONFIG_BLK_DEV_DTC2278
   This driver is enabled at runtime using the "ide0=dtc2278" kernel
   boot parameter.  It enables support for the secondary IDE interface
-  of the DTC-2278 card, and permits faster I/O speeds to be set as well.
-  See the README.ide and dtc2278.c files for more info.
+  of the DTC-2278 card, and permits faster I/O speeds to be set as
+  well.  See the README.ide and dtc2278.c files for more info.
 
 Holtek HT6560B chipset support
 CONFIG_BLK_DEV_HT6560B
@@ -207,51 +227,95 @@
   Very old 8 bit hard disk controllers used in the IBM XT
   computer. Pretty unlikely that you have this: say N.
 
+Support for Deskstation RPC44 
+CONFIG_DESKSTATION_RPC44
+  This is a machine with a R4400 100 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
+Support for Mips Magnum 3000 
+CONFIG_MIPS_MAGNUM_3000
+  To compile a Linux kernel that runs on these, say Y here. For
+  details about Linux on the MIPS architecture, check out the
+  Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse the
+  WWW, you need to have access to a machine on the Internet that has
+  one of the programs lynx, netscape or Mosaic).
+
+Support for Mips Magnum 4000
+CONFIG_MIPS_MAGNUM_4000
+  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
+Support for Olivetty M700
+CONFIG_OLIVETTI_M700
+  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
 Support for Deskstation Tyne
 CONFIG_DESKSTATION_TYNE
-#####
-##### Anyone have details? It's for the MIPS architecture.
-#####
+  This is a machine with a R4600 134 MHz CPU. The Linux port for this
+  system is idle right now because of hardware or documentation
+  problems. For details about Linux on the MIPS architecture, check
+  out the Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse
+  the WWW, you need to have access to a machine on the Internet that
+  has one of the programs lynx, netscape or Mosaic).
 
 Support for Acer PICA 1 chipset
 CONFIG_ACER_PICA_61
-#####
-##### Anyone have details? It's for the MIPS architecture.
-#####
+  This is a machine with a R4400 134/150 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about
+  Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the
+  WWW at http://lena.fnet.fr/ (To browse the WWW, you need to have
+  access to a machine on the Internet that has one of the programs
+  lynx, netscape or Mosaic).
 
 Support for DECstation
 CONFIG_DECSTATION
-#####
-##### Anyone have details? It's for the MIPS architecture.
-#####
-
-Generate code for R4x00
-CONFIG_R4X00
-  If your computer uses the 64 bit R4X00 processor (as opposed to the
-  32 bit R3000), you need to say Y here, otherwise N. Note that these
-  processors are not compatible and the kernel can only work on the
-  processor type it was compiled for.
+  The DECStation 3100 (with a MIPS R2000 series CPU) and DECStation
+  5000/xxx (MIPS R3000 series CPU) are also sometimes labeled
+  PMAX. They often run the Ultrix operating system. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
+CPU type
+CONFIG_CPU_R3000
+  Give the type of your machine's MIPS CPU. For this question,
+  it suffices to give a unique prefix of the option you want to
+  choose. 
 
 Networking support
 CONFIG_NET
   Unless you really know what you are doing, you should say Y
   here. The reason is that some programs need it even if you configure
   a stand-alone machine that won't be connected to any other computer.
-  If you have recently upgraded from an older kernel, you should
-  consider updating your networking tools too; read net/README for
-  details. 
+  from an older kernel, you should consider updating your networking
+  tools too; read net/README for details.
 
 Network aliasing
 CONFIG_NET_ALIAS
-  This is for setting several network addresses on the same low-level network
-  device driver. Typically used for services that act differently based
-  on the address they listen on (e.g. Apache httpd) or for connecting to
-  different logical networks through the same physical interface.
-  This is the generic part, later when configuring network protocol
-  options you will be asked for protocol-specific aliasing support.
-  See Documentation/networking/alias.txt for more info.
-  If you need this features (for any protocol, like IP) say Y; if unsure, 
-  say N.  
+  This is for setting several network addresses on the same low-level
+  network device driver. Typically used for services that act
+  differently based on the address they listen on (e.g. Apache httpd)
+  or for connecting to different logical networks through the same
+  physical interface.  This is the generic part, later when
+  configuring network protocol options you will be asked for
+  protocol-specific aliasing support.  See
+  Documentation/networking/alias.txt for more info.  If you need this
+  features (for any protocol, like IP) say Y; if unsure, say N.
 
 Network firewalls
 CONFIG_FIREWALL
@@ -269,67 +333,73 @@
 
 Alpha system type
 CONFIG_ALPHA_AVANTI
-  Find out what type of Alpha motherboard you have. If you can't
-  find one of the given names, then try "Noname". For this question,
-  it suffices to give a unique prefix of the option you want to
-  choose. 
+  Find out what type of Alpha motherboard you have. You will probably
+  want to read the Linux/Alpha homepage on the WWW at
+  http://www.azstarnet.com/~axplinux/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic). For this question, it suffices
+  to give a unique prefix of the option you want to choose. The
+  choices:
+  ** Avanti: This is for Mustang (AS200), M3 (AS250), Avanti (AS400)
+     and XL (a.k.a. "Windows NT Dream Machine" :-) AlphaStations.
+     These usually come with a TGA graphics adaptor, so you'll want to
+     say Y to "TGA Console support", below, if you have one of these.
+  ** Jensen: a.k.a. DEC 2000 a.k.a. DECpc AXP 150, the oldest Alpha
+     PC; it sports an EISA bus. The boot process on Jensen machines is
+     difficult (no booting from floppies, MILO doesn't work). You need
+     to have access to a second Linux workstation. The Linux/Alpha
+     FAQ, accessible from the above mentioned WWW page, has details.
+  ** Noname: a.k.a. AXPpci33, a PCI-bus based board using the 21066
+     Alpha CPU, running at either 166 or 233 MHz. You also want to
+     choose this option if you have a UDB (Universal Desktop Box
+     a.k.a. Multia) machine.
+  ** Cabriolet: also called AlphaPC64, a PCI-bus based board using the
+     21064 Alpha CPU typically running at 275 or 300 MHz.
+  ** EB66: "Evaluation Board"
+  ** EB66+: "Evaluation Board"
+###
+### Add info about Platform2000
+###
 
 Limit memory to low 16MB
 CONFIG_MAX_16M
   This is for some buggy motherboards which cannot properly deal with
   the memory above 16MB. If you have more than 16MB of RAM and
   experience weird problems, you might want to try Y, everyone else
-  says N. Note for machines with more than 64MB of RAM: in order for the
-  kernel to be able to use the memory above 64MB, pass the command
-  line option "mem=XXXM" (where XXX is the memory size in
-  megabytes) to your kernel. See the documentation of your boot loader
-  (lilo or loadlin) about how to pass options to the kernel. The lilo
-  procedure is also explained in the SCSI-HOWTO, available via ftp
-  (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
-  You also need at least 512kB of RAM cache if you have more than 64MB
-  of RAM.
-  Some other things to try when experiencing seemingly random, "weird"
-  problems: 1) passing the "no-hlt" option to the kernel 2) passing
-  the "no-387" option to the kernel 3) passing the "mem=4M" option to
-  the kernel (will disable all but the first 4M of RAM) 4) disabling
-  the cache from your BIOS settings 5) exchanging RAM chips 6)
-  exchanging the motherboard 7) committing suicide.
+  says N. Note for machines with more that 64MB of RAM: in order for
+  the kernel to be able to use the memory above 64MB, pass the command
+  line option "mem=XXXM" (where XXX is the memory size in megabytes)
+  to your kernel during boot time. See the documentation of your boot
+  loader (lilo or loadlin) about how to pass options to the
+  kernel. The lilo procedure is also explained in the SCSI-HOWTO,
+  available via ftp (user: anonymous) in
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  You also need at least 512kB
+  of RAM cache if you have more than 64MB of RAM.  Some other things
+  to try when experiencing seemingly random, "weird" problems: 1)
+  passing the "no-hlt" option to the kernel 2) passing the "no-387"
+  option to the kernel 3) passing the "mem=4M" option to the kernel
+  (thereby disabling all but the first 4M of RAM) 4) disabling the
+  cache from your BIOS settings 5) exchanging RAM chips 6) exchanging
+  the motherboard 7) committing suicide.
 
 Using SRM as bootloader
 CONFIG_ALPHA_SRM
-  This selects whether the Linux kernel on an Alpha machines is being
-  booted through SRM (the DEC Unix firmware).  If you use MILO, answer
-  "no" here.  Except for Cabriolet and some other evaluation-board based
-  machines, this option has no effect and can be set to either value
-  with no ill effects.
-
-Kernel KGDB support
-CONFIG_KGDB
-  Selects whether kernel debugging via serial line should be enabled.
-  Enable this option only if you really plan on debugging the Linux
-  kernel.  If you enable this option, take a look at
-  arch/alpha/kernel/kgdb.c and search for SERIAL_LINE to find out
-  what serial port the kernel will use (either /dev/ttyS0 or
-  /dev/ttyS1).  Then, hook up a serial line to another machine
-  (must be another 64-bit machine when debugging a 64-bit kernel)
-  and start "gdb vmlinux" on that machine.  Then boot the kernel on
-  the target system with boot option "kgdb".  The kernel will display:
-     kgdb: stealing /dev/ttyS0 and initializing it to 38400 baud
-     kgdb: waiting for gdb to connect...
-  At this point, enter the following commands on the system running
-  gdb:
-     gdb> set remotebaud 38400
-     gdb> set target remote /dev/<whatever>
-  After a few seconds, gdb should respond with the usual prompt, showing
-  the source at which the kernel is currently executing.  You can now
-  use the normal gdb features such as breakpoints to debug the kernel.
-  WARNING: when CONFIG_KGDB is enabled, send a Ctrl-C character over
-  the serial line will drop the kernel into the debugger!
-
-Kernel tracing support
-CONFIG_KGDB_TRACING
-  Enabling this option allows to collect kernel execution traces.  Don't
-  try this at home!
+  There are two different types of booting firmware on Alphas: SRM,
+  which is command line driven, and ARC, which uses menus and arrow
+  keys. The usual way to load Linux on an Alpha machine is to use MILO
+  (a bootloader that lets you pass command line parameters to the
+  kernel just like LILO does) which can be loaded either from ARC or
+  can be installed directly as a permanent firmware replacement from
+  floppy (which requires changing a certain jumper on the
+  motherboard). If you want to do either of these, say N here. If MILO
+  doesn't work on your system (true for Jensen motherboards), you can
+  bypass it altogether and boot Linux directly from an SRM console;
+  say Y here in order to do that. Note that you won't be able to boot
+  from an IDE disk using SRM. If unsure, say N. Details about the
+  Linux/Alpha booting process are contained in the Linux/Alpha FAQ,
+  accessible on the WWW from http://www.azstarnet.com/~axplinux/ (To
+  browse the WWW, you need to 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
@@ -340,26 +410,29 @@
 
 TGA Console Support
 CONFIG_TGA_CONSOLE
-  Many Alpha systems are shipped with a graphics card that implements the
-  TGA interface (much like the VGA standard, but older TGA adaptors are
-  *not* VGA compatible).  On such systems, this option needs to be enabled
-  such that the TGA driver rather than the standard VGA driver is used.
+  Many Alpha systems (e.g the Multia) are shipped with a graphics card
+  that implements the TGA interface (much like the VGA standard, but
+  older TGA adaptors are *not* VGA compatible).  On such systems, this
+  option needs to be enabled so that the TGA driver rather than the
+  standard VGA driver is used.  Note that, at this time, there is no X
+  server for these systems. If unsure, try N.
 
 PCI bios support
 CONFIG_PCI
   Find out whether you have a PCI motherboard. PCI is the name of a
   bus system, i.e. the way the CPU talks to the other stuff inside
-  your box. Other bus systems are ISA, EISA, Microchannel or VESA. If
-  you have PCI, say Y, otherwise N. Note: some old PCI motherboards
-  have BIOS bugs and may crash if this is enabled (but they run fine
-  without this option). The PCI-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO, contains
-  valuable information about which PCI hardware works under Linux and
-  which doesn't.  If some of your PCI devices don't work and you get a
-  warning during boot time ("man dmesg"), please follow the instructions 
-  at the top of include/linux/pci.h. The buggy PCTech RZ 1000 IDE
-  harddrive controller which is used in some PCI systems is detected
-  and correctly handled by this driver.
+  your box. Other bus systems are ISA, EISA, Microchannel (MCA) or
+  VESA. If you have PCI, say Y, otherwise N. Note1: MCA systems are
+  not supported by the standard kernels, but patches exist at
+  http://www.undergrad.math.uwaterloo.ca/~cpbeaure/mca-linux.html on
+  the WWW. Note2: some old PCI motherboards have BIOS bugs and may
+  crash if "PCI bios support" is enabled (but they run fine without
+  this option). The PCI-HOWTO, available via ftp (user: anonymous) in
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO, contains valuable information
+  about which PCI hardware does work under Linux and which doesn't.
+  If some of your PCI devices don't work and you get a warning during
+  boot time ("man dmesg"), please follow the instructions at the top
+  of include/linux/pci.h. 
 
 PCI bridge optimization (experimental)
 CONFIG_PCI_OPTIMIZE
@@ -369,14 +442,13 @@
 
 Intel 430FX (Triton) chipset DMA support
 CONFIG_BLK_DEV_TRITON
-  This option is valid only if PCI BIOS support was also selected earlier.
   If your PCI system uses an IDE harddrive (as opposed to SCSI, say)
-  and includes the Intel 430FX PCI Triton chipset, you will want
-  to enable this option to allow use of bus-mastering DMA data transfers.
-  Read the comments at the beginning of drivers/block/triton.c.
-  The hdparm utility can be obtained via ftp (user: anonymous)
-  from sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/.
-  It is safe to say Y.
+  and includes the Intel 430FX PCI Triton chipset, you will want to
+  enable this option to allow use of bus-mastering DMA data transfers.
+  Read the comments at the beginning of drivers/block/triton.c.  The
+  hdparm utility can be obtained via ftp (user: anonymous) from
+  sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/.  It is safe
+  to say Y.
 
 System V IPC
 CONFIG_SYSVIPC
@@ -404,14 +476,15 @@
   (this does *not* mean that you will be able to run executables from
   different architectures or operating systems!) and makes building
   run-time libraries very easy. Many new executables are distributed
-  solely in ELF format. You definitely want to say Y here. Information about
-  ELF is on the WWW at http://www.sjc.ox.ac.uk/users/barlow/elf-howto.html
-  (To browse the WWW, you need to have access to a machine on the
-  Internet that has one of the programs lynx, netscape or Mosaic).  If
-  you find that after upgrading to Linux kernel 1.3 and saying Y here,
-  you still can't run any ELF binaries (they just crash), then you'll
-  have to install the newest ELF runtime libraries, including ld.so
-  (available via ftp (user: anonymous) from
+  solely in ELF format. You definitely want to say Y here. Information
+  about ELF is on the WWW at
+  http://www.sjc.ox.ac.uk/users/barlow/elf-howto.html (To browse the
+  WWW, you need to have access to a machine on the Internet that has
+  one of the programs lynx, netscape or Mosaic).  If you find that
+  after upgrading to Linux kernel 1.3 and saying Y here, you still
+  can't run any ELF binaries (they just crash), then you'll have to
+  install the newest ELF runtime libraries, including ld.so (available
+  via ftp (user: anonymous) from
   tsx-11.mit.edu:/pub/linux/packages/GCC). Also note that ELF binary
   support was broken in kernel versions 1.3.0 - 1.3.2. Either use a
   newer 1.3 kernel or one of the stable 1.2 versions. If you want to
@@ -450,13 +523,34 @@
 Processor type
 CONFIG_M386
   This is the processor type of your CPU. It is used for optimizing
-  purposes. In order to compile a kernel that can run on all three CPU
-  types (albeit not optimally fast), you can specify "386" here.  If
-  you specify "486" or "Pentium", then the kernel will run on
-  both 486 and Pentium CPUs. In rare cases, it can make sense to
-  specify "Pentium" here even if running a 486: the kernel will be
-  smaller but slower.
-  
+  purposes. In order to compile a kernel that can run on all CPU types
+  (albeit not optimally fast), you can specify "386" here.  If you
+  specify "486" or "Pentium" or "PPro", then the kernel will run on
+  486 and Pentium (=586) and Pentium Pro (=686) CPUs. In rare cases,
+  it can make sense to specify "Pentium" even if running a 486: the
+  kernel will be smaller but slower.
+
+Compile the kernel into the ELF object format 
+CONFIG_ELF_KERNEL
+  ELF (Executable and Linkable Format) is a format for libraries and
+  executables used across different architectures and operating
+  systems. This option will cause the resulting kernel to be in ELF
+  format, which is generally desirable, so say Y. However, it only
+  works if your compiler and linker can produce ELF code.
+
+Is your ELF compiler an extra compiler
+CONFIG_EXTRA_ELF_COMPILER
+  If you have a linuxelf-gcc as opposed to linux-gcc, say Y, otherwise
+  N.
+
+Generate little endian code
+CONFIG_CPU_LITTLE_ENDIAN
+  If your compiler is mipsel-linux-gcc or mipsel-linuxelf-gcc (as
+  opposed to mips-linux-gcc or mips-linuxelf-gcc), say Y here,
+  otherwise N. Most MIPS machines use little-endian code, but it might
+  be necessary to run older Mips sytems, such as the Sony News and
+  MIPS RC3xxx in big endian mode.
+
 Enable loadable module support
 CONFIG_MODULES
   Kernel modules are small pieces of compiled code which can be 
@@ -469,13 +563,13 @@
 
 Set version information on all symbols for modules
 CONFIG_MODVERSIONS
-  Usually, modules have to be recompiled whenever you
-  switch to a new kernel. Enabling this option allows you
-  to keep using the same modules even after compiling a new kernel;
-  this requires the program modprobe. All the software needed for
-  module support is in the modules package in
-  sunsite.unc.edu:/pub/Linux/kernel, available via ftp (user:
-  anonymous). NOTE1: if you say Y here but don't have the program
+  Usually, modules have to be recompiled whenever you switch to a new
+  kernel. Enabling this option allows you to keep using the same
+  modules even after compiling a new kernel; this requires the program
+  modprobe. All the software needed for module support is in the
+  modules package in sunsite.unc.edu:/pub/Linux/kernel, available via
+  ftp (user: anonymous) and to be extracted with "tar xzvf
+  filename". NOTE1: if you say Y here but don't have the program
   genksyms (which is also contained in the above mentioned modules
   package), then the building of your kernel will fail. NOTE2: if you
   say Y here, then you cannot say Y to the PPP driver, below; the only
@@ -488,7 +582,7 @@
   to be created as loadable modules, you also have the responsibility
   to load the corresponding module (via insmod/modprobe) before you
   use it.  If you select Y here, the kernel will take care of this
-  all by itself, together with a user level daemon, "kerneld".
+  all by itself, together with a user level daemon; "kerneld".
   Note that "kerneld" will also automatically unload all unused
   modules, so you don't have to use "rmmod" either.
   There are some other "kernel callouts" that will be available
@@ -745,21 +839,21 @@
 
 The IPX protocol
 CONFIG_IPX
-  This is support for the Novell networking protocol, IPX. You need it
-  if you want to access Novell Netware servers by using the Linux
-  Novell client ncpfs (available via ftp (user: anonymous) from 
-  sunsite.unc.edu:/pub/Linux/system/Filesystem/) or from within the 
+  This is support for the Novell networking protocol, IPX, commonly
+  used for local networks of Windows machines. You need it if you want
+  to access Novell Netware file or print servers using the Linux
+  Novell client ncpfs (available via ftp (user: anonymous) from
+  sunsite.unc.edu:/pub/Linux/system/Filesystems/) or from within the
   Linux DOS emulator dosemu (read the DOSEMU-HOWTO, available in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO). To turn your Linux box into
-  a fully featured Netware file server and IPX router, say Y here and
-  fetch lwared from
-  sunsite.unc.edu:/pub/Linux/system/Networking/daemons/. General
-  information about how to connect Linux, Windows machines and Macs is
-  on the WWW at http://eats.com/linux_mac_win.html (to browse the WWW,
-  you need to have access to a machine on the Internet that has one of
-  the programs lynx, netscape or Mosaic). This driver would enlarge
-  your kernel by about 5 kB. Unless you have Novell computers on your
-  local network, say N.
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO). In order to do the former,
+  you'll also have to say Y to "NCP filesystem support", below. To
+  turn your Linux box into a fully featured Netware file server and
+  IPX router, say Y here and fetch lwared from
+  sunsite.unc.edu:/pub/Linux/system/Network/daemons/. For more
+  information, read the IPX-HOWTO in
+  sunsite.unc.edu:/pub/Linux/docs/howto. The IPX driver would enlarge
+  your kernel by about 5 kB. Unless you want to integrate your Linux
+  box with a local Novell network, say N.
 
 Full internal IPX network
 CONFIG_IPX_INTERN
@@ -775,6 +869,7 @@
   primary network is disabled. This might break existing applications,
   especially RIP/SAP daemons. A RIP/SAP daemon that works well with the
   full internal net can be found on linux01.gwdg.de:/pub/ncpfs.
+  If you don't know what you are doing, say N.
 
 Appletalk DDP
 CONFIG_ATALK
@@ -934,6 +1029,15 @@
   understand if you enable this; it will enlarge your kernel by about
   12KB. If in doubt, say Y.
 
+AdvanSys SCSI support
+CONFIG_SCSI_ADVANSYS
+  This is a driver for all SCSI host adaptors manufactured by
+  AdvanSys. It is documented in the kernel source in
+  drivers/scsi/advansys.c. This driver is also available as a module (
+  = code which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
+
 Adaptec AHA152X support
 CONFIG_SCSI_AHA152X
   This is support for an SCSI host adaptor. It is explained in section
@@ -980,14 +1084,14 @@
 
 BusLogic SCSI support
 CONFIG_SCSI_BUSLOGIC
-  This is support for BusLogic MultiMaster SCSI Host Adaptors.  Consult
-  the documentation in drivers/scsi/README.BusLogic for more information.
-  BusLogic FlashPoint SCSI Host Adapters are not supported by this driver.
-  If this driver does not work correctly without modification, please
-  consult the author.  This driver may also be built as a module, but
-  only a single instance may be loaded.  You might also want to read
-  the SCSI-HOWTO, available via anonymous ftp from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  This is support for BusLogic MultiMaster SCSI Host Adaptors.
+  Consult the documentation in drivers/scsi/README.BusLogic for more
+  information.  BusLogic FlashPoint SCSI Host Adapters are not
+  supported by this driver.  If this driver does not work correctly
+  without modification, please consult the author.  This driver may
+  also be built as a module, but only a single instance may be loaded.
+  You might also want to read the SCSI-HOWTO, available via anonymous
+  ftp from sunsite.unc.edu:/pub/Linux/docs/HOWTO.
  
 EATA-DMA (DPT,NEC&ATT for ISA,EISA,PCI) support
 CONFIG_SCSI_EATA_DMA
@@ -1028,17 +1132,18 @@
 Future Domain 16xx SCSI support
 CONFIG_SCSI_FUTURE_DOMAIN
   This is support for Future Domain's 16-bit SCSI host adaptors
-  (TMC-1660/1680, TMC-1650/1670, TMC-3260) and other adaptors based on the
-  Future Domain chipsets (Quantum ISA-200S, ISA-250MG; and at least one IBM
-  board).  It is explained in section 3.7 of the SCSI-HOWTO, available via
-  ftp (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If it
-  doesn't work out of the box, you may have to change some settings in
-  drivers/scsi/fdomain.h. This driver is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). If you want to compile it as a module, say M here and
-  read Documentation/modules.txt.
+  (TMC-1660/1680, TMC-1650/1670, TMC-3260) and other adaptors based on
+  the Future Domain chipsets (Quantum ISA-200S, ISA-250MG; and at
+  least one IBM board).  It is explained in section 3.7 of the
+  SCSI-HOWTO, available via ftp (user: anonymous) at
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If it doesn't work out of
+  the box, you may have to change some settings in
+  drivers/scsi/fdomain.h. This driver is also available as a module (
+  = code which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
 
-Generic NCR5380 SCSI support
+Generic NCR5380/53c400 SCSI support
 CONFIG_SCSI_GENERIC_NCR5380
   This is the generic NCR family of SCSI controllers, not to be
   confused with the NCR 53c7 or 8xx controllers. It is explained in
@@ -1050,6 +1155,22 @@
   kernel whenever you want). If you want to compile it as a module,
   say M here and read Documentation/modules.txt.
  
+Enable NCR53c400 extensions
+CONFIG_SCSI_GENERIC_NCR53C400
+  This enables certain optimizations for the NCR53c400 scsi cards. You
+  might as well try it out. Note that this driver will only probe for
+  the Trantor T130B in its default configuration; you might have to
+  pass a command line option to the kernel at boot time if it doesn't
+  detect your card. See the file drivers/scsi/README.g_NCR5380 for
+  details. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.
+
+NCR5380/53c400 mapping method (use Port for T130B)
+CONFIG_SCSI_G_NCR5380_PORT
+  The NCR5380 and NCR53c400 SCSI controllers come in two varieties:
+  port or memory mapped. You should know what you have. The most
+  common card, Trantor T130B, uses port mapped mode.
+
 NCR53c7,8xx SCSI support
 CONFIG_SCSI_NCR53C7xx
   This is the 53c7 and 8xx NCR family of SCSI controllers, not to be
@@ -1146,6 +1267,23 @@
   running kernel whenever you want), say M here and read
   Documentation/modules.txt.
 
+NCR53c406a SCSI support
+CONFIG_SCSI_NCR53C406A
+  This is support for the NCR53c406a SCSI host adapter. For user
+  configurable parameters, check out drivers/scsi/NCR53c406.c in the
+  kernel source. Also read the SCSI-HOWTO, available via ftp (user:
+  anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to
+  compile this driver as a module ( = code which can be inserted in
+  and removed from the running kernel whenever you want), say M here
+  and read Documentation/modules.txt.
+
+AM53/79C974 PCI SCSI support
+CONFIG_SCSI_AM53C974
+  This is support for the AM53/79C974 SCSI host adapters. Please read
+  drivers/scsi/README.AM53C974 for details. Also, the SCSI-HOWTO,
+  available via ftp (user: anonymous) at
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO, is for you.
+
 Network device support?
 CONFIG_NETDEVICES
   You can say N here in case you don't intend to connect to any other
@@ -1231,8 +1369,9 @@
 
 Keepalive and linefill
 CONFIG_SLIP_SMART
-  Adds additional capabilities to the SLIP driver to support the RELCOM
-  line fill and keepalive monitoring. Ideal on poor quality analogue lines.
+  Adds additional capabilities to the SLIP driver to support the
+  RELCOM line fill and keepalive monitoring. Ideal on poor quality
+  analogue lines.
 
 PPP (point-to-point) support
 CONFIG_PPP
@@ -1275,6 +1414,9 @@
   and communicate with other computers.  If you want to use this, read
   Documentation/networking/z8530drv.txt and the HAM-HOWTO, available via
   ftp (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt.
 
 PLIP (parallel port) support
 CONFIG_PLIP
@@ -1472,6 +1614,21 @@
   you may need to use the DOS setup disk to disable Plug & Play mode, and
   to select the default media type.
 
+3c590 series (592/595/597) "Vortex" support
+CONFIG_VORTEX
+  If you have a network (ethernet) card of this type, say Y and read
+  the Ethernet-HOWTO, available via ftp (user: anonymous) in
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO. More specific information is
+  in Documentation/networking/vortex.txt and in the comments at the
+  beginning of drivers/net/3c59x.c. If you want to compile this
+  as a module ( = code which can be inserted in and removed from the
+  running kernel whenever you want), say M here and read
+  Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt. If you plan to use more
+  than one network card under linux, read the
+  Multiple-Ethernet-mini-HOWTO, available from
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini
+
 Other ISA cards
 CONFIG_NET_ISA
   If your network (ethernet) card hasn't been mentioned yet and its
@@ -1629,13 +1786,12 @@
 
 Gracilis PackeTwin support
 CONFIG_PT
-  This card is similar to the PI card (mentioned above).  It is used mainly
-  by amateur radio operators for packet radio.  You should have already 
-  said Y to "AX.25 support" as this card uses that protocol. 
-  More information about this driver can be found in the file 
-  drivers/net/README.pt. 
-  NOTE: The card is capable of DMA and full duplex but neither of these have
-  been coded in the driver as yet.
+  This card is similar to the PI card (mentioned above).  It is used
+  mainly by amateur radio operators for packet radio.  You should have
+  already said Y to "AX.25 support" as this card uses that protocol.
+  More information about this driver can be found in the file
+  drivers/net/README.pt.  NOTE: The card is capable of DMA and full
+  duplex but neither of these have been coded in the driver as yet.
 
 WaveLAN support
 CONFIG_WAVELAN
@@ -1790,12 +1946,10 @@
 
 Pocket and portable adaptors
 CONFIG_NET_POCKET
-  Cute little network (ethernet) devices which attach to your parallel
-  port ("pocket adaptors"). If you have one of those, say Y and read
-  the Ethernet-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you plan to use more than
-  one network card under linux, read the Multiple-Ethernet-mini-HOWTO,
-  available from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. If you
+  Cute little network (ethernet) devices which attach to the parallel
+  port ("pocket adaptors"), commonly used with laptops. If you have
+  one of those, say Y and read the Ethernet-HOWTO, available via ftp
+  (user: anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you
   want to plug a network card into the PCMCIA slot of your laptop
   instead (PCMCIA is the standard for credit card size extension cards
   used by all modern laptops), look in
@@ -1893,12 +2047,12 @@
 Sony CDU31A/CDU33A CDROM support
 CONFIG_CDU31A
   These CDROM drives have a spring-pop-out caddyless drawer, and a
-  rectangular green LED centered beneath it.
-  NOTE: these CDROM drives will not be auto detected by the kernel at
-  boot time; you have to provide the interface address as an option to
-  the kernel as described in Documentation/cdrom/cdu31a or fill in your
+  rectangular green LED centered beneath it.  NOTE: these CDROM drives
+  will not be auto detected by the kernel at boot time; you have to
+  provide the interface address as an option to the kernel at boot
+  time as described in Documentation/cdrom/cdu31a or fill in your
   parameters into linux/drivers/cdrom/cdu31a.c. See the documentation
-  of your boot loader (lilo or loadlin) about how to pass options to 
+  of your boot loader (lilo or loadlin) about how to pass options to
   the kernel. The lilo procedure is also explained in the SCSI-HOWTO.
 
 Standard Mitsumi [no XA/Multisession] CDROM support
@@ -1928,25 +2082,27 @@
 CONFIG_SBPCD
   This driver supports most of the drives which use the Panasonic or
   SoundBlaster interface.
-  The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives (sometimes
-  labeled "Creative"), the CreativeLabs CD200, the Longshine LCS-7260,
-  the "IBM External ISA CDROM" (in fact a CR-56x model), the TEAC CD-55A
-  fall under this category. Some other "electrically compatible" drives
-  (Vertos, Genoa, some Funai models) are currently not supported; for the
-  Sanyo H94A drive currently a separate driver (asked later) is responsible.
-  Most drives have a uniquely shaped faceplate, with a caddyless motorized
-  drawer, but without external brand markings. The older CR-52x drives have
-  a caddy and manual loading/eject, but still no external markings.
-  The driver is able to do an extended auto-probing for interface addresses
-  and drive types; this can help to find facts in cases you are not sure,
-  but can consume some time during the boot process if none of the supported
-  drives gets found.
+  The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
+  (sometimes labeled "Creative"), the CreativeLabs CD200, the
+  Longshine LCS-7260, the "IBM External ISA CDROM" (in fact a CR-56x
+  model), the TEAC CD-55A fall under this category. Some other
+  "electrically compatible" drives (Vertos, Genoa, some Funai models)
+  are currently not supported; for the Sanyo H94A drive currently a
+  separate driver (asked later) is responsible.  Most drives have a
+  uniquely shaped faceplate, with a caddyless motorized drawer, but
+  without external brand markings. The older CR-52x drives have a
+  caddy and manual loading/eject, but still no external markings.  The
+  driver is able to do an extended auto-probing for interface
+  addresses and drive types; this can help to find facts in cases you
+  are not sure, but can consume some time during the boot process if
+  none of the supported drives gets found.
   Once your drive got found, you should enter the reported parameters into
   linux/include/linux/sbpcd.h and set "DISTRIBUTION 0" there.
-  This driver can support up to four CDROM interface cards, and each card
-  can support up to four CDROM drives; if you say Y here, you will be asked
-  how many controllers you have. If compiled as a module, only one interface
-  card (but with up to four drives) is usable.
+  This driver can support up to four CDROM interface cards, and each
+  card can support up to four CDROM drives; if you say Y here, you
+  will be asked how many controllers you have. If compiled as a
+  module, only one interface card (but with up to four drives) is
+  usable.
 
 Matsushita/Panasonic, ... second CDROM controller support
 CONFIG_SBPCD2
@@ -1992,7 +2148,7 @@
 
 Soft configurable cdrom interface card support
 CONFIG_CDI_INIT
-  If you want to include boot-time intialisation of any cdrom
+  If you want to include boot-time initialization of any cdrom
   interface card that is software configurable, say Y here.
   Currently only the ISP16/MAD16/Mozart cards are supported.
 
@@ -2003,15 +2159,19 @@
   at boot time, please say Y. Boot time command line options (or
   'append=' options in /etc/lilo.conf) are:
                 isp16=<port>,<irq>,<dma>,<drive_type>
-  Here 'port','irq' and 'dma' are the base i/o address, irq number
-  and dma line assumed to be used by the attached cdrom drive. 'drive_type'
-  is the type of cdrom drive or its emulation mode. Valid values for
-  drive_type include: Sanyo, Panasonic (same as Sanyo), Sony and Mitsumi.
-  Default values are: port=0x340, irq=0, dma=0, drive_type=Sanyo.
+
+  Here 'port','irq' and 'dma' are the base i/o address, irq number and
+  dma line assumed to be used by the attached cdrom
+  drive. 'drive_type' is the type of cdrom drive or its emulation
+  mode. Valid values for drive_type include: Sanyo, Panasonic (same as
+  Sanyo), Sony and Mitsumi.  Default values are: port=0x340, irq=0,
+  dma=0, drive_type=Sanyo.
   The command line
                 isp16=noisp16
   will skip detection and configuration after all.
-  N.B. options are case sensitive.
+  N.B. options are case sensitive. 
+  Read Documentation/cdrom/isp16 for details. 
+
 
 Quota support
 CONFIG_QUOTA
@@ -2019,7 +2179,7 @@
   usage (also called diskquotas). Currently, it works only for the
   ext2 filesystem; you need the software available via ftp (user:
   anonymous) from
-  sunsite.unc.edu:/pub/Linux/systm/Admin/quota_acct.tar.gz in order to
+  sunsite.unc.edu:/pub/Linux/system/Admin/quota_acct.tar.gz in order to
   use it. Probably this is only useful for multi user systems. If
   unsure, say N.
 
@@ -2196,19 +2356,19 @@
   some other computer over the net via NFS (presumably because your
   box doesn't have a harddisk), say Y here. You will then have to
   specify the directory that should be remotely mounted with the
-  "root" kernel command line option. See the documentation of your
-  boot loader (lilo or loadlin) about how to pass options to the
-  kernel. The lilo procedure is also explained in the SCSI-HOWTO,
-  available via ftp (user: anonymous) in
+  "root" kernel command line option at boot time. See the
+  documentation of your boot loader (lilo or loadlin) about how to
+  pass options to the kernel. The lilo procedure is also explained in
+  the SCSI-HOWTO, available via ftp (user: anonymous) in
   sunsite.unc.edu:/pub/Linux/docs/HOWTO.) Most people say N here.
 
 ISO9660 cdrom filesystem support
 CONFIG_ISO9660_FS
-  This is the standard filesystem used on CDROMs. It was previously known 
-  as "High Sierra Filesystem" and is called "hsfs" on other Unix systems. 
-  If you have a CDROM drive and want to do more with it than just listen to
-  audio CDs and watch its LEDs, say Y (and read the CDROM-HOWTO,
-  available via ftp (user: anonymous) from
+  This is the standard filesystem used on CDROMs. It was previously
+  known as "High Sierra Filesystem" and is called "hsfs" on other Unix
+  systems.  If you have a CDROM drive and want to do more with it than
+  just listen to audio CDs and watch its LEDs, say Y (and read the
+  CDROM-HOWTO, available via ftp (user: anonymous) from
   sunsite.unc.edu:/pub/Linux/docs/HOWTO), thereby enlarging your
   kernel by about 27 kB; otherwise say N.  If you want to compile this
   as a module ( = code which can be inserted in and removed from the
@@ -2277,14 +2437,15 @@
 NCP filesystem support (to mount NetWare volumes)
 CONFIG_NCP_FS
   NCP (NetWare Core Protocol) is a protocol that runs over IPX and is
-  used by NetWare clients to talk to file servers. Enabling this
-  allows you to mount NetWare file server volumes and access them just
-  like any other directory. To actually mount the filesystem, you need
-  a special mount program, available on sunsite.unc.edu via anonymous
-  ftp in /pub/Linux/system/Filesystem/ncpfs-xx.tgz. If you want to
-  compile this as a module ( = code which can be inserted in and
-  removed from the running kernel whenever you want), say M here and
-  read Documentation/modules.txt.
+  used by NetWare clients to talk to file servers. It is to IPX what
+  nfs is to tcp/ip, if that helps. Enabling this option allows you to
+  mount NetWare file server volumes and to access them just like any
+  other Unix directory. To actually mount the filesystem, you need a
+  special mount program, as described in the IPX-HOWTO on
+  sunsite.unc.edu:/pub/Linux/docs/howto.  If you want to compile this
+  as a module ( = code which can be inserted in and removed from the
+  running kernel whenever you want), say M here and read
+  Documentation/modules.txt.
 
 Cyclades async mux support
 CONFIG_CYCLADES
@@ -2301,21 +2462,24 @@
   Stallion cards give you many serial ports. You would need something
   like this to connect more than two modems to your linux box, for
   instance in order to become a BBS. If you say Y here, you will be
-  asked for your specific card model in the next questions. If you
-  haven't heard about it, it's safe to say N.
+  asked for your specific card model in the next questions. Make sure
+  to read drivers/char/README.stallion in this case. If you have never
+  heard about all this, it's safe to say N.
  
 Stallion EasyIO or EC8/32 support 
 CONFIG_STALLION n
   If you have an EasyIO or EasyConnection 8/32 multiport Stallion
-  card, then this is for you; say Y.  If you want to compile this as a
+  card, then this is for you; say Y. Make sure to read
+  drivers/char/README.stallion. If you want to compile this as a
   module ( = code which can be inserted in and removed from the
   running kernel whenever you want), say M here and read
   Documentation/modules.txt.
 
 CONFIG_ISTALLION n
   If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
-  serial multiport card, say Y here. To compile it as a module ( =
-  code which can be inserted in and removed from the running kernel
+  serial multiport card, say Y here. Make sure to read
+  drivers/char/README.stallion. To compile it as a module ( = code
+  which can be inserted in and removed from the running kernel
   whenever you want), say M here and read Documentation/modules.txt.
 
 Parallel printer support
@@ -2493,6 +2657,35 @@
   after a lock-up. For details, read Documentation/watchdog.txt in the
   kernel source. If unsure, say N.
 
+Disable watchdog shutdown on close
+CONFIG_WATCHDOG_NOWAYOUT
+  The default watchdog behaviour is to stop the timer if the process
+  managing it closes the file. Its always remotely possible that this
+  process might get killed. In NOWAYOUT mode you cannot stop the watchdog
+  once its begun.
+
+WDT Watchdog timer
+CONFIG_WDT
+  Drivers for the WDT watchdog timer cards. These are hardware timer boards
+  that physically pull the power on and off to recover crashed machines.
+  Brutal but _very_ effective.
+
+WDT501 features
+CONFIG_WDT_501
+  Enable the onboard thermometer and voltage monitors on the extended (501)
+  card.
+
+Fan Tachometer
+CONFIG_WDT_501_FAN
+  Enable the Fan Tachometer on the WDT501. Only do this if you have a fan
+  tachometer actually set up.
+
+Software Watchdog
+CONFIG_SOFT_WATDHDOG
+  A software monitoring watchdog. This will fail to reboot your system from
+  some situations that the hardware watchdog will recover from. Equally its
+  a lot cheaper to install.
+
 Do CPU IDLE calls
 CONFIG_APM_CPU_IDLE
   Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.  On
@@ -2599,6 +2792,14 @@
 # LocalWords:  ICL EtherTeam ETH IDESCSI TXC dmesg httpd hlt sjc barlow dlp mtu
 # LocalWords:  thesphere TwoServers BOOTP DHCP ncpfs BPQETHER BPQ chipsets MG
 # LocalWords:  bsd comp Sparcstation le SunOS ie Gracilis PackeTwin PT pt LU FX
-# LocalWords:  FX TEAC SoundBlaster CR CreativeLabs LCS mS
+# LocalWords:  FX TEAC SoundBlaster CR CreativeLabs LCS mS ramdisk IDETAPE cmd
 # LocalWords:  Vertos Genoa Funai hsfs NCP NetWare tgz APM apm ioctls UltraLite
-# LocalWords:  TravelMate CDT LCD backlight VC
+# LocalWords:  TravelMate CDT LCD backlight VC RPC Mips Olivetty DECStation AXP
+# LocalWords:  PMAX MILO Alphas Multia Tseng linuxelf endian mipsel mips drv HT
+# LocalWords:  KERNELD kerneld callouts AdvanSys advansys diskquotas Admin WDT
+# LocalWords:  wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI
+# LocalWords:  QD qd UMC umc ALI ali lena fnet fr homepage azstarnet axplinux
+# LocalWords:  Avanti XL AlphaStations Jensen DECpc AXPpci UDB Cabriolet MCA RC
+# LocalWords:  AlphaPC uwaterloo cpbeaure mca AOUT OUTput PPro sipx gwdg
+# LocalWords:  Keepalive linefill RELCOM keepalive analogue CDR conf CDI INIT
+# LocalWords:  OPTi isp irq noisp VFAT vfat NTFS
diff -u --recursive --new-file v1.3.67/linux/Documentation/filesystems/ncpfs.txt linux/Documentation/filesystems/ncpfs.txt
--- v1.3.67/linux/Documentation/filesystems/ncpfs.txt	Thu Jan  1 02:00:00 1970
+++ linux/Documentation/filesystems/ncpfs.txt	Thu Feb 22 15:20:19 1996
@@ -0,0 +1,11 @@
+ncpfs is a filesystem which understands the NCP protocol, designed by the
+Novell Corporation for their NetWare(tm) product. NCP is functionally
+similar to the NFS used in the tcp/ip community.
+To mount a Netware-Filesystem, you need a special mount program, which can
+be found in ncpfs package. Homesite for ncpfs is linux01.gwdg.de/pub/ncpfs,
+but sunsite and its many mirrors will have it as well.
+
+Related products are linware and mars_nwe, which will give Linux partial
+Netware Server functionality.
+Linware's home site is: klokan.sh.cvut.cz/pub/linux/linware,
+Mars_nwe can be found on linux01.gwdg.de/pub/ncpfs.
diff -u --recursive --new-file v1.3.67/linux/MAINTAINERS linux/MAINTAINERS
--- v1.3.67/linux/MAINTAINERS	Thu Jan  1 02:00:00 1970
+++ linux/MAINTAINERS	Wed Feb 21 08:33:21 1996
@@ -0,0 +1,107 @@
+		Maintainers And Source Submission Procedures
+
+	In order to keep things easy for the maintainers please try to
+follow the guidelines given. Not all of these guidelines matter for every
+trivial patch so apply some common sense.
+
+1.	Always _test_ your changes however small on at least 4 or 5 people,
+preferably many more.
+
+2.	Try and release a few ALPHA test versions to the net. Announce them
+onto the kernel channel and await results. This is especially important
+for device drivers because often thats the only way you will find things
+like the fact version 3 firmware needs a magic fix you didnt know about, or
+some clown changed the chips on a board and not its name (Don't laugh look
+at the SMC etherpower for that).
+
+3.	Make sure your changes compile correctly in multiple configurations.
+
+4.	When you are happy with a change make it generally available for
+testing and await feedback. 
+
+5.	Make a patch available to the relevant maintainer in the list. Use
+'diff -u' to make the patch easy to merge. Be prepared to get your changes
+sent back with seemingly silly requests about formatting and variable names.
+These aren't as silly as they seem, one job the maintainers (and especially
+Linus) do is to keep things looking the same. Sometimes this means that
+the clever hack in your driver to get around a problem actual needs to
+become a generalised kernel feature ready for next time.
+	PLEASE try and include any credit lines you want added with the
+patch. It avoids people being missed off by mistake and makes it easier to
+know who wants adding and who doesn't.
+	PLEASE Document known bugs. If it doesnt work for everything or
+does something very odd once a month document it.
+
+6.	Make sure you have the right to send any changes you make. If you
+do changes at work you may find your employer owns the patch not you.
+
+7.	Happy hacking
+
+
+[This file is new: I've just put the existing network contacts in, other
+ people please add yourselves] -- AC
+
+		-----------------------------------
+
+Maintainers List (try to look for most precise areas first)
+
+P: Person
+M: Mail patches to
+L: Mailing list that is relevant to this area
+S: Status
+	Supported:	Someone is actually paid to look after this (wildly
+			improbable).
+	Maintained:	Someone actually looks after it.
+	Odd Fixes:	It has a maintainer but they don't have time to do
+			much other than throw the odd patch in. See below..
+	Orphan:		No current maintainer [but maybe you could take the 
+			role as you write your new driver].
+	Obsolete:	Ex code. Something tagged obsolete generally means
+			its been replaced by a better system and you should
+			be using that.
+
+3C501 NETWORK DRIVER
+P:	Alan Cox
+M:	net-patches@lxorguk.ukuu.org.uk
+L:	linux-net@vger.rutgers.edu
+S:	Maintained
+
+APPLETALK NETWORK LAYER
+P:	Alan Cox & University Of Michigan
+M:	net-patches@lxorguk.ukuu.org.uk, Cc: netatalk@umich.edu
+L:	[Someone fill in the netatalk list here]
+S:	Maintained
+
+AX.25 NETWORK LAYER
+P:	Jon Naylor
+M:	jsn@cs.nott.ac.uk
+L:	linux-hams@vger.rutges.edu
+S:	Maintained
+
+IPX NETWORK LAYER
+P:	Alan Cox [for the moment]
+M:	net-patches@lxorguk.ukuu.org.uk
+L:	linux-ipx@vger.rutgers.edu [will change]
+S:	Maintained
+
+NETROM NETWORK LAYER
+P:	Jon Naylor
+M:	jsn@cs.nott.ac.uk
+L:	linux-hams@vger.rutges.edu
+S:	Maintained
+
+NETWORKING [GENERAL]:
+P:	Alan Cox
+M:	net-patches@lxorguk.ukuu.org.uk
+L:	linux-net@vger.rutgers.edu
+S:	Odd Fixes <-> Maintained subject to workloads
+
+SMP:
+P:	Alan Cox
+M:	smp-patches@lxorguk.ukuu.org.uk
+L:	linux-smp@vger.rutgers.edu
+S:	Maintained
+
+REST:
+P:	Linus Torvalds
+S:	Buried alive in email
diff -u --recursive --new-file v1.3.67/linux/Makefile linux/Makefile
--- v1.3.67/linux/Makefile	Tue Feb 20 14:37:22 1996
+++ linux/Makefile	Tue Feb 20 15:36:04 1996
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 67
+SUBLEVEL = 68
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.67/linux/arch/i386/boot/bootsect.S linux/arch/i386/boot/bootsect.S
--- v1.3.67/linux/arch/i386/boot/bootsect.S	Fri Nov 17 08:42:24 1995
+++ linux/arch/i386/boot/bootsect.S	Thu Feb 22 15:29:35 1996
@@ -53,6 +53,10 @@
 ! ld86 requires an entry symbol. This may as well be the usual one.
 .globl	_main
 _main:
+	nop
+	jmp	over_magic
+	.byte	0xF0
+over_magic:
 #if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
 	int	3
 #endif
diff -u --recursive --new-file v1.3.67/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v1.3.67/linux/arch/i386/defconfig	Wed Feb 14 14:37:06 1996
+++ linux/arch/i386/defconfig	Thu Feb 22 14:50:00 1996
@@ -30,7 +30,6 @@
 # Floppy, IDE, and other block devices
 #
 CONFIG_BLK_DEV_FD=y
-# CONFIG_BLK_DEV_RAM is not set
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -43,6 +42,8 @@
 CONFIG_BLK_DEV_RZ1000=y
 # CONFIG_BLK_DEV_TRITON is not set
 # CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_XD is not set
 
 #
diff -u --recursive --new-file v1.3.67/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v1.3.67/linux/drivers/block/Config.in	Wed Feb 14 14:37:07 1996
+++ linux/drivers/block/Config.in	Thu Feb 22 14:40:01 1996
@@ -5,7 +5,6 @@
 comment 'Floppy, IDE, and other block devices'
 
 tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
-tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 bool 'Enhanced IDE/MFM/RLL disk/cdrom/tape support' CONFIG_BLK_DEV_IDE
 comment 'Please see drivers/block/README.ide for help/info on IDE drives'
 if [ "$CONFIG_BLK_DEV_IDE" = "n" ]; then
@@ -29,6 +28,10 @@
     bool '      ALI M1439/M1445 chipset support' CONFIG_BLK_DEV_ALI14XX
   fi
 fi
+
+tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+
 if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then
   define_bool CONFIG_BLK_DEV_HD y
 fi
diff -u --recursive --new-file v1.3.67/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v1.3.67/linux/drivers/block/Makefile	Fri Feb  9 17:52:58 1996
+++ linux/drivers/block/Makefile	Thu Feb 22 14:40:01 1996
@@ -36,6 +36,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_BLK_DEV_LOOP),y)
+L_OBJS += loop.o
+else
+  ifeq ($(CONFIG_BLK_DEV_LOOP),m)
+  M_OBJS += loop.o
+  endif
+endif
+
 ifeq ($(CONFIG_BLK_DEV_HD),y)
 L_OBJS += hd.o
 endif
diff -u --recursive --new-file v1.3.67/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v1.3.67/linux/drivers/block/ll_rw_blk.c	Sat Feb 17 16:02:46 1996
+++ linux/drivers/block/ll_rw_blk.c	Thu Feb 22 14:40:01 1996
@@ -608,6 +608,9 @@
 #ifdef CONFIG_BLK_DEV_RAM
 	rd_init();
 #endif
+#ifdef CONFIG_BLK_DEV_LOOP
+	loop_init();
+#endif
 #ifdef CONFIG_BLK_DEV_IDE
 	ide_init();		/* this MUST preceed hd_init */
 #endif
diff -u --recursive --new-file v1.3.67/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v1.3.67/linux/drivers/block/loop.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/block/loop.c	Thu Feb 22 15:18:43 1996
@@ -0,0 +1,500 @@
+/*
+ *  linux/drivers/block/loop.c
+ *
+ *  Written by Theodore Ts'o, 3/29/93
+ * 
+ * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
+ * permitted under the GNU Public License.
+ *
+ * DES encryption plus some minor changes by Werner Almesberger, 30-MAY-1993
+ *
+ * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994
+ *
+ * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
+ */
+
+#include <linux/module.h>
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <asm/segment.h>
+#include "loop.h"
+
+#ifdef DES_AVAILABLE
+#include "des.h"
+#endif
+
+#define DEFAULT_MAJOR_NR 28
+int loop_major = DEFAULT_MAJOR_NR;
+#define MAJOR_NR loop_major	/* not necessarily constant */
+
+#define DEVICE_NAME "loop"
+#define DEVICE_REQUEST do_lo_request
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define DEVICE_NO_RANDOM
+#define TIMEOUT_VALUE (6 * HZ)
+#include <linux/blk.h>
+
+#define MAX_LOOP 8
+static struct loop_device loop_dev[MAX_LOOP];
+static int loop_sizes[MAX_LOOP];
+
+/*
+ * Transfer functions
+ */
+static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf,
+		  char *loop_buf, int size)
+{
+	if (cmd == READ)
+		memcpy(loop_buf, raw_buf, size);
+	else
+		memcpy(raw_buf, loop_buf, size);
+	return 0;
+}
+
+static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf,
+		 char *loop_buf, int size)
+{
+	char	*in, *out, *key;
+	int	i, keysize;
+
+	if (cmd == READ) {
+		in = raw_buf;
+		out = loop_buf;
+	} else {
+		in = loop_buf;
+		out = raw_buf;
+	}
+	key = lo->lo_encrypt_key;
+	keysize = lo->lo_encrypt_key_size;
+	for (i=0; i < size; i++)
+		*out++ = *in++ ^ key[(i & 511) % keysize];
+	return 0;
+}
+
+#ifdef DES_AVAILABLE
+static int transfer_des(struct loop_device *lo, int cmd, char *raw_buf,
+		  char *loop_buf, int size)
+{
+	unsigned long tmp[2];
+	unsigned long x0,x1,p0,p1;
+
+	if (size & 7)
+		return -EINVAL;
+	x0 = lo->lo_des_init[0];
+	x1 = lo->lo_des_init[1];
+	while (size) {
+		if (cmd == READ) {
+			tmp[0] = (p0 = ((unsigned long *) raw_buf)[0])^x0;
+			tmp[1] = (p1 = ((unsigned long *) raw_buf)[1])^x1;
+			des_ecb_encrypt((des_cblock *) tmp,(des_cblock *)
+			    loop_buf,lo->lo_des_key,DES_ENCRYPT);
+			x0 = p0^((unsigned long *) loop_buf)[0];
+			x1 = p1^((unsigned long *) loop_buf)[1];
+		}
+		else {
+			p0 = ((unsigned long *) loop_buf)[0];
+			p1 = ((unsigned long *) loop_buf)[1];
+			des_ecb_encrypt((des_cblock *) loop_buf,(des_cblock *)
+			    raw_buf,lo->lo_des_key,DES_DECRYPT);
+			((unsigned long *) raw_buf)[0] ^= x0;
+			((unsigned long *) raw_buf)[1] ^= x1;
+			x0 = p0^((unsigned long *) raw_buf)[0];
+			x1 = p1^((unsigned long *) raw_buf)[1];
+		}
+		size -= 8;
+		raw_buf += 8;
+		loop_buf += 8;
+	}
+	return 0;
+}
+#endif
+
+static transfer_proc_t xfer_funcs[MAX_LOOP] = {
+	transfer_none,		/* LO_CRYPT_NONE */
+	transfer_xor,		/* LO_CRYPT_XOR */
+#ifdef DES_AVAILABLE
+	transfer_des,		/* LO_CRYPT_DES */
+#else
+	NULL,			/* LO_CRYPT_DES */
+#endif
+	0			/* LO_CRYPT_IDEA */
+};
+
+
+#define MAX_DISK_SIZE 1024*1024*1024
+
+
+static void figure_loop_size(struct loop_device *lo)
+{
+	int	size;
+
+	if (S_ISREG(lo->lo_inode->i_mode))
+		size = (lo->lo_inode->i_size - lo->lo_offset) / 1024;
+	else {
+		if (blk_size[MAJOR(lo->lo_device)])
+			size = ((blk_size[MAJOR(lo->lo_device)]
+				 [MINOR(lo->lo_device)]) -
+				(lo->lo_offset/1024));
+		else
+			size = MAX_DISK_SIZE;
+	}
+	loop_sizes[lo->lo_number] = size;
+}
+
+static void do_lo_request(void)
+{
+	int	real_block, block, offset, len, blksize, size;
+	char	*dest_addr;
+	struct loop_device *lo;
+	struct buffer_head *bh;
+
+repeat:
+	INIT_REQUEST;
+	if (MINOR(CURRENT->rq_dev) >= MAX_LOOP)
+		goto error_out;
+	lo = &loop_dev[MINOR(CURRENT->rq_dev)];
+	if (!lo->lo_inode || !lo->transfer)
+		goto error_out;
+
+	blksize = BLOCK_SIZE;
+	if (blksize_size[MAJOR(lo->lo_device)]) {
+	    blksize = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
+	    if (!blksize)
+	      blksize = BLOCK_SIZE;
+	}
+
+	dest_addr = CURRENT->buffer;
+	
+	if (blksize < 512) {
+		block = CURRENT->sector * (512/blksize);
+		offset = 0;
+	} else {
+		block = CURRENT->sector / (blksize >> 9);
+		offset = CURRENT->sector % (blksize >> 9);
+	}
+	block += lo->lo_offset / blksize;
+	offset += lo->lo_offset % blksize;
+	if (offset > blksize) {
+		block++;
+		offset -= blksize;
+	}
+	len = CURRENT->current_nr_sectors << 9;
+	if ((CURRENT->cmd != WRITE) && (CURRENT->cmd != READ)) {
+		printk("unknown loop device command (%d)?!?", CURRENT->cmd);
+		goto error_out;
+	}
+	while (len > 0) {
+		real_block = block;
+		if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
+			real_block = bmap(lo->lo_inode, block);
+			if (!real_block) {
+				printk("loop: block %d not present\n", block);
+				goto error_out;
+			}
+		}
+		bh = getblk(lo->lo_device, real_block, blksize);
+		if (!bh) {
+			printk("loop: device %s: getblk(-, %d, %d) returned NULL",
+			       kdevname(lo->lo_device),
+			       block, blksize);
+			goto error_out;
+		}
+		if (!buffer_uptodate(bh) && ((CURRENT->cmd == READ) ||
+					(offset || (len < blksize)))) {
+			ll_rw_block(READ, 1, &bh);
+			wait_on_buffer(bh);
+			if (!buffer_uptodate(bh)) {
+				brelse(bh);
+				goto error_out;
+			}
+		}
+		size = blksize - offset;
+		if (size > len)
+			size = len;
+		if ((lo->transfer)(lo, CURRENT->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) {
+			set_bit(BH_Dirty, &bh->b_state);
+			ll_rw_block(WRITE, 1, &bh);
+			wait_on_buffer(bh);
+			if (buffer_dirty(bh)) {
+				brelse(bh);
+				goto error_out;
+			}
+		}
+		brelse(bh);
+		dest_addr += size;
+		len -= size;
+		offset = 0;
+		block++;
+	}
+	end_request(1);
+	goto repeat;
+error_out:
+	end_request(0);
+	goto repeat;
+}
+
+static int loop_set_fd(struct loop_device *lo, unsigned int arg)
+{
+	struct inode	*inode;
+	
+	if (arg >= NR_OPEN || !current->files->fd[arg])
+		return -EBADF;
+	if (lo->lo_inode)
+		return -EBUSY;
+	inode = current->files->fd[arg]->f_inode;
+	if (!inode) {
+		printk("loop_set_fd: NULL inode?!?\n");
+		return -EINVAL;
+	}
+	if (S_ISREG(inode->i_mode)) {
+		lo->lo_device = inode->i_dev;
+		lo->lo_flags |= LO_FLAGS_DO_BMAP;
+	} else if (S_ISBLK(inode->i_mode))
+			lo->lo_device = inode->i_rdev;
+		else
+			return -EINVAL;
+	lo->lo_inode = inode;
+	lo->lo_inode->i_count++;
+	lo->transfer = NULL;
+	figure_loop_size(lo);
+	return 0;
+}
+
+static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
+{
+	if (!lo->lo_inode)
+		return -ENXIO;
+	if (lo->lo_refcnt > 1)
+		return -EBUSY;
+	lo->lo_inode->i_count--;
+	lo->lo_device = 0;
+	lo->lo_inode = NULL;
+	lo->lo_encrypt_type = 0;
+	lo->lo_offset = 0;
+	lo->lo_encrypt_key_size = 0;
+	memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
+	memset(lo->lo_name, 0, LO_NAME_SIZE);
+	invalidate_buffers(dev);
+	return 0;
+}
+
+static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
+{
+	struct loop_info info;
+
+	if (!lo->lo_inode)
+		return -ENXIO;
+	if (!arg)
+		return -EINVAL;
+	memcpy_fromfs(&info, arg, sizeof(info));
+	if (info.lo_encrypt_key_size > LO_KEY_SIZE)
+		return -EINVAL;
+	switch (info.lo_encrypt_type) {
+	case LO_CRYPT_NONE:
+		break;
+	case LO_CRYPT_XOR:
+		if (info.lo_encrypt_key_size < 0)
+			return -EINVAL;
+		break;
+#ifdef DES_AVAILABLE
+	case LO_CRYPT_DES:
+		if (info.lo_encrypt_key_size != 8)
+			return -EINVAL;
+		des_set_key((des_cblock *) lo->lo_encrypt_key,
+		   lo->lo_des_key);
+		memcpy(lo->lo_des_init,info.lo_init,8);
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+	lo->lo_offset = info.lo_offset;
+	strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);
+	lo->lo_encrypt_type = info.lo_encrypt_type;
+	lo->transfer = xfer_funcs[lo->lo_encrypt_type];
+	lo->lo_encrypt_key_size = info.lo_encrypt_key_size;
+	if (info.lo_encrypt_key_size)
+		memcpy(lo->lo_encrypt_key, info.lo_encrypt_key,
+		       info.lo_encrypt_key_size);
+	figure_loop_size(lo);
+	return 0;
+}
+
+static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
+{
+	struct loop_info	info;
+	
+	if (!lo->lo_inode)
+		return -ENXIO;
+	if (!arg)
+		return -EINVAL;
+	memset(&info, 0, sizeof(info));
+	info.lo_number = lo->lo_number;
+	info.lo_device = kdev_t_to_nr(lo->lo_inode->i_dev);
+	info.lo_inode = lo->lo_inode->i_ino;
+	info.lo_rdevice = kdev_t_to_nr(lo->lo_device);
+	info.lo_offset = lo->lo_offset;
+	info.lo_flags = lo->lo_flags;
+	strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
+	info.lo_encrypt_type = lo->lo_encrypt_type;
+	if (lo->lo_encrypt_key_size && suser()) {
+		info.lo_encrypt_key_size = lo->lo_encrypt_key_size;
+		memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,
+		       lo->lo_encrypt_key_size);
+	}
+	memcpy_tofs(arg, &info, sizeof(info));
+	return 0;
+}
+
+static int lo_ioctl(struct inode * inode, struct file * file,
+	unsigned int cmd, unsigned long arg)
+{
+	struct loop_device *lo;
+	int dev, err;
+
+	if (!inode)
+		return -EINVAL;
+	if (MAJOR(inode->i_rdev) != loop_major) {
+		printk("lo_ioctl: pseudo-major != %d\n", loop_major);
+		return -ENODEV;
+	}
+	dev = MINOR(inode->i_rdev);
+	if (dev >= MAX_LOOP)
+		return -ENODEV;
+	lo = &loop_dev[dev];
+	switch (cmd) {
+	case LOOP_SET_FD:
+		return loop_set_fd(lo, arg);
+	case LOOP_CLR_FD:
+		return loop_clr_fd(lo, inode->i_rdev);
+	case LOOP_SET_STATUS:
+		return loop_set_status(lo, (struct loop_info *) arg);
+	case LOOP_GET_STATUS:
+		return loop_get_status(lo, (struct loop_info *) arg);
+	case BLKGETSIZE:   /* Return device size */
+		if (!lo->lo_inode)
+			return -ENXIO;
+		if (!arg)  return -EINVAL;
+		err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
+		if (err)
+			return err;
+		put_fs_long(loop_sizes[lo->lo_number] << 1, (long *) arg);
+		return 0;
+		default:
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static int lo_open(struct inode *inode, struct file *file)
+{
+	struct loop_device *lo;
+	int	dev;
+
+	if (!inode)
+		return -EINVAL;
+	if (MAJOR(inode->i_rdev) != loop_major) {
+		printk("lo_open: pseudo-major != %d\n", loop_major);
+		return -ENODEV;
+	}
+	dev = MINOR(inode->i_rdev);
+	if (dev >= MAX_LOOP)
+		return -ENODEV;
+	lo = &loop_dev[dev];
+	lo->lo_refcnt++;
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static void lo_release(struct inode *inode, struct file *file)
+{
+	struct loop_device *lo;
+	int	dev;
+
+	if (!inode)
+		return;
+	if (MAJOR(inode->i_rdev) != loop_major) {
+		printk("lo_release: pseudo-major != %d\n", loop_major);
+		return;
+	}
+	dev = MINOR(inode->i_rdev);
+	if (dev >= MAX_LOOP)
+		return;
+	sync_dev(inode->i_rdev);
+	lo = &loop_dev[dev];
+	if (lo->lo_refcnt <= 0)
+		printk("lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);
+	else  {
+		lo->lo_refcnt--;
+		MOD_DEC_USE_COUNT;
+	}
+
+	return;
+}
+
+static struct file_operations lo_fops = {
+	NULL,			/* lseek - default */
+	block_read,		/* read - general block-dev read */
+	block_write,		/* write - general block-dev write */
+	NULL,			/* readdir - bad */
+	NULL,			/* select */
+	lo_ioctl,		/* ioctl */
+	NULL,			/* mmap */
+	lo_open,		/* open */
+	lo_release		/* release */
+};
+
+/*
+ * And now the modules code and kernel interface.
+ */
+#ifdef MODULE
+#define loop_init init_module
+#endif
+
+int
+loop_init( void ) {
+	int	i = (loop_major ? loop_major : DEFAULT_MAJOR_NR);
+
+	if (register_blkdev(i, "loop", &lo_fops) &&
+	    (i = register_blkdev(0, "loop", &lo_fops)) <= 0) {
+		printk("Unable to get major number for loop device\n");
+		return -EIO;
+	}
+	loop_major = i;
+#ifdef MODULE
+	if (i != DEFAULT_MAJOR_NR)
+#endif
+	  printk("loop: registered device at major %d\n",loop_major);
+
+	blk_dev[loop_major].request_fn = DEVICE_REQUEST;
+	for (i=0; i < MAX_LOOP; i++) {
+		memset(&loop_dev[i], 0, sizeof(struct loop_device));
+		loop_dev[i].lo_number = i;
+	}
+	memset(&loop_sizes, 0, sizeof(loop_sizes));
+	blk_size[loop_major] = loop_sizes;
+
+	return 0;
+}
+
+#ifdef MODULE
+void
+cleanup_module( void ) {
+  if (unregister_blkdev(loop_major, "loop") != 0)
+    printk("loop: cleanup_module failed\n");
+}
+#endif
diff -u --recursive --new-file v1.3.67/linux/drivers/block/loop.h linux/drivers/block/loop.h
--- v1.3.67/linux/drivers/block/loop.h	Thu Jan  1 02:00:00 1970
+++ linux/drivers/block/loop.h	Thu Feb 22 14:40:01 1996
@@ -0,0 +1,77 @@
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
+
+/*
+ * include/linux/loop.h
+ *
+ * Written by Theodore Ts'o, 3/29/93.
+ *
+ * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
+ * permitted under the GNU Public License.
+ */
+
+#define LO_NAME_SIZE	64
+#define LO_KEY_SIZE	32
+       
+struct loop_device {
+	int		lo_number;
+	struct inode	*lo_inode;
+	int		lo_refcnt;
+	kdev_t		lo_device;
+	int		lo_offset;
+	int		lo_encrypt_type;
+	int		lo_encrypt_key_size;
+	int		lo_flags;
+	int		(*transfer)(struct loop_device *, int cmd,
+				    char *raw_buf, char *loop_buf, int size);
+	char		lo_name[LO_NAME_SIZE];
+	char		lo_encrypt_key[LO_KEY_SIZE];
+#ifdef DES_AVAILABLE
+	des_key_schedule lo_des_key;
+	unsigned long	lo_des_init[2];
+#endif
+};
+
+typedef	int (* transfer_proc_t)(struct loop_device *, int cmd,
+				char *raw_buf, char *loop_buf, int size);
+
+/*
+ * Loop flags
+ */
+#define LO_FLAGS_DO_BMAP	0x00000001
+
+struct loop_info {
+	int		lo_number;	/* ioctl r/o */
+	dev_t		lo_device; 	/* ioctl r/o */
+	unsigned long	lo_inode; 	/* ioctl r/o */
+	dev_t		lo_rdevice; 	/* ioctl r/o */
+	int		lo_offset;
+	int		lo_encrypt_type;
+	int		lo_encrypt_key_size; 	/* ioctl w/o */
+	int		lo_flags;	/* ioctl r/o */
+	char		lo_name[LO_NAME_SIZE];
+	unsigned char	lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+	unsigned long	lo_init[2];
+	char		reserved[4];
+};
+
+/*
+ * Loop encryption types --- LO_CRYPT_IDEA isn't supported yet
+ */
+
+#define LO_CRYPT_NONE	0
+#define LO_CRYPT_XOR	1
+#define LO_CRYPT_DES	2
+#define LO_CRYPT_IDEA	5
+#define MAX_LO_CRYPT	4
+
+/*
+ * IOCTL commands --- we will commandeer 0x4C ('L')
+ */
+
+#define LOOP_SET_FD	0x4C00
+#define LOOP_CLR_FD	0x4C01
+#define LOOP_SET_STATUS	0x4C02
+#define LOOP_GET_STATUS	0x4C03
+
+#endif
diff -u --recursive --new-file v1.3.67/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v1.3.67/linux/drivers/char/Config.in	Sat Feb 17 16:02:47 1996
+++ linux/drivers/char/Config.in	Thu Feb 22 07:40:17 1996
@@ -13,7 +13,7 @@
 tristate 'Parallel printer support' CONFIG_PRINTER
 tristate 'Logitech busmouse support' CONFIG_BUSMOUSE
 tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
-if [ "$CONFIG_PSMOUSE" = "y" ]; then
+if [ "$CONFIG_PSMOUSE" != "n" ]; then
   bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
 fi
 tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE
@@ -39,6 +39,7 @@
 fi
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
+  bool '    Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
   tristate '   WDT Watchdog timer' CONFIG_WDT
   if [ "$CONFIG_WDT" = "y" ]; then
      bool '       WDT501 features' CONFIG_WDT_501
diff -u --recursive --new-file v1.3.67/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v1.3.67/linux/drivers/char/softdog.c	Wed Feb  7 15:11:23 1996
+++ linux/drivers/char/softdog.c	Wed Feb 21 13:12:18 1996
@@ -18,12 +18,13 @@
  *	driver this won't always recover a failed machine.
  */
  
- 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mouse.h>
+
 #define WATCHDOG_MINOR	130
 #define TIMER_MARGIN	(60*HZ)		/* Allow 1 minute */
 
@@ -68,7 +69,9 @@
 	/*
 	 *	Shut off the timer.
 	 */
+#ifndef CONFIG_WATCHDOG_NOWAYOUT	 
 	del_timer(&watchdog_ticktock);
+#endif	
 	timer_alive=0;
 }
 
diff -u --recursive --new-file v1.3.67/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v1.3.67/linux/drivers/char/wdt.c	Wed Feb  7 15:11:24 1996
+++ linux/drivers/char/wdt.c	Wed Feb 21 08:33:22 1996
@@ -187,8 +187,10 @@
 {
 	if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
 	{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT	
 		inb_p(WDT_DC);		/* Disable counters */
 		wdt_ctr_load(2,0);	/* 0 length reset pulses now */
+#endif		
 		wdt_is_open=0;
 	}
 	MOD_DEC_USE_COUNT;
diff -u --recursive --new-file v1.3.67/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v1.3.67/linux/drivers/net/Makefile	Fri Jan 26 01:37:06 1996
+++ linux/drivers/net/Makefile	Wed Feb 21 08:33:22 1996
@@ -36,10 +36,10 @@
 endif
 
 ifeq ($(CONFIG_NET_IPIP),y)
-L_OBJS += tunnel.o
+L_OBJS += new_tunnel.o
 else
   ifeq ($(CONFIG_NET_IPIP),m)
-  M_OBJS += tunnel.o
+  M_OBJS += new_tunnel.o
   endif
 endif
 
diff -u --recursive --new-file v1.3.67/linux/drivers/net/new_tunnel.c linux/drivers/net/new_tunnel.c
--- v1.3.67/linux/drivers/net/new_tunnel.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/new_tunnel.c	Wed Feb 21 13:11:50 1996
@@ -0,0 +1,426 @@
+/* tunnel.c: an IP tunnel driver
+
+	The purpose of this driver is to provide an IP tunnel through
+	which you can tunnel network traffic transparently across subnets.
+
+	This was written by looking at Nick Holloway's dummy driver
+	Thanks for the great code!
+
+		-Sam Lantinga	(slouken@cs.ucdavis.edu)  02/01/95
+		
+	Minor tweaks:
+		Cleaned up the code a little and added some pre-1.3.0 tweaks.
+		dev->hard_header/hard_header_len changed to use no headers.
+		Comments/bracketing tweaked.
+		Made the tunnels use dev->name not tunnel: when error reporting.
+		Added tx_dropped stat
+		
+		-Alan Cox	(Alan.Cox@linux.org) 21 March 95
+
+	Reworked:
+		Changed to tunnel to destination gateway instead of pointopoint
+		Almost completely rewritten
+		Note:  There is currently no firewall or ICMP handling done.
+
+		-Sam Lantinga	(slouken@cs.ucdavis.edu) 02/13/96
+		
+	Note:
+		The old driver is in tunnel.c if you have funnies with the
+		new one.
+*/
+
+/* Things I wish I had known when writing the tunnel driver:
+
+	When the tunnel_xmit() function is called, the skb contains the
+	packet to be sent (plus a great deal of extra info), and dev
+	contains the tunnel device that _we_ are.
+
+	When we are passed a packet, we are expected to fill in the
+	source address with our source IP address.
+
+	What is the proper way to allocate, copy and free a buffer?
+	After you allocate it, it is a "0 length" chunk of memory
+	starting at zero.  If you want to add headers to the buffer
+	later, you'll have to call "skb_reserve(skb, amount)" with
+	the amount of memory you want reserved.  Then, you call
+	"skb_put(skb, amount)" with the amount of space you want in
+	the buffer.  skb_put() returns a pointer to the top (#0) of
+	that buffer.  skb->len is set to the amount of space you have
+	"allocated" with skb_put().  You can then write up to skb->len
+	bytes to that buffer.  If you need more, you can call skb_put()
+	again with the additional amount of space you need.  You can
+	find out how much more space you can allocate by calling 
+	"skb_tailroom(skb)".
+	Now, to add header space, call "skb_push(skb, header_len)".
+	This creates space at the beginning of the buffer and returns
+	a pointer to this new space.  If later you need to strip a
+	header from a buffer, call "skb_pull(skb, header_len)".
+	skb_headroom() will return how much space is left at the top
+	of the buffer (before the main data).  Remember, this headroom
+	space must be reserved before the skb_put() function is called.
+*/
+
+#include <linux/module.h>
+
+/* Only two headers!! :-) */
+#include <net/ip.h>
+#include <linux/if_arp.h>
+
+
+/*#define TUNNEL_DEBUG*/
+
+/* 
+ *	Our header is a simple IP packet with no options
+ */
+ 
+#define tunnel_hlen	sizeof(struct iphdr)
+
+/*
+ *	Okay, this needs to be high enough that we can fit a "standard"
+ *	ethernet header and an IP tunnel header into the outgoing packet.
+ *	[36 bytes]
+ */
+ 
+#define TUNL_HLEN	(((ETH_HLEN+15)&~15)+tunl_hlen)
+
+
+#ifdef MODULE
+static int tunnel_open(struct device *dev)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int tunnel_close(struct device *dev)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+#endif
+
+#ifdef TUNNEL_DEBUG
+void print_ip(struct iphdr *ip)
+{
+	unsigned char *ipaddr;
+
+	printk("IP packet:\n");
+	printk("--- header len = %d\n", ip->ihl*4);
+	printk("--- ip version: %d\n", ip->version);
+	printk("--- ip protocol: %d\n", ip->protocol);
+	ipaddr=(unsigned char *)&ip->saddr;
+	printk("--- source address: %u.%u.%u.%u\n", 
+			*ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
+	ipaddr=(unsigned char *)&ip->daddr;
+	printk("--- destination address: %u.%u.%u.%u\n", 
+			*ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
+	printk("--- total packet len: %d\n", ntohs(ip->tot_len));
+}
+#endif
+
+/*
+ *	This function assumes it is being called from dev_queue_xmit()
+ *	and that skb is filled properly by that function.
+ */
+
+static int tunnel_xmit(struct sk_buff *skb, struct device *dev)
+{
+	struct enet_statistics *stats;		/* This device's statistics */
+	struct rtable *rt;     			/* Route to the other host */
+	struct device *tdev;			/* Device to other host */
+	struct iphdr  *iph;			/* Our new IP header */
+	__u32          target;			/* The other host's IP address */
+	int      max_headroom;			/* The extra header space needed */
+
+	/*
+	 *	Return if there is nothing to do.  (Does this ever happen?)
+	 */
+	if (skb == NULL || dev == NULL) {
+#ifdef TUNNEL_DEBUG
+		printk ( KERN_INFO "tunnel: Nothing to do!\n" );
+#endif
+		return 0;
+	}
+
+	/* 
+	 *	Make sure we are not busy (check lock variable) 
+	 */
+	 
+	stats = (struct enet_statistics *)dev->priv;
+	cli();
+	if (dev->tbusy != 0) 
+	{
+		sti();
+		stats->tx_errors++;
+		return(1);
+	}
+	dev->tbusy = 1;
+	sti();
+  
+	/*printk("-");*/
+	/*
+	 *  First things first.  Look up the destination address in the 
+	 *  routing tables
+	 */
+	iph = (struct iphdr *) skb->data;
+	if ((rt = ip_rt_route(iph->daddr, 0)) == NULL)
+	{ 
+		/* No route to host */
+		/* Where did the packet come from? */
+		/*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
+		printk ( KERN_INFO "%s: Packet with no route!\n", dev->name );
+		dev->tbusy=0;
+		stats->tx_errors++;
+		return(1);
+	}
+
+	if (!(rt->rt_flags & RTF_GATEWAY))
+	{ 
+		/* No gateway to tunnel through? */
+		/* Where did the packet come from? */
+		/*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
+		printk ( KERN_INFO "%s: Packet with no target gateway!\n", dev->name);
+		ip_rt_put(rt);
+		dev->tbusy=0;
+		stats->tx_errors++;
+		return(1);
+	}
+	target = rt->rt_gateway;
+	ip_rt_put(rt);
+
+	if ((rt = ip_rt_route(target, 0)) == NULL)
+	{ 
+		/* No route to host */
+		/* Where did the packet come from? */
+		/*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
+		printk ( KERN_INFO "%s: Can't reach target gateway!\n", dev->name);
+		dev->tbusy=0;
+		stats->tx_errors++;
+		return(1);
+	}
+	tdev = rt->rt_dev;
+
+	if (tdev == dev)
+	{ 
+		/* Tunnel to ourselves?  -- I don't think so. */
+		printk ( KERN_INFO "%s: Packet targetted at myself!\n" ,dev->name);
+		ip_rt_put(rt);
+		dev->tbusy=0;
+		stats->tx_errors++;
+		return(1);
+	}
+
+#ifdef TUNNEL_DEBUG
+	printk("Old IP Header....\n");
+	print_ip(iph);
+#endif
+
+	/*
+	 * Okay, now see if we can stuff it in the buffer as-is.
+	 */
+	max_headroom = ((tunnel_hlen+tdev->hard_header_len+15)&~15);
+#ifdef TUNNEL_DEBUG
+printk("Room left at head: %d\n", skb_headroom(skb));
+printk("Room left at tail: %d\n", skb_tailroom(skb));
+printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
+#endif
+	if (skb_headroom(skb) >= max_headroom) {
+		skb->h.iph = (struct iphdr *) skb_push(skb, tunnel_hlen);
+	} else {
+		struct sk_buff *new_skb;
+
+		if ( !(new_skb = dev_alloc_skb(skb->len+max_headroom)) ) 
+		{
+			printk( KERN_INFO "%s: Out of memory, dropped packet\n",
+				dev->name);
+			ip_rt_put(rt);
+  			dev->tbusy = 0;
+  			stats->tx_dropped++;
+			return(1);
+		}
+		new_skb->free = 1;
+
+		/*
+		 * Reserve space for our header
+		 */
+		skb_reserve(new_skb, tunnel_hlen);
+		new_skb->h.iph = (struct iphdr *) skb_push(new_skb, tunnel_hlen);
+		/*
+		 * Copy the old packet to the new buffer.
+		 * Note that new_skb->h.iph is our (tunnel driver's) header
+		 * and new_skb->ip_hdr is the IP header of the old packet.
+		 */
+		new_skb->ip_hdr = (struct iphdr *) skb_put(new_skb, skb->len);
+		memcpy(new_skb->ip_hdr, skb->data, skb->len);
+		/* Is this necessary? */
+		memcpy(new_skb->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
+
+		/* Free the old packet, we no longer need it */
+		kfree_skb(skb, FREE_WRITE);
+		skb = new_skb;
+	}
+
+	/*
+	 *	Push down and install the IPIP header.
+	 */
+	iph = skb->h.iph;
+	iph->version	= 	4;
+	iph->tos		=	skb->ip_hdr->tos;
+	iph->ttl		=	skb->ip_hdr->ttl;
+	iph->frag_off		=	0;
+	iph->daddr		=	target;
+	iph->saddr		=	tdev->pa_addr;
+	iph->protocol		=	IPPROTO_IPIP;
+	iph->ihl		=	5;
+	iph->tot_len		=	htons(skb->len);
+	iph->id			=	htons(ip_id_count++);	/* Race condition here? */
+	ip_send_check(iph);
+	skb->ip_hdr = skb->h.iph;
+
+#ifdef TUNNEL_DEBUG
+	printk("New IP Header....\n");
+	print_ip(iph);
+#endif
+
+	/*
+	 *	Send the packet on its way!
+	 *	Note that dev_queue_xmit() will eventually free the skb.
+	 *	If ip_forward() made a copy, it will return 1 so we can free.
+	 */
+
+	if (ip_forward(skb, dev, 0, target) == 1)
+		kfree_skb(skb, FREE_WRITE);
+
+	/*
+	 *	Clean up:  We're done with the route and the packet
+	 */
+	 
+	ip_rt_put(rt);
+ 
+#ifdef TUNNEL_DEBUG
+	printk("Packet sent through tunnel interface!\n");
+#endif
+/*printk(">");*/
+	/* Record statistics and return */
+	stats->tx_packets++;
+	dev->tbusy=0;
+	return 0;
+}
+
+static struct enet_statistics *
+tunnel_get_stats(struct device *dev)
+{
+	return((struct enet_statistics*) dev->priv);
+}
+
+/*
+ *	Called when a new tunnel device is initialized.
+ *	The new tunnel device structure is passed to us.
+ */
+ 
+int tunnel_init(struct device *dev)
+{
+	int i;
+
+	/* Oh, just say we're here, in case anyone cares */
+	static int tun_msg=0;
+	if(!tun_msg)
+	{
+		printk ( KERN_INFO "tunnel: version v0.2b\n" );
+		tun_msg=1;
+	}
+
+	/* Add our tunnel functions to the device */
+#ifdef MODULE
+	dev->open		= tunnel_open;
+	dev->stop		= tunnel_close;
+#endif
+	dev->hard_start_xmit	= tunnel_xmit;
+	dev->get_stats		= tunnel_get_stats;
+	dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
+	if (dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct enet_statistics));
+
+	/* Initialize the tunnel device structure */
+	for (i = 0; i < DEV_NUMBUFFS; i++)
+		skb_queue_head_init(&dev->buffs[i]);
+
+	dev->hard_header	= NULL;
+	dev->rebuild_header 	= NULL;
+	dev->set_mac_address 	= NULL;
+	dev->header_cache_bind 	= NULL;
+	dev->header_cache_update= NULL;
+
+	dev->type				= ARPHRD_TUNNEL;
+	dev->hard_header_len 	= (tunnel_hlen+ETH_HLEN);
+	dev->mtu		= 1500-tunnel_hlen; 	/* eth_mtu */
+	dev->addr_len		= 0;		/* Is this only for ARP? */
+	dev->tx_queue_len	= 2;		/* Small queue */
+											it should all run through */
+	memset(dev->broadcast,0xFF, ETH_ALEN);
+
+	/* New-style flags. */
+	dev->flags		= IFF_NOARP;	/* Don't use ARP on this device */
+						/* No broadcasting through a tunnel */
+	dev->family		= AF_INET;
+	dev->pa_addr		= 0;
+	dev->pa_brdaddr 	= 0;
+	dev->pa_mask		= 0;
+	dev->pa_alen		= 4;
+
+	/* We're done.  Have I forgotten anything? */
+	return 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/*  Module specific interface                                      */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifdef MODULE
+
+static int tunnel_probe(struct device *dev)
+{
+	tunnel_init(dev);
+	return 0;
+}
+
+static struct device dev_tunnel = {
+	"tunl0\0   ", 
+	0, 0, 0, 0,
+ 	0x0, 0,
+ 	0, 0, 0, NULL, tunnel_probe };
+
+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++;
+	}
+	
+#ifdef TUNNEL_DEBUG
+	printk("tunnel: registering device %s\n", dev_tunnel.name);
+#endif
+	if (register_netdev(&dev_tunnel) != 0)
+		return -EIO;
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	unregister_netdev(&dev_tunnel);
+	kfree_s(dev_tunnel.priv,sizeof(struct enet_statistics));
+	dev_tunnel.priv=NULL;
+}
+#endif /* MODULE */
+
+
+
+
+ 
+
+
+
diff -u --recursive --new-file v1.3.67/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v1.3.67/linux/drivers/pci/pci.c	Sat Feb 17 16:02:49 1996
+++ linux/drivers/pci/pci.c	Thu Feb 22 15:35:56 1996
@@ -106,6 +106,8 @@
 	DEVICE( OPTI,		OPTI_82C558,	"82C558"),
 	DEVICE( OPTI,		OPTI_82C621,	"82C621"),
 	DEVICE( OPTI,		OPTI_82C822,	"82C822"),
+	DEVICE( SGS,		SGS_2000,	"STG 2000X"),
+	DEVICE( SGS,		SGS_1764,	"STG 1764X"),
 	DEVICE( BUSLOGIC,	BUSLOGIC_946C_2,"BT-946C"),
 	DEVICE( BUSLOGIC,	BUSLOGIC_946C,	"BT-946C"),
 	DEVICE( BUSLOGIC,	BUSLOGIC_930,	"BT-930"),
@@ -151,6 +153,7 @@
 	DEVICE( ASP,		ASP_ABP940,	"ABP940"),
 	DEVICE( IMS,		IMS_8849,	"8849"),
 	DEVICE( TEKRAM2,	TEKRAM2_690c,	"DC690c"),
+	DEVICE( AMCC,		AMCC_MYRINET,	"Myrinet PCI (M2-PCI-32)"),
 	DEVICE( INTERG,		INTERG_1680,	"IGA-1680"),
 	DEVICE( REALTEK,	REALTEK_8029,	"8029"),
 	DEVICE( INIT,		INIT_320P,	"320 P"),
@@ -171,6 +174,10 @@
 	DEVICE( ZEITNET,	ZEITNET_1225,	"1225"),
 	DEVICE( SPECIALIX,	SPECIALIX_XIO,	"XIO/SIO host"),
 	DEVICE( SPECIALIX,	SPECIALIX_RIO,	"RIO host"),
+	DEVICE( RP,             RP8OCTA,        "RocketPort 8 Oct"),
+	DEVICE( RP,             RP8INTF,        "RocketPort 8 Intf"),
+	DEVICE( RP,             RP16INTF,       "RocketPort 16 Intf"),
+	DEVICE( RP,             RP32INTF,       "RocketPort 32 Intf"),
 	DEVICE( CYCLADES,	CYCLADES_Y,	"Cyclome-Y"),
 	DEVICE( SYMPHONY,	SYMPHONY_101,	"82C101"),
 	DEVICE( TEKRAM,		TEKRAM_DC290,	"DC-290"),
@@ -464,6 +471,7 @@
 	      case PCI_VENDOR_ID_MUTECH:	return "Mutech";
 	      case PCI_VENDOR_ID_ZEITNET:	return "ZeitNet";
 	      case PCI_VENDOR_ID_SPECIALIX:	return "Specialix";
+	      case PCI_VENDOR_ID_RP:		return "Comtrol";
 	      case PCI_VENDOR_ID_CYCLADES:	return "Cyclades";
 	      case PCI_VENDOR_ID_SYMPHONY:	return "Symphony";
 	      case PCI_VENDOR_ID_TEKRAM:	return "Tekram";
diff -u --recursive --new-file v1.3.67/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.3.67/linux/drivers/scsi/scsi.c	Tue Feb 20 14:37:24 1996
+++ linux/drivers/scsi/scsi.c	Tue Feb 20 17:52:58 1996
@@ -234,12 +234,14 @@
 {"MAXTOR","MXT-1240S","I1.2", BLIST_NOLUN},     /* Locks up when LUN>0 polled */
 {"MAXTOR","XT-4170S","B5A", BLIST_NOLUN},       /* Locks-up sometimes when LUN>0 polled. */
 {"MAXTOR","XT-8760S","B7B", BLIST_NOLUN},       /* guess what? */
+{"MEDIAVIS","RENO CD-ROMX2A","2.03",BLIST_NOLUN},/*Responds to all lun */
 {"NEC","CD-ROM DRIVE:841","1.0", BLIST_NOLUN},  /* Locks-up when LUN>0 polled. */
 {"RODIME","RO3000S","2.33", BLIST_NOLUN},       /* Locks up if polled for lun != 0 */
 {"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN},   /* causes failed REQUEST SENSE on lun 1 
 						 * for aha152x controller, which causes 
 						 * SCSI code to reset bus.*/
 {"SEAGATE", "ST296","921", BLIST_NOLUN},        /* Responds to all lun */
+{"SEAGATE","ST1581","6538",BLIST_NOLUN},	/* Responds to all lun */
 {"SONY","CD-ROM CDU-541","4.3d", BLIST_NOLUN},
 {"SONY","CD-ROM CDU-55S","1.0i", BLIST_NOLUN},
 {"SONY","CD-ROM CDU-561","1.7x", BLIST_NOLUN},
diff -u --recursive --new-file v1.3.67/linux/fs/exec.c linux/fs/exec.c
--- v1.3.67/linux/fs/exec.c	Tue Feb 20 14:37:26 1996
+++ linux/fs/exec.c	Wed Feb 21 08:33:22 1996
@@ -290,7 +290,7 @@
 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
 		unsigned long p, int from_kmem)
 {
-	char *tmp, *pag = NULL;
+	char *tmp, *tmp1, *pag = NULL;
 	int len, offset = 0;
 	unsigned long old_fs, new_fs;
 
@@ -303,14 +303,12 @@
 	while (argc-- > 0) {
 		if (from_kmem == 1)
 			set_fs(new_fs);
-		if (!(tmp = get_user(argv+argc)))
+		if (!(tmp1 = tmp = get_user(argv+argc)))
 			panic("VFS: argc is wrong");
 		if (from_kmem == 1)
 			set_fs(old_fs);
-		len=0;		/* remember zero-padding */
-		do {
-			len++;
-		} while (get_user(tmp++));
+		while (get_user(tmp++));
+		len = tmp - tmp1;
 		if (p < len) {	/* this shouldn't happen - 128kB */
 			set_fs(old_fs);
 			return 0;
@@ -329,7 +327,16 @@
 					set_fs(new_fs);
 
 			}
-			*(pag + offset) = get_user(tmp);
+			if (len == 0 || offset == 0)
+			  *(pag + offset) = get_user(tmp);
+			else {
+			  int bytes_to_copy = (len > offset) ? offset : len;
+			  tmp -= bytes_to_copy;
+			  p -= bytes_to_copy;
+			  offset -= bytes_to_copy;
+			  len -= bytes_to_copy;
+			  memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
+			}
 		}
 	}
 	if (from_kmem==2)
diff -u --recursive --new-file v1.3.67/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v1.3.67/linux/fs/fat/inode.c	Tue Feb 20 14:37:26 1996
+++ linux/fs/fat/inode.c	Thu Feb 22 14:31:54 1996
@@ -68,13 +68,14 @@
 
 static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
     gid_t *gid,int *umask,int *debug,int *fat,int *quiet,
-	int *blksize, char *dotsOK, char *sys_immutable)
+	int *blksize, char *dotsOK, char *sys_immutable, char *showexec)
 {
 	char *this_char,*value;
 
 	*check = 'n';
 	*conversion = 'b';
 	*dotsOK = 0;
+	*showexec = 0;
 	*uid = current->uid;
 	*gid = current->gid;
 	*umask = current->fs->umask;
@@ -105,6 +106,9 @@
 		else if (!strcmp(this_char,"nodots")) {
 		  *dotsOK = 0;
 		}
+		else if (!strcmp(this_char,"showexec")) {
+		  *showexec = 1;
+		}
 		else if (!strcmp(this_char,"dotsOK") && value) {
 			if (!strcmp(value,"yes")) *dotsOK = 1;
 			else if (!strcmp(value,"no")) *dotsOK = 0;
@@ -173,7 +177,7 @@
 	struct msdos_boot_sector *b;
 	int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
 	int debug,error,fat,quiet;
-	char check,conversion,dotsOK,sys_immutable;
+	char check,conversion,dotsOK,sys_immutable,showexec;
 	uid_t uid;
 	gid_t gid;
 	int umask;
@@ -187,7 +191,7 @@
 		}
 	}
 	if (!parse_options((char *) data,&check,&conversion,&uid,&gid,&umask,
-	    &debug,&fat,&quiet,&blksize,&dotsOK,&sys_immutable)
+	    &debug,&fat,&quiet,&blksize,&dotsOK,&sys_immutable,&showexec)
 		|| (blksize != 512 && blksize != 1024)) {
 		sb->s_dev = 0;
 		MOD_DEC_USE_COUNT;
@@ -299,6 +303,7 @@
 	MSDOS_SB(sb)->fs_umask = umask;
 	MSDOS_SB(sb)->quiet = quiet;
 	MSDOS_SB(sb)->dotsOK = dotsOK;
+	MSDOS_SB(sb)->showexec = showexec;
 	MSDOS_SB(sb)->sys_immutable = sys_immutable;
 	MSDOS_SB(sb)->vfat = 0;   /* vfat_read_super sets this */
 	MSDOS_SB(sb)->umsdos = 0; /* umsdos_read_super will set this */
@@ -433,7 +438,8 @@
 			}
 	} else { /* not a directory */
 		inode->i_mode = MSDOS_MKMODE(raw_entry->attr,
-		    ((IS_NOEXEC(inode) || !is_exec(raw_entry->ext))
+		    ((IS_NOEXEC(inode) || (MSDOS_SB(inode->i_sb)->showexec &&
+						!is_exec(raw_entry->ext)))
 		    	? S_IRUGO|S_IWUGO : S_IRWXUGO)
 		    & ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFREG;
 		inode->i_op = (sb->s_blocksize == 1024)
diff -u --recursive --new-file v1.3.67/linux/fs/inode.c linux/fs/inode.c
--- v1.3.67/linux/fs/inode.c	Wed Feb 14 14:37:16 1996
+++ linux/fs/inode.c	Thu Feb 22 14:18:42 1996
@@ -151,7 +151,7 @@
 {
 	struct wait_queue * wait;
 
-	invalidate_inode_pages(inode, 0);
+	truncate_inode_pages(inode, 0);
 	wait_on_inode(inode);
 	if (IS_WRITABLE(inode)) {
 		if (inode->i_sb && inode->i_sb->dq_op)
diff -u --recursive --new-file v1.3.67/linux/fs/ncpfs/Makefile linux/fs/ncpfs/Makefile
--- v1.3.67/linux/fs/ncpfs/Makefile	Tue Jan  2 16:46:28 1996
+++ linux/fs/ncpfs/Makefile	Thu Feb 22 15:20:19 1996
@@ -11,6 +11,10 @@
 O_OBJS   := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o
 M_OBJS   := $(O_TARGET)
 
+# If you want debugging output, please uncomment the following line
+
+# EXTRA_CFLAGS += -DDEBUG_NCP=1
+
 include $(TOPDIR)/Rules.make
 
 ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h
diff -u --recursive --new-file v1.3.67/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- v1.3.67/linux/fs/ncpfs/dir.c	Tue Jan 23 21:15:51 1996
+++ linux/fs/ncpfs/dir.c	Thu Feb 22 15:20:19 1996
@@ -96,7 +96,7 @@
 	NULL,			/* write - bad */
 	ncp_readdir,		/* readdir */
 	NULL,			/* select - default */
-	ncp_ioctl,		/* ioctl - default */
+	ncp_ioctl,		/* ioctl */
 	NULL,			/* mmap */
 	NULL,			/* no special open code */
 	NULL,			/* no special release code */
@@ -159,6 +159,11 @@
 		return -EBADF;
 	}
 
+	if (!ncp_conn_valid(NCP_SERVER(inode)))
+	{
+		return -EIO;
+	}
+
 	if (c_entry == NULL) 
 	{
 		i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE;
@@ -640,6 +645,11 @@
 		iput(dir);
 		return -ENOENT;
 	}
+	if (!ncp_conn_valid(NCP_SERVER(dir)))
+	{
+		iput(dir);
+		return -EIO;
+	}
 
         DDPRINTK("ncp_lookup: %s, len %d\n", __name, len);
 
@@ -772,6 +782,11 @@
 		iput(dir);
 		return -ENOENT;
 	}
+	if (!ncp_conn_valid(NCP_SERVER(dir)))
+	{
+		iput(dir);
+		return -EIO;
+	}
 
 	strncpy(_name, name, len);
 	_name[len] = '\0';
@@ -779,7 +794,8 @@
 
 	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)
 	{
@@ -828,6 +844,11 @@
 		iput(dir);
 		return -ENOENT;
 	}
+	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,
@@ -858,8 +879,14 @@
 		iput(dir);
 		return -ENOENT;
 	}
+	if (!ncp_conn_valid(NCP_SERVER(dir)))
+	{
+		iput(dir);
+		return -EIO;
+	}
         if (ncp_find_inode(dir, name) != NULL)
 	{
+		iput(dir);
                 error = -EBUSY;
         }
 	else
@@ -877,7 +904,7 @@
 		}
 		else
 		{
-			error = -EINVAL;
+			error = -EACCES;
 		}
         }
 	iput(dir);
@@ -896,8 +923,14 @@
 		iput(dir);
 		return -ENOENT;
 	}
+	if (!ncp_conn_valid(NCP_SERVER(dir)))
+	{
+		iput(dir);
+		return -EIO;
+	}
         if (ncp_find_inode(dir, name) != NULL)
 	{
+		iput(dir);
                 error = -EBUSY;
         }
 	else
@@ -914,7 +947,7 @@
 		}
 		else
 		{
-			error = -EINVAL;
+			error = -EACCES;
 		}
         }
 	iput(dir);
@@ -934,6 +967,12 @@
 		printk("ncp_rename: old inode is NULL or not a directory\n");
                 res = -ENOENT;
                 goto finished;
+	}
+
+	if (!ncp_conn_valid(NCP_SERVER(old_dir)))
+	{
+		res = -EIO;
+		goto finished;
 	}
 
 	if (!new_dir || !S_ISDIR(new_dir->i_mode))
diff -u --recursive --new-file v1.3.67/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
--- v1.3.67/linux/fs/ncpfs/file.c	Thu Jan  4 21:54:58 1996
+++ linux/fs/ncpfs/file.c	Thu Feb 22 15:20:19 1996
@@ -93,6 +93,10 @@
 		DPRINTK("ncp_file_read: inode = NULL\n");
 		return -EINVAL;
 	}
+	if (!ncp_conn_valid(NCP_SERVER(inode)))
+	{
+		return -EIO;
+	}
 
 	if (!S_ISREG(inode->i_mode))
 	{
@@ -171,6 +175,10 @@
 	{
 		DPRINTK("ncp_file_write: inode = NULL\n");
 		return -EINVAL;
+	}
+	if (!ncp_conn_valid(NCP_SERVER(inode)))
+	{
+		return -EIO;
 	}
 
 	if (!S_ISREG(inode->i_mode))
diff -u --recursive --new-file v1.3.67/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- v1.3.67/linux/fs/ncpfs/inode.c	Tue Jan 23 21:15:51 1996
+++ linux/fs/ncpfs/inode.c	Thu Feb 22 15:35:35 1996
@@ -6,6 +6,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/config.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -20,6 +21,9 @@
 #include <linux/locks.h>
 #include <linux/fcntl.h>
 #include <linux/malloc.h>
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
 #include "ncplib_kernel.h"
 
 extern int close_fp(struct file *filp);
@@ -182,6 +186,7 @@
         struct ncp_server *server;
 	struct file *ncp_filp;
 	struct file *wdog_filp;
+	struct file *msg_filp;
 	kdev_t dev = sb->s_dev;
 	int error;
 
@@ -197,6 +202,8 @@
 		printk("ncp warning: mount version %s than kernel\n",
 		       (data->version < NCP_MOUNT_VERSION) ?
                        "older" : "newer");
+		sb->s_dev = 0;
+		return NULL;
 	}
 
 	if (   (data->ncp_fd >= NR_OPEN)
@@ -217,6 +224,15 @@
 		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);
@@ -229,6 +245,7 @@
 
 	ncp_filp->f_count += 1;
 	wdog_filp->f_count += 1;
+	msg_filp->f_count += 1;
 
 	lock_super(sb);
 
@@ -242,10 +259,12 @@
 
 	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->buffer_size = 0;
+	server->conn_status = 0;
 
         server->m = *data;
 	server->m.file_mode = (server->m.file_mode &
@@ -253,6 +272,9 @@
 	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';
+
 	server->packet_size = NCP_PACKET_SIZE;
 	server->packet      = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
 
@@ -278,6 +300,15 @@
 		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);
@@ -324,6 +355,7 @@
  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;
 }
@@ -343,6 +375,7 @@
 
 	ncp_dont_catch_watchdog(server);
 	close_fp(server->wdog_filp);
+	close_fp(server->msg_filp);
 
         ncp_free_all_inodes(server);
 
@@ -357,6 +390,32 @@
         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)
+{
+	char command[ sizeof(server->m.mount_point)
+		     + sizeof(NCP_MSG_COMMAND) + 2];
+
+	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)
 {
@@ -386,6 +445,11 @@
 	int info_mask;
 	struct nw_modify_dos_info info;
 
+	if (!ncp_conn_valid(NCP_SERVER(inode)))
+	{
+		return -EIO;
+	}
+
 	if ((result = inode_change_ok(inode, attr)) < 0)
 		return result;
 
@@ -493,6 +557,7 @@
 }
 
 #ifdef MODULE
+int
 init_module( void)
 {
 	int status;
diff -u --recursive --new-file v1.3.67/linux/fs/ncpfs/mmap.c linux/fs/ncpfs/mmap.c
--- v1.3.67/linux/fs/ncpfs/mmap.c	Mon Jan  8 14:10:28 1996
+++ linux/fs/ncpfs/mmap.c	Thu Feb 22 15:20:19 1996
@@ -133,6 +133,11 @@
 {
         DPRINTK("ncp_mmap: called\n");
 
+	if (!ncp_conn_valid(NCP_SERVER(inode)))
+	{
+		return -EIO;
+	}
+
         /* only PAGE_COW or read-only supported now */
 	if (vma->vm_flags & VM_SHARED)	
 		return -EINVAL;
diff -u --recursive --new-file v1.3.67/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
--- v1.3.67/linux/fs/ncpfs/ncplib_kernel.c	Wed Feb  7 15:11:34 1996
+++ linux/fs/ncpfs/ncplib_kernel.c	Thu Feb 22 15:20:19 1996
@@ -411,12 +411,18 @@
 			       struct nw_file_info *target)
 {
 	int result;
+	__u16 search_attribs = 0x0006;
+
+	if ((create_attributes & aDIR) != 0)
+	{
+		search_attribs |= 0x8000;
+	}
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 1); /* subfunction */
 	ncp_add_byte(server, 0); /* dos name space */
 	ncp_add_byte(server, open_create_mode);
-	ncp_add_word(server, 0x8006);
+	ncp_add_word(server, search_attribs);
 	ncp_add_dword(server, RIM_ALL);
 	ncp_add_dword(server, create_attributes);
 	/* The desired acc rights seem to be the inherited rights mask
diff -u --recursive --new-file v1.3.67/linux/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c
--- v1.3.67/linux/fs/ncpfs/sock.c	Tue Jan  2 16:46:28 1996
+++ linux/fs/ncpfs/sock.c	Thu Feb 22 15:20:19 1996
@@ -93,13 +93,8 @@
 		    /* How to check connection number here? */
 		    )
 		{
-			/* Error, throw away the complete packet */
-			_recvfrom(sock, (void *)packet_buf, 2, 1, 0,
-				  &sender, &addr_len);
-
 			printk("ncpfs: got strange packet on watchdog "
 			       "socket\n");
-			
 		}
 		else
 		{
@@ -123,7 +118,6 @@
 	}
 }
 
-
 int
 ncp_catch_watchdog(struct ncp_server *server)
 {
@@ -146,7 +140,7 @@
 
         if (sock->type != SOCK_DGRAM)
 	{
-                printk("ncp_catch_watchdog: did not get SOCK_STREAM\n");
+                printk("ncp_catch_watchdog: did not get SOCK_DGRAM\n");
                 server->data_ready = NULL;
                 return -EINVAL;
         }
@@ -160,7 +154,7 @@
                 return -EINVAL;
         }
 
-        DDPRINTK("ncp_catch_watchdog.: sk->d_r = %x, server->d_r = %x\n",
+        DDPRINTK("ncp_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
                  (unsigned int)(sk->data_ready),
                  (unsigned int)(server->data_ready));
 
@@ -198,11 +192,11 @@
 
         if (sock->type != SOCK_DGRAM)
 	{
-                printk("ncp_dont_catch_watchdog: did not get SOCK_STREAM\n");
+                printk("ncp_dont_catch_watchdog: did not get SOCK_DGRAM\n");
                 return -EINVAL;
         }
 
-        sk   = (struct sock *)(sock->data);
+        sk = (struct sock *)(sock->data);
 
         if (sk == NULL)
 	{
@@ -234,8 +228,88 @@
         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 addr_len = sizeof(struct sockaddr_ipx);
+		int result;
+		unsigned short fs;
+
+		fs = get_fs();
+		set_fs(get_ds());
+
+		result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
+				   &sender, &addr_len);
+
+		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->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 = (struct sock *)(sock->data);
+
+        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->ipx_ncp_server = server;
+        return 0;
+}
+                
 #define NCP_SLACK_SPACE 1024
 
 #define _S(nr) (1<<((nr)-1))
@@ -474,13 +548,30 @@
 static int
 ncp_do_request(struct ncp_server *server, int size)
 {
+	int result;
+
 	if (server->lock == 0)
 	{
 		printk("ncpfs: Server not locked!\n");
 		return -EIO;
 	}
 
-	return do_ncp_rpc_call(server, size);
+	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)
+	{
+		/* There was a problem with I/O, so the connections is
+                 * no longer usable. */
+		ncp_invalidate_conn(server);
+	}
+	return result;
 }
 
 /* ncp_do_request assures that at least a complete reply header is
diff -u --recursive --new-file v1.3.67/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v1.3.67/linux/fs/nfs/file.c	Tue Feb 20 14:37:26 1996
+++ linux/fs/nfs/file.c	Thu Feb 22 14:29:35 1996
@@ -81,7 +81,7 @@
 			return;
 		NFS_OLDMTIME(inode) = fattr.mtime.seconds;
 	}
-	invalidate_inode_pages(inode, 0);
+	invalidate_inode_pages(inode);
 }
 
 
@@ -118,18 +118,15 @@
 		result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode), 
 			pos, rsize, buf, &fattr);
 		if (result < 0)
-			goto partial;
+			break;
 		refresh = 1;
-		count -= rsize;
-		pos += rsize;
-		buf += rsize;
+		count -= result;
+		pos += result;
+		buf += result;
 		if (result < rsize)
-			goto partial;
+			break;
 	} while (count);
-	nfs_refresh_inode(inode, &fattr);
-	return;
 
-partial:
 	memset(buf, 0, count);
 	if (refresh)
 		nfs_refresh_inode(inode, &fattr);
diff -u --recursive --new-file v1.3.67/linux/fs/proc/array.c linux/fs/proc/array.c
--- v1.3.67/linux/fs/proc/array.c	Fri Feb 16 11:34:09 1996
+++ linux/fs/proc/array.c	Wed Feb 21 12:55:21 1996
@@ -272,14 +272,34 @@
 static int get_meminfo(char * buffer)
 {
 	struct sysinfo i;
+	int len;
 
 	si_meminfo(&i);
 	si_swapinfo(&i);
-	return sprintf(buffer, "        total:    used:    free:  shared: buffers:  cached:\n"
+	len = sprintf(buffer, "        total:    used:    free:  shared: buffers:  cached:\n"
 		"Mem:  %8lu %8lu %8lu %8lu %8lu %8lu\n"
 		"Swap: %8lu %8lu %8lu\n",
 		i.totalram, i.totalram-i.freeram, i.freeram, i.sharedram, i.bufferram, page_cache_size*PAGE_SIZE,
 		i.totalswap, i.totalswap-i.freeswap, i.freeswap);
+	/*
+	 * Tagged format, for easy grepping and expansion. The above will go away
+	 * eventually, once the tools have been updated.
+	 */
+	return len + sprintf(buffer+len,
+		"MemTotal:  %8lu kB\n"
+		"MemFree:   %8lu kB\n"
+		"MemShared: %8lu kB\n"
+		"Buffers:   %8lu kB\n"
+		"Cached:    %8lu kB\n"
+		"SwapTotal: %8lu kB\n"
+		"SwapFree:  %8lu kB\n",
+		i.totalram >> 10,
+		i.freeram >> 10,
+		i.sharedram >> 10,
+		i.bufferram >> 10,
+		page_cache_size << (PAGE_SHIFT - 10),
+		i.totalswap >> 10,
+		i.freeswap >> 10);
 }
 
 static int get_version(char * buffer)
@@ -452,6 +472,164 @@
 # define KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->tss.usp)
 #endif
 
+/* Gcc optimizes away "strlen(x)" for constant x */
+#define ADDBUF(buffer, string) \
+do { memcpy(buffer, string, strlen(string)); \
+     buffer += strlen(string); } while (0)
+
+static inline char * task_name(struct task_struct *p, char * buf)
+{
+	int i;
+	char * name;
+
+	ADDBUF(buf, "Name:\t");
+	name = p->comm;
+	i = sizeof(p->comm);
+	do {
+		unsigned char c = *name;
+		name++;
+		i--;
+		*buf = c;
+		if (!c)
+			break;
+		if (c == '\\') {
+			buf[1] = c;
+			buf += 2;
+			continue;
+		}
+		if (c == '\n') {
+			buf[0] = '\\';
+			buf[1] = 'n';
+			buf += 2;
+			continue;
+		}
+		buf++;
+	} while (i);
+	*buf = '\n';
+	return buf+1;
+}
+
+static inline char * task_state(struct task_struct *p, char *buffer)
+{
+#define NR_STATES (sizeof(states)/sizeof(const char *))
+	unsigned int n = p->state;
+	static const char * states[] = {
+		"R (running)",
+		"S (sleeping)",
+		"D (disk sleep)",
+		"Z (zombie)",
+		"T (stopped)",
+		"W (paging)",
+		". Huh?"
+	};
+
+	if (n >= NR_STATES)
+		n = NR_STATES-1;
+
+	buffer += sprintf(buffer,
+		"State:\t%s\n"
+		"Pid:\t%d\n"
+		"PPid:\t%d\n"
+		"Uid:\t%d\t%d\t%d\t%d\n"
+		"Gid:\t%d\t%d\t%d\t%d\n",
+		states[n],
+		p->pid, p->p_pptr->pid,
+		p->uid, p->euid, p->suid, p->fsuid,
+		p->gid, p->egid, p->sgid, p->fsgid);
+	return buffer;
+}
+
+static inline char * task_mem(struct task_struct *p, char *buffer)
+{
+	struct mm_struct * mm = p->mm;
+
+	if (mm && mm != &init_mm) {
+		struct vm_area_struct * vma = mm->mmap;
+		unsigned long data = 0, stack = 0;
+		unsigned long exec = 0, lib = 0;
+
+		for (vma = mm->mmap; vma; vma = vma->vm_next) {
+			unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
+			if (!vma->vm_inode) {
+				data += len;
+				if (vma->vm_flags & VM_GROWSDOWN)
+					stack += len;
+				continue;
+			}
+			if (vma->vm_flags & VM_WRITE)
+				continue;
+			if (vma->vm_flags & VM_EXEC) {
+				exec += len;
+				if (vma->vm_flags & VM_EXECUTABLE)
+					continue;
+				lib += len;
+			}
+		}	
+		buffer += sprintf(buffer,
+			"VmSize:\t%8lu kB\n"
+			"VmLck:\t%8lu kB\n"
+			"VmRSS:\t%8lu kB\n"
+			"VmData:\t%8lu kB\n"
+			"VmStk:\t%8lu kB\n"
+			"VmExe:\t%8lu kB\n"
+			"VmLib:\t%8lu kB\n",
+			mm->total_vm << (PAGE_SHIFT-10),
+			mm->locked_vm << (PAGE_SHIFT-10),
+			mm->rss << (PAGE_SHIFT-10),
+			data - stack, stack,
+			exec - lib, lib);
+	}
+	return buffer;
+}
+
+static inline char * task_sig(struct task_struct *p, char *buffer)
+{
+	buffer += sprintf(buffer,
+		"SigPnd:\t%08lx\n"
+		"SigBlk:\t%08lx\n",
+		p->signal, p->blocked);
+	if (p->sig) {
+		struct sigaction * action = p->sig->action;
+		unsigned long sig_ign = 0, sig_caught = 0;
+		unsigned long bit = 1;
+		int i;
+
+		for (i = 0; i < 32; i++) {
+			switch((unsigned long) action->sa_handler) {
+				case 0:
+					break;
+				case 1:
+					sig_ign |= bit;
+					break;
+				default:
+					sig_caught |= bit;
+			}
+			bit <<= 1;
+			action++;
+		}
+		
+		buffer += sprintf(buffer,
+			"SigIgn:\t%08lx\n"
+			"SigCgt:\t%08lx\n",
+			sig_ign, sig_caught);
+	}
+	return buffer;
+}
+
+static int get_status(int pid, char * buffer)
+{
+	char * orig = buffer;
+	struct task_struct ** p = get_task(pid), *tsk;
+
+	if (!p || (tsk = *p) == NULL)
+		return 0;
+	buffer = task_name(tsk, buffer);
+	buffer = task_state(tsk, buffer);
+	buffer = task_mem(tsk, buffer);
+	buffer = task_sig(tsk, buffer);
+	return buffer - orig;
+}
+
 static int get_stat(int pid, char * buffer)
 {
 	struct task_struct ** p = get_task(pid), *tsk;
@@ -857,6 +1035,8 @@
 static int get_process_array(char * page, int pid, int type)
 {
 	switch (type) {
+		case PROC_PID_STATUS:
+			return get_status(pid, page);
 		case PROC_PID_ENVIRON:
 			return get_env(pid, page);
 		case PROC_PID_CMDLINE:
diff -u --recursive --new-file v1.3.67/linux/fs/proc/base.c linux/fs/proc/base.c
--- v1.3.67/linux/fs/proc/base.c	Tue Dec 26 04:45:39 1995
+++ linux/fs/proc/base.c	Wed Feb 21 11:26:09 1996
@@ -83,6 +83,12 @@
 void proc_base_init(void)
 {
 	proc_register(&proc_pid, &(struct proc_dir_entry) {
+		PROC_PID_STATUS, 6, "status",
+		S_IFREG | S_IRUGO, 1, 0, 0,
+		0, &proc_array_inode_operations,
+		NULL, proc_pid_fill_inode,
+	});
+	proc_register(&proc_pid, &(struct proc_dir_entry) {
 		PROC_PID_MEM, 3, "mem",
 		S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
 		0, &proc_mem_inode_operations,
diff -u --recursive --new-file v1.3.67/linux/fs/proc/inode.c linux/fs/proc/inode.c
--- v1.3.67/linux/fs/proc/inode.c	Tue Jan 23 21:15:51 1996
+++ linux/fs/proc/inode.c	Wed Feb 21 10:30:09 1996
@@ -222,6 +222,7 @@
 			inode->i_op = &proc_array_inode_operations;
 			return;
 		case PROC_PID_CMDLINE:
+		case PROC_PID_STATUS:
 		case PROC_PID_STAT:
 		case PROC_PID_STATM:
 			inode->i_mode = S_IFREG | S_IRUGO;
diff -u --recursive --new-file v1.3.67/linux/include/linux/fs.h linux/include/linux/fs.h
--- v1.3.67/linux/include/linux/fs.h	Tue Feb 20 14:37:28 1996
+++ linux/include/linux/fs.h	Thu Feb 22 14:53:58 1996
@@ -546,7 +546,7 @@
 
 extern int check_disk_change(kdev_t dev);
 extern void invalidate_inodes(kdev_t dev);
-extern void invalidate_inode_pages(struct inode *, unsigned long);
+extern void invalidate_inode_pages(struct inode *);
 extern void invalidate_buffers(kdev_t dev);
 extern int floppy_is_wp(int minor);
 extern void sync_inodes(kdev_t dev);
diff -u --recursive --new-file v1.3.67/linux/include/linux/interrupt.h linux/include/linux/interrupt.h
--- v1.3.67/linux/include/linux/interrupt.h	Fri Feb  9 17:53:08 1996
+++ linux/include/linux/interrupt.h	Thu Feb 22 15:51:42 1996
@@ -2,7 +2,7 @@
 #ifndef _LINUX_INTERRUPT_H
 #define _LINUX_INTERRUPT_H
 
-#include <linux/linkage.h>
+#include <linux/kernel.h>
 #include <asm/bitops.h>
 
 struct bh_struct {
@@ -49,10 +49,12 @@
 extern inline void start_bh_atomic(void)
 {
 	intr_count++;
+	barrier();
 }
 
 extern inline void end_bh_atomic(void)
 {
+	barrier();
 	intr_count--;
 }
 
diff -u --recursive --new-file v1.3.67/linux/include/linux/kernel.h linux/include/linux/kernel.h
--- v1.3.67/linux/include/linux/kernel.h	Wed Jan  4 21:16:05 1995
+++ linux/include/linux/kernel.h	Thu Feb 22 15:51:08 1996
@@ -10,6 +10,9 @@
 #include <stdarg.h>
 #include <linux/linkage.h>
 
+/* Optimization barrier */
+#define barrier() __asm__("": : :"memory")
+
 #define INT_MAX		((int)(~0U>>1))
 #define UINT_MAX	(~0U)
 #define LONG_MAX	((long)(~0UL>>1))
diff -u --recursive --new-file v1.3.67/linux/include/linux/mm.h linux/include/linux/mm.h
--- v1.3.67/linux/include/linux/mm.h	Fri Jan 26 01:37:07 1996
+++ linux/include/linux/mm.h	Thu Feb 22 15:52:41 1996
@@ -223,6 +223,7 @@
 /* filemap.c */
 extern unsigned long page_unuse(unsigned long);
 extern int shrink_mmap(int, unsigned long);
+extern void truncate_inode_pages(struct inode *, unsigned long);
 
 #define GFP_BUFFER	0x00
 #define GFP_ATOMIC	0x01
diff -u --recursive --new-file v1.3.67/linux/include/linux/msdos_fs_sb.h linux/include/linux/msdos_fs_sb.h
--- v1.3.67/linux/include/linux/msdos_fs_sb.h	Wed Feb  7 15:11:38 1996
+++ linux/include/linux/msdos_fs_sb.h	Thu Feb 22 14:31:54 1996
@@ -23,6 +23,7 @@
 	int prev_free; /* previously returned free cluster number */
 	int free_clusters; /* -1 if undefined */
 	char dotsOK;
+	char showexec; /* 1 = only set x bit for com/exe/bat */
 	char sys_immutable; /* system files are immutable */
 	int vfat; /* 0=no vfat long filename support, 1=vfat support */
 	int umsdos; /* 1 if mounted by umsdos, 0 if not */
diff -u --recursive --new-file v1.3.67/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h
--- v1.3.67/linux/include/linux/ncp_fs.h	Tue Jan 23 21:15:53 1996
+++ linux/include/linux/ncp_fs.h	Thu Feb 22 16:00:44 1996
@@ -54,6 +54,8 @@
 #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
@@ -145,6 +147,7 @@
 extern int init_ncp_fs(void);
 void ncp_invalidate_connection(struct ncp_server *server);
 int ncp_conn_is_valid(struct ncp_server *server);
+void ncp_trigger_message(struct ncp_server *server);
 
 /* linux/fs/ncpfs/sock.c */
 int ncp_request(struct ncp_server *server, int function);
@@ -152,6 +155,7 @@
 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);
 
diff -u --recursive --new-file v1.3.67/linux/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h
--- v1.3.67/linux/include/linux/ncp_fs_sb.h	Tue Jan  2 16:46:30 1996
+++ linux/include/linux/ncp_fs_sb.h	Thu Feb 22 15:36:28 1996
@@ -22,8 +22,8 @@
 				    it completely. */
 
 	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
@@ -35,7 +35,8 @@
 
 	u8         completion;	/* Status message from server */
 	u8         conn_status;	/* Bit 4 = 1 ==> Server going down, no
-				   requests allowed anymore */
+				   requests allowed anymore.
+				   Bit 0 = 1 ==> Server is down. */
 
 	int        buffer_size;	/* Negotiated bufsize */
 
@@ -55,6 +56,18 @@
         struct ncp_inode_info root;
 	char       root_path;	/* '\0' */
 };
+
+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)
+{
+	server->conn_status |= 0x01;
+}
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v1.3.67/linux/include/linux/ncp_mount.h linux/include/linux/ncp_mount.h
--- v1.3.67/linux/include/linux/ncp_mount.h	Tue Jan  2 16:46:30 1996
+++ linux/include/linux/ncp_mount.h	Thu Feb 22 15:20:20 1996
@@ -13,7 +13,7 @@
 #include <linux/ncp.h>
 #include <linux/ncp_fs_i.h>
 
-#define NCP_MOUNT_VERSION 1
+#define NCP_MOUNT_VERSION 2
 
 #define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN)
 #define NCP_PASSWORD_LEN 20
@@ -30,10 +30,10 @@
         uid_t mounted_uid;      /* Who may umount() this filesystem? */
 
 	struct sockaddr_ipx serv_addr;
-	unsigned char server_name[49];
+	unsigned char server_name[NCP_BINDERY_NAME_LEN];
 
-	unsigned char username[NCP_USERNAME_LEN+1];
-	unsigned char password[NCP_PASSWORD_LEN+1];
+	unsigned char mount_point[PATH_MAX+1];
+	unsigned char mounted_vol[NCP_VOLNAME_LEN+1];
 
 	unsigned int time_out;	/* How long should I wait after
 				   sending a NCP request? */
diff -u --recursive --new-file v1.3.67/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v1.3.67/linux/include/linux/netdevice.h	Sat Feb 17 16:02:54 1996
+++ linux/include/linux/netdevice.h	Thu Feb 22 15:52:47 1996
@@ -34,13 +34,17 @@
 #define MAX_ADDR_LEN	7
 #ifndef CONFIG_AX25
 #ifndef CONFIG_TR
+#ifndef CONFIG_NET_IPIP
 #define MAX_HEADER	32		/* We really need about 18 worst case .. so 32 is aligned */
 #else
+#define MAX_HEADER	48		/* We need to allow for having tunnel headers */
+#endif  /* IPIP */
+#else
 #define MAX_HEADER	48		/* Token Ring header needs 40 bytes ... 48 is aligned */ 
-#endif
+#endif /* TR */
 #else
 #define MAX_HEADER	96		/* AX.25 + NetROM */
-#endif
+#endif /* AX25 */
 
 #define IS_MYADDR	1		/* address is (one of) our own	*/
 #define IS_LOOPBACK	2		/* address is for LOOPBACK	*/
diff -u --recursive --new-file v1.3.67/linux/include/linux/pci.h linux/include/linux/pci.h
--- v1.3.67/linux/include/linux/pci.h	Sat Feb 17 16:02:54 1996
+++ linux/include/linux/pci.h	Thu Feb 22 15:36:02 1996
@@ -327,6 +327,8 @@
 #define PCI_DEVICE_ID_OPTI_82C822	0xc822
 
 #define PCI_VENDOR_ID_SGS		0x104a
+#define PCI_DEVICE_ID_SGS_2000		0x0008
+#define PCI_DEVICE_ID_SGS_1764		0x0009
 
 #define PCI_VENDOR_ID_BUSLOGIC		0x104B
 #define PCI_DEVICE_ID_BUSLOGIC_946C_2	0x0140
@@ -418,6 +420,7 @@
 #define PCI_DEVICE_ID_TEKRAM2_690c	0x690c
 
 #define PCI_VENDOR_ID_AMCC		0x10e8
+#define PCI_DEVICE_ID_AMCC_MYRINET	0x8043
 
 #define PCI_VENDOR_ID_INTERG		0x10ea
 #define PCI_DEVICE_ID_INTERG_1680	0x1680
@@ -464,6 +467,12 @@
 #define PCI_VENDOR_ID_SPECIALIX		0x11cb
 #define PCI_DEVICE_ID_SPECIALIX_XIO	0x4000
 #define PCI_DEVICE_ID_SPECIALIX_RIO	0x8000
+
+#define PCI_VENDOR_ID_RP               0x11fe
+#define PCI_DEVICE_ID_RP8OCTA          0x0001
+#define PCI_DEVICE_ID_RP8INTF          0x0002
+#define PCI_DEVICE_ID_RP16INTF         0x0003
+#define PCI_DEVICE_ID_RP32INTF         0x0004
 
 #define PCI_VENDOR_ID_CYCLADES		0x120e
 #define PCI_DEVICE_ID_CYCLADES_Y	0x0100
diff -u --recursive --new-file v1.3.67/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v1.3.67/linux/include/linux/proc_fs.h	Fri Feb 16 11:34:11 1996
+++ linux/include/linux/proc_fs.h	Thu Feb 22 15:52:47 1996
@@ -46,6 +46,7 @@
 
 enum pid_directory_inos {
 	PROC_PID_INO = 2,
+	PROC_PID_STATUS,
 	PROC_PID_MEM,
 	PROC_PID_CWD,
 	PROC_PID_ROOT,
diff -u --recursive --new-file v1.3.67/linux/include/linux/scc.h linux/include/linux/scc.h
--- v1.3.67/linux/include/linux/scc.h	Thu Dec 21 08:53:33 1995
+++ linux/include/linux/scc.h	Wed Feb 21 08:33:22 1996
@@ -185,7 +185,7 @@
 };
 
 
-struct scc_modem{
+struct scc_modem {
 	long speed;		/* Line speed, bps */
 	char clocksrc;		/* 0 = DPLL, 1 = external, 2 = divider */
 	char nrz;		/* NRZ instead of NRZI */	
diff -u --recursive --new-file v1.3.67/linux/include/linux/sched.h linux/include/linux/sched.h
--- v1.3.67/linux/include/linux/sched.h	Wed Feb 14 14:37:18 1996
+++ linux/include/linux/sched.h	Thu Feb 22 15:51:08 1996
@@ -104,8 +104,6 @@
 
 #ifdef __KERNEL__
 
-#define barrier() __asm__("": : :"memory")
-
 extern void sched_init(void);
 extern void show_state(void);
 extern void trap_init(void);
diff -u --recursive --new-file v1.3.67/linux/include/net/ax25.h linux/include/net/ax25.h
--- v1.3.67/linux/include/net/ax25.h	Wed Feb  7 15:11:38 1996
+++ linux/include/net/ax25.h	Thu Feb 22 15:52:47 1996
@@ -203,6 +203,7 @@
 extern int  ax25_cs_get_info(char *, char **, off_t, int, int);
 extern int  ax25_rt_autobind(ax25_cb *, ax25_address *);
 extern void ax25_rt_build_path(ax25_cb *, ax25_address *);
+extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *);
 extern void ax25_rt_device_down(struct device *);
 extern int  ax25_rt_ioctl(unsigned int, void *);
 extern void ax25_ip_mode_set(ax25_address *, struct device *, char);
diff -u --recursive --new-file v1.3.67/linux/include/net/sock.h linux/include/net/sock.h
--- v1.3.67/linux/include/net/sock.h	Tue Feb 20 14:37:28 1996
+++ linux/include/net/sock.h	Thu Feb 22 15:52:47 1996
@@ -197,6 +197,12 @@
 	ipx_address		ipx_dest_addr;
 	ipx_interface		*ipx_intrfc;
 	unsigned short		ipx_port;
+
+/* To handle asynchronous messages from the NetWare server, we have to
+ * know the connection this socket belongs to. Sorry to blow up this
+ * structure even more. */
+	struct ncp_server       *ipx_ncp_server;
+
 #ifdef CONFIG_IPX_INTERN
 	unsigned char           ipx_node[IPX_NODE_LEN];
 #endif
diff -u --recursive --new-file v1.3.67/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.67/linux/kernel/ksyms.c	Tue Feb 20 14:37:29 1996
+++ linux/kernel/ksyms.c	Thu Feb 22 14:28:59 1996
@@ -180,6 +180,7 @@
 	X(check_disk_change),
 	X(invalidate_buffers),
 	X(invalidate_inodes),
+	X(invalidate_inode_pages),
 	X(fsync_dev),
 	X(permission),
 	X(inode_setattr),
@@ -192,6 +193,7 @@
 	X(__bforget),
 	X(ll_rw_block),
 	X(__wait_on_buffer),
+	X(__wait_on_page),
 	X(mark_buffer_uptodate),
 	X(unlock_buffer),
 	X(dcache_lookup),
diff -u --recursive --new-file v1.3.67/linux/mm/filemap.c linux/mm/filemap.c
--- v1.3.67/linux/mm/filemap.c	Tue Feb 20 14:37:29 1996
+++ linux/mm/filemap.c	Thu Feb 22 15:18:31 1996
@@ -41,7 +41,40 @@
  * Simple routines for both non-shared and shared mappings.
  */
 
-void invalidate_inode_pages(struct inode * inode, unsigned long start)
+/*
+ * Invalidate the pages of an inode, removing all pages that aren't
+ * locked down (those are sure to be up-to-date anyway, so we shouldn't
+ * invalidate them).
+ */
+void invalidate_inode_pages(struct inode * inode)
+{
+	struct page ** p;
+	struct page * page;
+
+	p = &inode->i_pages;
+	while ((page = *p) != NULL) {
+		if (page->locked) {
+			p = &page->next;
+			continue;
+		}
+		inode->i_nrpages--;
+		if ((*p = page->next) != NULL)
+			(*p)->prev = page->prev;
+		page->dirty = 0;
+		page->next = NULL;
+		page->prev = NULL;
+		remove_page_from_hash_queue(page);
+		page->inode = NULL;
+		free_page(page_address(page));
+		continue;
+	}
+}
+
+/*
+ * Truncate the page cache at a set offset, removing the pages
+ * that are beyond that offset (and zeroing out partial pages).
+ */
+void truncate_inode_pages(struct inode * inode, unsigned long start)
 {
 	struct page ** p;
 	struct page * page;
@@ -261,14 +294,12 @@
  * inode->i_op->readpage() function for the actual low-level
  * stuff.
  */
-#define READAHEAD_PAGES 3
-#define MAX_IO_PAGES 4
+#define MAX_READAHEAD (PAGE_SIZE*4)
 int generic_file_read(struct inode * inode, struct file * filp, char * buf, int count)
 {
-	int read = 0, newpage = 0;
+	int read = 0;
 	unsigned long pos;
 	unsigned long page_cache = 0;
-	int pre_read = 0;
 	
 	if (count <= 0)
 		return 0;
@@ -277,8 +308,6 @@
 	do {
 		struct page *page;
 		unsigned long offset, addr, nr;
-		int i;
-		off_t p;
 
 		if (pos >= inode->i_size)
 			break;
@@ -326,48 +355,29 @@
 		add_page_to_hash_queue(inode, page);
 
 		inode->i_op->readpage(inode, page);
-		/* We only set "newpage" when we encounter a
-                   completely uncached page.  This way, we do no
-                   readahead if we are still just reading data out of
-                   the cache (even if the cached page is not yet
-                   uptodate --- it may be currently being read as a
-                   result of previous readahead).  -- sct */
-		newpage = 1;
 
 found_page:
 		addr = page_address(page);
 		if (nr > count)
 			nr = count;
-		/* We have two readahead cases.  First, do data
-                   pre-read if the current read request is for more
-                   than one page, so we can merge the adjacent
-                   requests. */
-		if (newpage && nr < count) {
-			if (pre_read > 0)
-				pre_read -= PAGE_SIZE;
-			else {
-				pre_read = (MAX_IO_PAGES-1) * PAGE_SIZE;
-				if (pre_read > (count - nr))
-					pre_read = count - nr;
-				for (i=0, p=pos; i<pre_read; i+=PAGE_SIZE) {
-					p += PAGE_SIZE;
-					page_cache = try_to_read_ahead(inode, p, page_cache);
-				}
-			}
-		}
-		else
-		/* Second, do readahead at the end of the read, if we
-                   are still waiting on the current IO to complete, if
-                   readahead is flagged for the file, and if we have
-                   finished with the current block. */
-		if (newpage && nr == count && filp->f_reada
-		    && !((pos + nr) & ~PAGE_MASK)) {
-			for (i=0, p=pos; i<READAHEAD_PAGES; i++) {
-				p += PAGE_SIZE;
-				page_cache = try_to_read_ahead(inode, p, page_cache);
+
+		/*
+		 * We may want to do read-ahead.. Do this only
+		 * if we're waiting for the current page to be
+		 * filled in, and if
+		 *  - we're going to read more than this page
+		 *  - if "f_reada" is set
+		 */
+		if (page->locked) {
+			if (nr < count || filp->f_reada) {
+				unsigned long ahead = 0;
+				do {
+					ahead += PAGE_SIZE;
+					page_cache = try_to_read_ahead(inode, pos + ahead, page_cache);
+				} while (ahead < MAX_READAHEAD);
 			}
+			__wait_on_page(page);
 		}
-		wait_on_page(page);
 		if (nr > inode->i_size - pos)
 			nr = inode->i_size - pos;
 		memcpy_tofs(buf, (void *) (addr + offset), nr);
diff -u --recursive --new-file v1.3.67/linux/mm/memory.c linux/mm/memory.c
--- v1.3.67/linux/mm/memory.c	Sun Jan 14 16:30:16 1996
+++ linux/mm/memory.c	Thu Feb 22 14:18:19 1996
@@ -48,6 +48,7 @@
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <asm/pgtable.h>
+#include <asm/string.h>
 
 unsigned long high_memory = 0;
 
@@ -177,13 +178,12 @@
 int new_page_tables(struct task_struct * tsk)
 {
 	pgd_t * page_dir, * new_pg;
-	int i;
 
 	if (!(new_pg = pgd_alloc()))
 		return -ENOMEM;
 	page_dir = pgd_offset(&init_mm, 0);
-	for (i = USER_PTRS_PER_PGD ; i < PTRS_PER_PGD ; i++)
-		new_pg[i] = page_dir[i];
+	memcpy(new_pg + USER_PTRS_PER_PGD, page_dir + USER_PTRS_PER_PGD,
+	       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof (pgd_t));
 	invalidate_mm(tsk->mm);
 	SET_PAGE_DIR(tsk, new_pg);
 	tsk->mm->pgd = new_pg;
@@ -801,7 +801,7 @@
 {
 	struct vm_area_struct * mpnt;
 
-	invalidate_inode_pages(inode, offset);
+	truncate_inode_pages(inode, offset);
 	if (!inode->i_mmap)
 		return;
 	mpnt = inode->i_mmap;
diff -u --recursive --new-file v1.3.67/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- v1.3.67/linux/net/ax25/af_ax25.c	Sat Feb 17 16:02:57 1996
+++ linux/net/ax25/af_ax25.c	Wed Feb 21 08:33:25 1996
@@ -571,8 +571,8 @@
 
 	ax25->state    = AX25_STATE_0;
 
-	memset(&ax25->dest_addr,   '\0', sizeof(ax25_address));
-	memset(&ax25->source_addr, '\0', sizeof(ax25_address));
+	memset(&ax25->dest_addr,   '\0', AX25_ADDR_LEN);
+	memset(&ax25->source_addr, '\0', AX25_ADDR_LEN);
 
 	return ax25;
 }
@@ -583,18 +583,17 @@
  *
  *	dl1bke 951121
  */
- 
 int ax25_dev_is_dama_slave(struct device *dev)
 {
-	ax25_cb * ax25;
+	ax25_cb *ax25;
 	int count = 0;
 	
-	for (ax25=ax25_list; ax25 ; ax25 = ax25->next)
-		if ( (ax25->device == dev) && ax25->dama_slave )
-		{
+	for (ax25 = ax25_list; ax25 != NULL; ax25 = ax25->next) {
+		if (ax25->device == dev && ax25->dama_slave) {
 			count++;
 			break;
 		}
+	}
 		
 	return count;
 }
@@ -652,15 +651,15 @@
 
 	ax25_fillin_cb(ax25, dev);
 
-	memcpy(&ax25->source_addr, src,  sizeof(ax25_address));
-	memcpy(&ax25->dest_addr,   dest, sizeof(ax25_address));
+	ax25->source_addr = *src;
+	ax25->dest_addr   = *dest;
 
 	if (digi != NULL) {
 		if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
 			kfree_s(ax25, sizeof(ax25));
 			return 0;
 		}
-		memcpy(ax25->digipeat, digi, sizeof(ax25_digi));
+		*ax25->digipeat = *digi;
 	} else {
 		ax25_rt_build_path(ax25, dest);
 	}
@@ -668,7 +667,7 @@
 	if (ax25_dev_is_dama_slave(ax25->device))	/* dl1bke 960116 */
 		dama_establish_data_link(ax25);
 	else
-	ax25_establish_data_link(ax25);
+		ax25_establish_data_link(ax25);
 		
 	ax25_insert_socket(ax25);
 
@@ -995,8 +994,7 @@
 	sk->type   = osk->type;
 	sk->socket = osk->socket;
 
-	switch(osk->type)
-	{
+	switch (osk->type) {
 		case SOCK_DGRAM:
 			break;
 		case SOCK_SEQPACKET:
@@ -1051,7 +1049,7 @@
 
 	ax25->window  = osk->ax25->window;
 
-	memcpy(&ax25->source_addr, &osk->ax25->source_addr, sizeof(ax25_address));
+	ax25->source_addr = osk->ax25->source_addr;
 	
 	if (osk->ax25->digipeat != NULL) {
 		if ((ax25->digipeat = (ax25_digi *)kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
@@ -1061,7 +1059,7 @@
 		}
 		
 		/* dl1bke 960119: we have to copy the old digipeater list! */
-		memcpy(ax25->digipeat, osk->ax25->digipeat, sizeof(ax25_digi));
+		*ax25->digipeat = *osk->ax25->digipeat;
 	}
 
 	sk->ax25 = ax25;
@@ -1105,7 +1103,7 @@
 				if (sk->ax25->dama_slave)
 					ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
 				else
-				ax25_send_control(sk->ax25, DM, POLLON, C_RESPONSE);
+					ax25_send_control(sk->ax25, DM, POLLON, C_RESPONSE);
 				sk->ax25->state = AX25_STATE_0;
 				sk->state       = TCP_CLOSE;
 				sk->state_change(sk);
@@ -1118,7 +1116,7 @@
 				ax25_clear_queues(sk->ax25);
 				sk->ax25->n2count = 0;
 				if (!sk->ax25->dama_slave)
-				ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
+					ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
 				sk->ax25->t3timer = 0;
 				sk->ax25->t1timer = sk->ax25->t1 = ax25_calculate_t1(sk->ax25);
 				sk->ax25->state   = AX25_STATE_2;
@@ -1170,9 +1168,9 @@
 		return -EPERM;
 		
 	if (call == NULL)
-		memcpy(&sk->ax25->source_addr, &addr->fsa_ax25.sax25_call, sizeof(ax25_address));
+		sk->ax25->source_addr = addr->fsa_ax25.sax25_call;
 	else
-		memcpy(&sk->ax25->source_addr, call, sizeof(ax25_address));
+		sk->ax25->source_addr = *call;
 
 	if (sk->debug)
 		printk("AX25: source address set to %s\n", ax2asc(&sk->ax25->source_addr));
@@ -1258,14 +1256,12 @@
 
 		while (ct < addr->sax25_ndigis) {
 			sk->ax25->digipeat->repeated[ct] = 0;
-			memcpy(&sk->ax25->digipeat->calls[ct], &fsa->fsa_digipeater[ct], sizeof(ax25_address));
+			sk->ax25->digipeat->calls[ct] = fsa->fsa_digipeater[ct];
 			ct++;
 		}
 
 		sk->ax25->digipeat->lastrepeat = 0;
-	}
-	else
-	{ /* dl1bke 960117 */
+	} else { /* dl1bke 960117 */
 		if (sk->debug)
 			printk("building digipeater path\n");
 		ax25_rt_build_path(sk->ax25, &addr->sax25_call);
@@ -1289,7 +1285,7 @@
 	if (sk->type == SOCK_SEQPACKET && ax25_find_cb(&sk->ax25->source_addr, &addr->sax25_call, sk->ax25->device) != NULL)
 		return -EBUSY;				/* Already such a connection */
 
-	memcpy(&sk->ax25->dest_addr, &addr->sax25_call, sizeof(ax25_address));
+	sk->ax25->dest_addr = addr->sax25_call;
 	
 	/* First the easy one */
 	if (sk->type != SOCK_SEQPACKET) {
@@ -1305,7 +1301,7 @@
 	if (ax25_dev_is_dama_slave(sk->ax25->device))
 		dama_establish_data_link(sk->ax25);
 	else
-	ax25_establish_data_link(sk->ax25);
+		ax25_establish_data_link(sk->ax25);
 		
 	sk->ax25->state     = AX25_STATE_1;
 	ax25_set_timer(sk->ax25);		/* Start going SABM SABM until a UA or a give up and DM */
@@ -1415,7 +1411,7 @@
 	}
 		
 	sax->fsa_ax25.sax25_family = AF_AX25;
-	memcpy(&sax->fsa_ax25.sax25_call, addr, sizeof(ax25_address));
+	sax->fsa_ax25.sax25_call   = *addr;
 	sax->fsa_ax25.sax25_ndigis = 0;
 	*uaddr_len = sizeof(struct sockaddr_ax25);
 
@@ -1423,9 +1419,9 @@
 	if (sk->ax25->digipeat != NULL) {
 		ndigi = sk->ax25->digipeat->ndigi;
 		sax->fsa_ax25.sax25_ndigis = ndigi;
-		*uaddr_len += sizeof(ax25_address) * ndigi;
+		*uaddr_len += AX25_ADDR_LEN * ndigi;
 		for (i = 0; i < ndigi; i++)
-			memcpy(&sax->fsa_digipeater[i], &sk->ax25->digipeat->calls[i], sizeof(ax25_address));
+			sax->fsa_digipeater[i] = sk->ax25->digipeat->calls[i];
 	}
 
 	return 0;
@@ -1450,9 +1446,7 @@
 	skb->h.raw = skb->data;
 	
 #ifdef CONFIG_FIREWALL
-	
-	if(call_in_firewall(PF_AX25, skb, skb->h.raw)!=FW_ACCEPT)
-	{
+	if (call_in_firewall(PF_AX25, skb, skb->h.raw) != FW_ACCEPT) {
 		kfree_skb(skb, FREE_READ);
 		return 0;
 	}
@@ -1476,8 +1470,7 @@
 	 *	Ours perhaps ?
 	 */
 	if (dp.lastrepeat + 1 < dp.ndigi) {		/* Not yet digipeated completely */
-		if (ax25cmp(&dp.calls[dp.lastrepeat + 1], dev_addr) == 0) 
-		{
+		if (ax25cmp(&dp.calls[dp.lastrepeat + 1], dev_addr) == 0) {
 			struct device *dev_out = dev;
 
 			/* We are the digipeater. Mark ourselves as repeated
@@ -1485,10 +1478,8 @@
 			dp.lastrepeat++;
 			dp.repeated[(int)dp.lastrepeat] = 1;
 
-			if (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) 
-			{
-				while (dp.lastrepeat + 1 < dp.ndigi) 
-				{
+			if (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) {
+				while (dp.lastrepeat + 1 < dp.ndigi) {
 					struct device *dev_scan;
 					if ((dev_scan = ax25rtr_get_dev(&dp.calls[dp.lastrepeat + 1])) == NULL)
 						break;
@@ -1496,23 +1487,20 @@
 					dp.repeated[(int)dp.lastrepeat] = 1;
 					dev_out = dev_scan;
 				}
-				if (dev != dev_out && (ax25_dev_get_value(dev_out, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) == 0)
-				{
+				if (dev != dev_out && (ax25_dev_get_value(dev_out, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) == 0) {
 					kfree_skb(skb, FREE_READ);
 					return 0;
 				}
 			}
 
-			if (dev == dev_out && (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_INBAND) == 0)
-			{
+			if (dev == dev_out && (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_INBAND) == 0) {
 				kfree_skb(skb, FREE_READ);
 				return 0;	/* Hey, Alan: look what you're doing below! You forgot this return! */
 			}
 
 			build_ax25_addr(skb->data, &src, &dest, &dp, type, MODULUS);
 #ifdef CONFIG_FIREWALL
-			if(call_fw_firewall(PF_AX25, skb,skb->data)!=FW_ACCEPT)
-			{
+			if (call_fw_firewall(PF_AX25, skb, skb->data) != FW_ACCEPT) {
 				kfree_skb(skb, FREE_READ);
 				return 0;
 			}
@@ -1680,8 +1668,8 @@
 #endif
 	}
 
-	memcpy(&ax25->source_addr, &dest, sizeof(ax25_address));
-	memcpy(&ax25->dest_addr,   &src,  sizeof(ax25_address));
+	ax25->source_addr = dest;
+	ax25->dest_addr   = src;
 
 	/*
 	 *	Sort out any digipeated paths.
@@ -1820,27 +1808,25 @@
 
 			while (ct < usax->sax25_ndigis) {
 				dtmp.repeated[ct] = 0;
-				memcpy(&dtmp.calls[ct], &fsa->fsa_digipeater[ct], sizeof(ax25_address));
+				dtmp.calls[ct]    = fsa->fsa_digipeater[ct];
 				ct++;
 			}
 
 			dtmp.lastrepeat = 0;
 		}
 
-		memcpy(&sax, usax, sizeof(sax));
-		if (sk->type == SOCK_SEQPACKET && memcmp(&sk->ax25->dest_addr, &sax.sax25_call, sizeof(ax25_address)) != 0)
+		sax = *usax;
+		if (sk->type == SOCK_SEQPACKET && ax25cmp(&sk->ax25->dest_addr, &sax.sax25_call) != 0)
 			return -EISCONN;
 		if (usax->sax25_ndigis == 0)
-		{
 			dp = NULL;
-		}
 		else
 			dp = &dtmp;
 	} else {
 		if (sk->state != TCP_ESTABLISHED)
 			return -ENOTCONN;
 		sax.sax25_family = AF_AX25;
-		memcpy(&sax.sax25_call, &sk->ax25->dest_addr, sizeof(ax25_address));
+		sax.sax25_call   = sk->ax25->dest_addr;
 		dp = sk->ax25->digipeat;
 	}
 	
@@ -1971,7 +1957,7 @@
 		   application know the digi calls further down (because it
 		   did NOT ask to know them).  This could get political... **/
 		sax->sax25_ndigis = digi.ndigi;
-		memcpy(&sax->sax25_call, &dest, sizeof(ax25_address));
+		sax->sax25_call   = dest;
 
 		*addr_len = sizeof(struct sockaddr_ax25);
 
@@ -1980,7 +1966,7 @@
 			struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)sax;
 
 			while (ct < digi.ndigi) {
-				memcpy(&fsa->fsa_digipeater[ct], &digi.calls[ct], sizeof(ax25_address));
+				fsa->fsa_digipeater[ct] = digi.calls[ct];
 				ct++;
 			}
 
@@ -2274,8 +2260,7 @@
 	int was_locked;
 	
 #ifdef CONFIG_FIREWALL
-	if(call_out_firewall(PF_AX25, skb, skb->data)!=FW_ACCEPT)
-	{
+	if (call_out_firewall(PF_AX25, skb, skb->data) != FW_ACCEPT) {
 		kfree_skb(skb, FREE_WRITE);
 		return;
 	}
@@ -2284,12 +2269,11 @@
 	skb->protocol = htons (ETH_P_AX25);
 
 #ifdef CONFIG_BPQETHER
-	if(dev->type == ARPHRD_ETHER)
-	{
+	if(dev->type == ARPHRD_ETHER) {
 		static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
 		int size;
-		if(skb_headroom(skb) < AX25_BPQ_HEADER_LEN)
-		{
+
+		if(skb_headroom(skb) < AX25_BPQ_HEADER_LEN) {
 			printk("ax25_queue_xmit: not enough space to add BPQ Ether header\n");
 			skb->free = 1;
 			kfree_skb(skb, FREE_WRITE);
@@ -2398,11 +2382,9 @@
   	if (arp_find(bp + 1, dest, dev, dev->pa_addr, skb))
   		return 1;
 
-	if (bp[16] == AX25_P_IP) 
-	{
+	if (bp[16] == AX25_P_IP) {
 		mode = ax25_ip_mode_get((ax25_address *)(bp + 1), dev);
-		if (mode == 'V' || mode == 'v' || (mode == ' ' && ax25_dev_get_value(dev, AX25_VALUES_IPDEFMODE) == 'V')) 
-		{
+		if (mode == 'V' || mode == 'v' || (mode == ' ' && ax25_dev_get_value(dev, AX25_VALUES_IPDEFMODE) == 'V')) {
 /*			skb_device_unlock(skb); *//* Don't unlock - it might vanish.. TCP will respond correctly to this lock holding */
 			skb_pull(skb, AX25_HEADER_LEN - 1);	/* Keep PID */
 #ifdef HUNTING_FOR_ENCAP_BUG
@@ -2410,14 +2392,14 @@
 		/* 		  twice... We'll try a work-around here and hope for   */
 		/* 		  the best.                                            */
 
-			if ( !(ax25cmp((ax25_address *) (bp + 8), (ax25_address *) (skb->data + 8)) ||
-			       ax25cmp((ax25_address *) (bp + 1), (ax25_address *) (skb->data + 1)) ) )
-			{
+			if (!(ax25cmp((ax25_address *)(bp + 8), (ax25_address *)(skb->data + 8)) ||
+			      ax25cmp((ax25_address *)(bp + 1), (ax25_address *)(skb->data + 1)))) {
 				printk("ax25_rebuild_header(): encap bug...\n");
 				skb_pull(skb, AX25_HEADER_LEN);
-			} else
+			} else {
 				if (!*skb->data)
 					printk("ax25_rebuild_header(): probably encap bug...\n");
+			}
 #endif
 			ax25_send_frame(skb, (ax25_address *)(bp + 8), (ax25_address *)(bp + 1), NULL, dev);
 			return 1;
@@ -2431,6 +2413,8 @@
   	bp[14] &= ~LAPB_C;
   	bp[14] |= LAPB_E;
   	bp[14] |= SSSID_SPARE;
+
+	ax25_dg_build_path(skb, (ax25_address *)(bp + 1), dev);
 
   	return 0;
 }	
diff -u --recursive --new-file v1.3.67/linux/net/ax25/ax25_in.c linux/net/ax25/ax25_in.c
--- v1.3.67/linux/net/ax25/ax25_in.c	Wed Feb  7 15:11:41 1996
+++ linux/net/ax25/ax25_in.c	Wed Feb 21 08:33:25 1996
@@ -27,7 +27,7 @@
  *	AX.25 030	Jonathan(G4KLX)	Added AX.25 fragment reception.
  *					Upgraded state machine for SABME.
  *					Added arbitrary protocol id support.
- *			Joerg(DL1BKE)	Added DAMA support
+ *	AX.25 031	Joerg(DL1BKE)	Added DAMA support
  */
 
 #include <linux/config.h>
@@ -268,14 +268,12 @@
 
 		case DISC:
 			ax25_send_control(ax25, UA, pf, C_RESPONSE);
-			if (ax25->dama_slave)
-			{
+			if (ax25->dama_slave) {
 				ax25->state = AX25_STATE_0;
 				ax25->dama_slave = 0;
 				ax25_dama_off(ax25);
 
-				if (ax25->sk != NULL) 
-				{
+				if (ax25->sk != NULL) {
 					ax25->sk->state = TCP_CLOSE;
 					ax25->sk->err   = 0;
 					if (!ax25->sk->dead)
@@ -321,12 +319,11 @@
 		case REJ:
 		case RNR:
 		case RR:
-			if (pf)
-			{
+			if (pf) {
 				if (ax25->dama_slave)
 					ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 				else
-				ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
+					ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
 			}
 			break;
 				
@@ -465,8 +462,7 @@
 				ax25_check_iframes_acked(ax25, nr);
 			}
 			if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-				if (pf)
-				{
+				if (pf)	{
 					if (ax25->dama_slave)	/* dl1bke 960114 */
 						dama_enquiry_response(ax25);
 					else
@@ -477,8 +473,7 @@
 			if (ns == ax25->vr) {
 				queued = ax25_rx_iframe(ax25, skb);
 				if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-					if (pf)
-					{
+					if (pf) {
 						if (ax25->dama_slave)	/* dl1bke 960114 */
 							dama_enquiry_response(ax25);
 						else
@@ -492,7 +487,7 @@
 					if (ax25->dama_slave)	/* dl1bke 960114 */
 						dama_enquiry_response(ax25);
 					else
-					ax25_enquiry_response(ax25);
+						ax25_enquiry_response(ax25);
 				} else {
 					if (!(ax25->condition & ACK_PENDING_CONDITION)) {
 						ax25->t2timer = ax25->t2;
@@ -501,8 +496,7 @@
 				}
 			} else {
 				if (ax25->condition & REJECT_CONDITION) {
-					if (pf) 
-					{
+					if (pf) {
 						if (ax25->dama_slave)	/* dl1bke 960114 */
 							dama_enquiry_response(ax25);
 						else
@@ -513,7 +507,7 @@
 					if (ax25->dama_slave)		/* dl1bke 960114 */
 						dama_enquiry_response(ax25);
 					else
-					ax25_send_control(ax25, REJ, pf, C_RESPONSE);
+						ax25_send_control(ax25, REJ, pf, C_RESPONSE);
 					ax25->condition &= ~ACK_PENDING_CONDITION;
 				}
 			}
@@ -716,8 +710,7 @@
 			}
 			ax25_frames_acked(ax25, nr);
 			if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-				if (pf)
-				{	/* dl1bke 960114 */
+				if (pf) {	/* dl1bke 960114 */
 					if (ax25->dama_slave)
 						ax25_enquiry_response(ax25);
 					else
@@ -728,8 +721,7 @@
 			if (ns == ax25->vr) {
 				queued = ax25_rx_iframe(ax25, skb);
 				if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-					if (pf) 
-					{	/* dl1bke 960114 */
+					if (pf) {	/* dl1bke 960114 */
 						if (ax25->dama_slave)
 							dama_enquiry_response(ax25);
 						else
@@ -743,7 +735,7 @@
 					if (ax25->dama_slave) 	/* dl1bke 960114 */
 						dama_enquiry_response(ax25);
 					else
-					ax25_enquiry_response(ax25);
+						ax25_enquiry_response(ax25);
 				} else {
 					if (!(ax25->condition & ACK_PENDING_CONDITION)) {
 						ax25->t2timer = ax25->t2;
@@ -752,8 +744,7 @@
 				}
 			} else {
 				if (ax25->condition & REJECT_CONDITION) {
-					if (pf) 
-					{ 	/* dl1bke 960114 */
+					if (pf) { 	/* dl1bke 960114 */
 						if (ax25->dama_slave)
 							dama_enquiry_response(ax25);
 						else
@@ -764,7 +755,7 @@
 					if (ax25->dama_slave)		/* dl1bke 960114 */
 						dama_enquiry_response(ax25);
 					else
-					ax25_send_control(ax25, REJ, pf, C_RESPONSE);
+						ax25_send_control(ax25, REJ, pf, C_RESPONSE);
 					ax25->condition &= ~ACK_PENDING_CONDITION;
 				}
 			}
diff -u --recursive --new-file v1.3.67/linux/net/ax25/ax25_out.c linux/net/ax25/ax25_out.c
--- v1.3.67/linux/net/ax25/ax25_out.c	Wed Feb  7 15:11:41 1996
+++ linux/net/ax25/ax25_out.c	Wed Feb 21 08:33:25 1996
@@ -24,7 +24,7 @@
  *			Jonathan(G4KLX)	Only poll when window is full.
  *	AX.25 030	Jonathan(G4KLX)	Added fragmentation to ax25_output.
  *					Added support for extended AX.25.
- *			Joerg(DL1BKE)	Added DAMA support
+ *	AX.25 031	Joerg(DL1BKE)	Added DAMA support
  */
 
 #include <linux/config.h>
@@ -109,8 +109,7 @@
 		skb_queue_tail(&ax25->write_queue, skb);	  /* Throw it on the queue */
 	}
 
-	if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4)
-	{
+	if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
 		if (!ax25->dama_slave)		/* bke 960114: we aren't allowed to transmit */
 			ax25_kick(ax25);	/* in DAMA mode unless we received a Poll */
 	}
@@ -318,34 +317,34 @@
 	}
 }
 
-/* dl1bke 960114: shouldn't ax25/dama_check_need_response reside as  */
-/*                static inline void ...() in ax25.h, should it? ;-) */
-
+/*
+ *	dl1bke 960114: shouldn't ax25/dama_check_need_response reside as
+ *                static inline void ...() in ax25.h, should it? ;-)
+ */
 void ax25_check_need_response(ax25_cb *ax25, int type, int pf)
 {
 	if (!ax25->dama_slave && type == C_COMMAND && pf)
 		ax25_enquiry_response(ax25);
 }
 
-/* dl1bke 960114: transmit I frames on DAMA poll */
-
-void dama_enquiry_response(ax25_cb * ax25)
+/*
+ *	dl1bke 960114: transmit I frames on DAMA poll
+ */
+void dama_enquiry_response(ax25_cb *ax25)
 {
-	ax25_cb * ax25o = NULL;
+	ax25_cb *ax25o;
 	
-	if (!(ax25->condition & PEER_RX_BUSY_CONDITION) )
-	{
+	if (!(ax25->condition & PEER_RX_BUSY_CONDITION)) {
 		ax25_requeue_frames(ax25);
 		ax25_kick(ax25);
 	}
-	if (ax25->state == AX25_STATE_1 ||
-	    ax25->state == AX25_STATE_2 ||
-	    skb_peek(&ax25->ack_queue) != NULL) 
-	{
-		ax25_t1_timeout(ax25);
 
-	} else
+	if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2 ||
+	    skb_peek(&ax25->ack_queue) != NULL) {
+		ax25_t1_timeout(ax25);
+	} else {
 		ax25->n2count = 0;
+	}
 	
 	ax25->t3timer = ax25->t3;
 	
@@ -367,31 +366,29 @@
 	/* transmissions of the other channels as well... This version    */	
 	/* gives better performance on FLEXNET nodes. (Why, Gunter?)	  */
 
-	for (ax25o=ax25_list; ax25o; ax25o=ax25o->next)
-	{
+	for (ax25o = ax25_list; ax25o != NULL; ax25o = ax25o->next) {
 		if (ax25o->device != ax25->device)
 			continue;
-			
-		if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2)
-		{
+
+		if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2) {
 			ax25_t1_timeout(ax25o);
 			continue;
 		}
-			
-		if ( !ax25o->dama_slave)
+
+		if (!ax25o->dama_slave)
 			continue;
 			
 		if ( !(ax25o->condition & PEER_RX_BUSY_CONDITION) && 
 		     (ax25o->state == AX25_STATE_3 || 
-		     (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0)) )
-		{
+		     (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0))) {
 			ax25_requeue_frames(ax25o);
 			ax25_kick(ax25o);
 		}
 		
-		if (ax25o->state == AX25_STATE_1 ||
-		    ax25o->state == AX25_STATE_2 ||
-		    skb_peek(&ax25o->ack_queue) != NULL) ax25_t1_timeout(ax25o);
+		if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2 ||
+		    skb_peek(&ax25o->ack_queue) != NULL) {
+			ax25_t1_timeout(ax25o);
+		}
 
 		ax25o->t3timer = ax25o->t3;
 	}
diff -u --recursive --new-file v1.3.67/linux/net/ax25/ax25_route.c linux/net/ax25/ax25_route.c
--- v1.3.67/linux/net/ax25/ax25_route.c	Wed Feb  7 15:11:41 1996
+++ linux/net/ax25/ax25_route.c	Wed Feb 21 08:33:25 1996
@@ -30,7 +30,7 @@
  *	AX.25 031	Jonathan(G4KLX)	Added concept of default route.
  *			Joerg(DL1BKE)	ax25_rt_build_path() find digipeater list and device by 
  *					destination call. Needed for IP routing via digipeater
- *
+ *			Jonathan(G4KLX)	Added routing for IP datagram packets.
  */
  
 #include <linux/config.h>
@@ -101,21 +101,14 @@
 	}
 
 	if (count > AX25_ROUTE_MAX) {
-		oldest->callsign = *src;
-		oldest->dev      = dev;
-		if (oldest->digipeat != NULL) {
+		if (oldest->digipeat != NULL)
 			kfree_s(oldest->digipeat, sizeof(ax25_digi));
-			oldest->digipeat = NULL;
-		}
-		oldest->stamp    = xtime;
-		oldest->n        = 1;
-		oldest->ip_mode  = ' ';
-		return;
+		ax25_rt = oldest;
+	} else {
+		if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
+			return;		/* No space */
 	}
 
-	if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
-		return;		/* No space */
-
 	ax25_rt->callsign = *src;
 	ax25_rt->dev      = dev;
 	ax25_rt->digipeat = NULL;
@@ -128,16 +121,18 @@
 			kfree_s(ax25_rt, sizeof(struct ax25_route));
 			return;
 		}
-		memcpy(ax25_rt->digipeat, digi, sizeof(ax25_digi));
+		*ax25_rt->digipeat = *digi;
 	}
 
-	save_flags(flags);
-	cli();
+	if (ax25_rt != oldest) {
+		save_flags(flags);
+		cli();
 
-	ax25_rt->next = ax25_route;
-	ax25_route    = ax25_rt;
+		ax25_rt->next = ax25_route;
+		ax25_route    = ax25_rt;
 
-	restore_flags(flags);
+		restore_flags(flags);
+	}
 }
 
 void ax25_rt_device_down(struct device *dev)
@@ -402,12 +397,12 @@
 		call = (ax25_address *)ax25->device->dev_addr;
 	}
 
-	memcpy(&ax25->source_addr, call, sizeof(ax25_address));
+	ax25->source_addr = *call;
 
 	if (ax25_rt->digipeat != NULL) {
 		if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
 			return -ENOMEM;
-		memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
+		*ax25->digipeat = *ax25_rt->digipeat;
 	}
 
 	if (ax25->sk != NULL)
@@ -424,8 +419,7 @@
 	struct ax25_route *ax25_rt;
 
 	for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-		if ( ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->digipeat != NULL ) {
-		
+		if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->digipeat != NULL) {
 			if (ax25_rt->dev == NULL)
 				continue;
 			
@@ -433,12 +427,48 @@
 				return;
 
 			ax25->device = ax25_rt->dev;
-			memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
+			*ax25->digipeat = *ax25_rt->digipeat;
+
 			return;
 		}
 	}
+
 	ax25->digipeat = NULL;
 }
+
+void ax25_dg_build_path(struct sk_buff *skb, ax25_address *addr, struct device *dev)
+{
+	struct ax25_route *ax25_rt;
+	ax25_address src, dest;
+	unsigned char *bp;
+	int len;
+
+	for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
+		if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev == dev) {
+			if (ax25_rt->digipeat == NULL)
+				return;
+
+			len = ax25_rt->digipeat->ndigi * AX25_ADDR_LEN;
+			
+			if (skb_headroom(skb) < len) {
+				printk("ax25_dg_build_path: not enough headroom for in skb\n");
+				return;
+			}
+
+			memcpy(&dest, skb->data + 1, AX25_ADDR_LEN);
+			memcpy(&src,  skb->data + 8, AX25_ADDR_LEN);
+
+			bp = skb_push(skb, len);
+
+			*bp++ = 0x00;		/* KISS Data */
+
+			build_ax25_addr(bp, &src, &dest, ax25_rt->digipeat, C_COMMAND, MODULUS);
+
+			return;
+		}
+	}
+}
+
 /*
  *	Register the mode of an incoming IP frame. It is assumed that an entry
  *	already exists in the routing table.
@@ -563,7 +593,6 @@
 	struct device *dev;
 	struct ax25_dev *ax25_dev;
 	int err;
-	int count;
 
 	switch (cmd) {
 		case SIOCAX25SETPARMS:
diff -u --recursive --new-file v1.3.67/linux/net/ax25/ax25_subr.c linux/net/ax25/ax25_subr.c
--- v1.3.67/linux/net/ax25/ax25_subr.c	Sat Feb 17 16:02:57 1996
+++ linux/net/ax25/ax25_subr.c	Wed Feb 21 08:33:25 1996
@@ -25,7 +25,7 @@
  *					Added fragmentation support.
  *			Darryl(G7LED)	Added function ax25_requeue_frames() to split
  *					it up from ax25_frames_acked().
- *			Joerg(DL1BKE)	DAMA needs KISS Fullduplex ON/OFF.
+ *	AX.25 031	Joerg(DL1BKE)	DAMA needs KISS Fullduplex ON/OFF.
  *					Thus we have ax25_kiss_cmd() now... ;-)
  *			Dave Brown(N2RJT)
  *					Killed a silly bug in the DAMA code.
@@ -360,8 +360,7 @@
 	digi->lastrepeat = -1;
 	digi->ndigi      = 0;
 	
-	while (!(buf[-1] & LAPB_E))
-	{
+	while (!(buf[-1] & LAPB_E)) {
 		if (d >= AX25_MAX_DIGIS)  return NULL;	/* Max of 6 digis */
 		if (len < 7) return NULL;	/* Short packet */
 
@@ -473,7 +472,16 @@
 	out->lastrepeat = 0;
 }
 
-void ax25_kiss_cmd(ax25_cb * ax25, unsigned char cmd, unsigned char param)
+/*
+ *	:::FIXME:::
+ *	This is ****NOT**** the right approach. Not all drivers do kiss. We
+ *	need a driver level request to switch duplex mode, that does either
+ *	SCC changing, PI config or KISS as required.
+ *
+ *	Not to mention this request isnt currently reliable.
+ */
+ 
+void ax25_kiss_cmd(ax25_cb *ax25, unsigned char cmd, unsigned char param)
 {
 	struct sk_buff *skb;
 	unsigned char *p;
@@ -487,8 +495,7 @@
 	skb->free = 1;
 	skb->arp = 1;
 	
-	if (ax25->sk != NULL)
-	{
+	if (ax25->sk != NULL) {
 		skb->sk = ax25->sk;
 		ax25->sk->wmem_alloc += skb->truesize;
 	}
@@ -507,10 +514,9 @@
 {
 	int count = ax25_dev_is_dama_slave(ax25->device);
 
-	if (count == 0)
-	{
-		if (ax25->sk && ax25->sk->debug)
-			printk("DAMA on\n");
+	if (count == 0) {
+		if (ax25->sk != NULL && ax25->sk->debug)
+			printk("ax25_dama_on: DAMA on\n");
 		ax25_kiss_cmd(ax25, 5, 1);
 	}
 }
@@ -519,11 +525,9 @@
 {
 	int count = ax25_dev_is_dama_slave(ax25->device);
 	
-	
-	if (count == 0)
-	{
-		if (ax25->sk && ax25->sk->debug)
-			printk("DAMA off\n");
+	if (count == 0) {
+		if (ax25->sk != NULL && ax25->sk->debug)
+			printk("ax25_dama_off: DAMA off\n");
 		ax25_kiss_cmd(ax25, 5, 0);
 	}
 }
diff -u --recursive --new-file v1.3.67/linux/net/ax25/ax25_timer.c linux/net/ax25/ax25_timer.c
--- v1.3.67/linux/net/ax25/ax25_timer.c	Wed Feb  7 15:11:41 1996
+++ linux/net/ax25/ax25_timer.c	Wed Feb 21 08:33:25 1996
@@ -17,6 +17,7 @@
  *	AX.25 028b	Jonathan(G4KLX)	Extracted AX25 control block from the
  *					sock structure.
  *	AX.25 029	Alan(GW4PTS)	Switched to KA9Q constant names.
+ *	AX.25 031	Joerg(DL1BKE)	Added DAMA support
  */
 
 #include <linux/config.h>
@@ -112,7 +113,7 @@
 				if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & OWN_RX_BUSY_CONDITION)) {
 					ax25->condition &= ~OWN_RX_BUSY_CONDITION;
 					if (!ax25->dama_slave) /* dl1bke */
-					ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
+						ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
 					ax25->condition &= ~ACK_PENDING_CONDITION;
 					break;
 				}
@@ -133,19 +134,15 @@
 			if (ax25->condition & ACK_PENDING_CONDITION) {
 				ax25->condition &= ~ACK_PENDING_CONDITION;
 				if (!ax25->dama_slave)			/* dl1bke 960114 */
-				ax25_timeout_response(ax25);
+					ax25_timeout_response(ax25);
 			}
 		}
 	}
 
-	if (ax25->t3timer > 0 && --ax25->t3timer == 0) 
-	{
-	
+	if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
 		/* dl1bke 960114: T3 expires and we are in DAMA mode:  */
 		/*                send a DISC and abort the connection */
-		 
-		if (ax25->dama_slave)
-		{
+		if (ax25->dama_slave) {
 #ifdef CONFIG_NETROM
 			nr_link_failed(&ax25->dest_addr, ax25->device);
 #endif
@@ -153,8 +150,7 @@
 			ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 				
 			ax25->state = AX25_STATE_0;
-			if (ax25->sk != NULL)
-			{
+			if (ax25->sk != NULL) {
 				if (ax25->sk->debug)
 					printk("T3 Timeout\n");
 				ax25->sk->state = TCP_CLOSE;
@@ -179,14 +175,13 @@
 	/* 		  nevertheless we have to re-enqueue the timer struct...   */
 	
 	if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
-	
 		ax25_reset_timer(ax25);
 		return;
 	}
 
-	if (!ax25_dev_is_dama_slave(ax25->device))
-	{
-		if (ax25->dama_slave) ax25->dama_slave = 0;
+	if (!ax25_dev_is_dama_slave(ax25->device)) {
+		if (ax25->dama_slave)
+			ax25->dama_slave = 0;
 		ax25_t1_timeout(ax25);
 	}
 }
@@ -200,8 +195,6 @@
  *                Thus we'll have to do parts of our T1 handling in
  *                ax25_enquiry_response().
  */
-
-
 void ax25_t1_timeout(ax25_cb * ax25)
 {	
 	switch (ax25->state) {
@@ -255,14 +248,14 @@
 			} else {
 				ax25->n2count++;
 				if (!ax25_dev_is_dama_slave(ax25->device))	/* dl1bke */
-				ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
+					ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 			}
 			break;
 
 		case AX25_STATE_3: 
 			ax25->n2count = 1;
 			if (!ax25->dama_slave)			/* dl1bke 960114 */
-			ax25_transmit_enquiry(ax25);
+				ax25_transmit_enquiry(ax25);
 			ax25->state   = AX25_STATE_4;
 			break;
 
@@ -286,7 +279,7 @@
 			} else {
 				ax25->n2count++;
 				if (!ax25->dama_slave)		/* dl1bke 960114 */
-				ax25_transmit_enquiry(ax25);
+					ax25_transmit_enquiry(ax25);
 			}
 			break;
 	}
diff -u --recursive --new-file v1.3.67/linux/net/core/dev.c linux/net/core/dev.c
--- v1.3.67/linux/net/core/dev.c	Wed Feb 14 14:37:19 1996
+++ linux/net/core/dev.c	Wed Feb 21 08:33:25 1996
@@ -43,6 +43,8 @@
  *					on a Sparc.
  *		Bjorn Ekwall	:	Added KERNELD hack.
  *		Alan Cox	:	Cleaned up the backlog initialise.
+ *		Craig Metz	:	SIOCGIFCONF fix if space for under
+ *					1 device.
  *
  */
 
@@ -214,8 +216,15 @@
 
 extern __inline__ void dev_load(const char *name)
 {
-	if(!dev_get(name))
-		request_module(name);
+        char *sptr;
+ 
+        if(!dev_get(name)) {
+#ifdef CONFIG_NET_ALIAS
+                for (sptr=name ; *sptr ; sptr++) if(*sptr==':') break;
+                if (!(*sptr && *(sptr+1)))
+#endif
+                        request_module(name);
+        }
 }
 
 #endif
@@ -788,17 +797,18 @@
 	{
         	if(!(dev->flags & IFF_UP))	/* Downed devices don't count */
 	        	continue;
-		memset(&ifr, 0, sizeof(struct ifreq));
-		strcpy(ifr.ifr_name, dev->name);
-		(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
-		(*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
-
 		/*
 		 *	Have we run out of space here ?
 		 */
 	
 		if (len < sizeof(struct ifreq)) 
 			break;
+
+		memset(&ifr, 0, sizeof(struct ifreq));
+		strcpy(ifr.ifr_name, dev->name);
+		(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
+		(*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
+
 
 		/*
 		 *	Write this block to the caller's space. 
diff -u --recursive --new-file v1.3.67/linux/net/core/net_alias.c linux/net/core/net_alias.c
--- v1.3.67/linux/net/core/net_alias.c	Thu Jan  4 21:54:59 1996
+++ linux/net/core/net_alias.c	Wed Feb 21 08:33:26 1996
@@ -15,9 +15,12 @@
  *	-	net_alias_type objs registration/unreg., module-ables.
  *	-	/proc/net/aliases & /proc/net/alias_types entries
  * Fixes:
- *	JJC	:	several net_alias_type func. renamed.
- *	JJC	:	net_alias_type object methods now pass *this.
- *	JJC	:	xxx_rcv device selection based on <src,dst> addrs
+ *			JJC	:	several net_alias_type func. renamed.
+ *			JJC	:	net_alias_type object methods now pass 
+ *					*this.
+ *			JJC	:	xxx_rcv device selection based on <src,dst> 
+ *					addrs
+ *		Andreas Schultz	:	Kerneld support.
  *
  * FIXME:
  *	- User calls sleep/wake_up locking.
@@ -30,6 +33,7 @@
  *	
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
@@ -47,6 +51,10 @@
 
 #include <linux/net_alias.h>
 
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
+
 /*
  * Only allow the following flags to pass from main device to aliases
  */
@@ -346,13 +354,23 @@
    */
   
   nat = nat_getbytype(family);
-  if (!nat)
-  {
-    printk("net_alias_dev_create(%s:%d): unregistered family==%d\n",
-	   main_dev->name, slot, family);
-    /* *err = -EAFNOSUPPORT; */
-    *err = -EINVAL;
-    return NULL;
+  if (!nat) {
+#ifdef CONFIG_KERNELD
+    char modname[20];
+    sprintf (modname,"netalias-%d", family);
+    request_module(modname);
+
+    nat = nat_getbytype(family);
+    if (!nat) {
+#endif
+      printk("net_alias_dev_create(%s:%d): unregistered family==%d\n",
+             main_dev->name, slot, family);
+      /* *err = -EAFNOSUPPORT; */
+      *err = -EINVAL;
+      return NULL;
+#ifdef CONFIG_KERNELD
+    }
+#endif
   }
   
   /*
diff -u --recursive --new-file v1.3.67/linux/net/core/sock.c linux/net/core/sock.c
--- v1.3.67/linux/net/core/sock.c	Tue Feb 20 14:37:29 1996
+++ linux/net/core/sock.c	Thu Feb 22 15:48:41 1996
@@ -558,17 +558,15 @@
 	 */
 
 	/* See if we have any packets built up. */
+	start_bh_atomic();
 	while ((skb = __skb_dequeue(&sk->back_log)) != NULL) 
 	{
-		barrier();
-		sk->users = 1;
 		if (sk->prot->rcv) 
 			sk->prot->rcv(skb, skb->dev, (struct options*)skb->proto_priv,
 				 skb->saddr, skb->len, skb->daddr, 1,
 				/* Only used for/by raw sockets. */
 				(struct inet_protocol *)sk->pair); 
-		sk->users = 0;
-		barrier();
 	}
+	end_bh_atomic();
 #endif  
 }
diff -u --recursive --new-file v1.3.67/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v1.3.67/linux/net/ipv4/af_inet.c	Tue Feb 20 14:37:30 1996
+++ linux/net/ipv4/af_inet.c	Thu Feb 22 16:48:36 1996
@@ -322,36 +322,24 @@
 		kfree_skb(skb, FREE_WRITE);
   	}
   	
-  	/* 
-  	 *	In case it's sleeping somewhere. 
-  	 */
-  	 
-  	if (!sk->dead) 
-  		sk->write_space(sk);
-
   	/*
-  	 *	Don't discard received data until the user side kills its
-  	 *	half of the socket.
+  	 *	Clean up the read buffer.
   	 */
 
-	if (sk->dead) 
+	while((skb=skb_dequeue(&sk->receive_queue))!=NULL) 
 	{
-  		while((skb=skb_dequeue(&sk->receive_queue))!=NULL) 
-  		{
 		/*
 		 * This will take care of closing sockets that were
 		 * listening and didn't accept everything.
 		 */
-			if (skb->sk != NULL && skb->sk != sk) 
-			{
-				IS_SKB(skb);
-				skb->sk->dead = 1;
-				skb->sk->prot->close(skb->sk, 0);
-			}
+		if (skb->sk != NULL && skb->sk != sk) 
+		{
 			IS_SKB(skb);
-			kfree_skb(skb, FREE_READ);
+			skb->sk->prot->close(skb->sk, 0);
 		}
-	}	
+		IS_SKB(skb);
+		kfree_skb(skb, FREE_READ);
+	}
 
 	/*
 	 *	Now we need to clean up the send head. 
@@ -396,7 +384,6 @@
 	 
 	if (sk->pair) 
 	{
-		sk->pair->dead = 1;
 		sk->pair->prot->close(sk->pair, 0);
 		sk->pair = NULL;
   	}
@@ -407,7 +394,7 @@
 	 * everything is gone.
 	 */
 
-	if (sk->dead && sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
+	if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
 	{
 		if(sk->opt)
 			kfree(sk->opt);
@@ -423,6 +410,7 @@
 	{
 		/* this should never happen. */
 		/* actually it can if an ack has just been sent. */
+		printk("Socket destroy delayed\n");
 		sk->destroy = 1;
 		sk->ack_backlog = 0;
 		release_sock(sk);
@@ -1028,7 +1016,6 @@
 	{
 	  	struct sock *sk=(struct sock *)newsock->data;
 	  	newsock->data=NULL;
-	  	sk->dead = 1;
 	  	destroy_sock(sk);
 	}
   
@@ -1078,7 +1065,6 @@
 	if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) 
 	{
 		err = sock_error(sk2);
-		sk2->dead=1;
 		destroy_sock(sk2);
 		newsock->data = NULL;
 		return err;
diff -u --recursive --new-file v1.3.67/linux/net/ipv4/igmp.c linux/net/ipv4/igmp.c
--- v1.3.67/linux/net/ipv4/igmp.c	Fri Feb  9 17:53:10 1996
+++ linux/net/ipv4/igmp.c	Wed Feb 21 08:33:26 1996
@@ -53,6 +53,9 @@
  *					message (960131).
  *		Christian Daudt :	removed del_timer from 
  *					igmp_timer_expire function (960205).
+ *             Christian Daudt :       igmp_heard_report now only calls
+ *                                     igmp_timer_expire if tm->running is
+ *                                     true (960216).
  */
 
 
@@ -288,7 +291,7 @@
 	if ((address & IGMP_LOCAL_GROUP_MASK) != IGMP_LOCAL_GROUP) {
 	  /* Timers are only set for non-local groups */
 	  for(im=dev->ip_mc_list;im!=NULL;im=im->next) {
-	    if(im->multiaddr==address) {
+	    if(im->multiaddr==address && im->tm_running) {
 	      igmp_stop_timer(im);
 	    }
 	  }
diff -u --recursive --new-file v1.3.67/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v1.3.67/linux/net/ipv4/route.c	Sat Feb 17 16:02:58 1996
+++ linux/net/ipv4/route.c	Wed Feb 21 08:33:26 1996
@@ -62,6 +62,7 @@
 #include <linux/in.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <linux/if_arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
@@ -557,9 +558,10 @@
 	{
 		/*
 		 *	Don't try to add a gateway we can't reach.. 
+		 *	Tunnel devices are exempt from this rule.
 		 */
 		 
-		if (dev != get_gw_dev(gw))
+		if ((dev != get_gw_dev(gw)) && dev->type!=ARPHRD_TUNNEL)
 			return;
 			
 		flags |= RTF_GATEWAY;
diff -u --recursive --new-file v1.3.67/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v1.3.67/linux/net/ipv4/tcp.c	Tue Feb 20 14:37:30 1996
+++ linux/net/ipv4/tcp.c	Thu Feb 22 16:03:05 1996
@@ -480,7 +480,6 @@
 
 	while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) 
 	{
-		skb->sk->dead=1;
 		tcp_close(skb->sk, 0);
 		kfree_skb(skb, FREE_READ);
 	}
@@ -1728,7 +1727,7 @@
 
 /*
  *	Shutdown the sending side of a connection. Much like close except
- *	that we don't receive shut down or set sk->dead=1.
+ *	that we don't receive shut down or set sk->dead.
  */
 
 void tcp_shutdown(struct sock *sk, int how)
@@ -1817,6 +1816,7 @@
 		tcp_set_state(sk, TCP_CLOSE);
 		tcp_close_pending(sk);
 		release_sock(sk);
+		sk->dead = 1;
 		return;
 	}
 	
@@ -1873,9 +1873,9 @@
 	 * This will destroy it. The timers will take care of actually
 	 * free'ing up the memory.
 	 */
-	sk->dead = 1;
 	tcp_cache_zap();	/* Kill the cache again. */
 	release_sock(sk);
+	sk->dead = 1;
 }
 
 
diff -u --recursive --new-file v1.3.67/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v1.3.67/linux/net/ipv4/tcp_output.c	Sat Feb 17 16:02:58 1996
+++ linux/net/ipv4/tcp_output.c	Thu Feb 22 16:02:31 1996
@@ -670,9 +670,7 @@
 	if (buff == NULL) 
 	{
 		sk->err = ENOMEM;
-		newsk->dead = 1;
-		newsk->state = TCP_CLOSE;
-		/* And this will destroy it */
+		destroy_sock(newsk);
 		kfree_skb(skb, FREE_READ);
 		tcp_statistics.TcpAttemptFails++;
 		return;
@@ -697,8 +695,7 @@
 		sk->err = tmp;
 		buff->free = 1;
 		kfree_skb(buff,FREE_WRITE);
-		newsk->dead = 1;
-		newsk->state = TCP_CLOSE;
+		destroy_sock(newsk);
 		skb->sk = sk;
 		kfree_skb(skb, FREE_READ);
 		tcp_statistics.TcpAttemptFails++;
diff -u --recursive --new-file v1.3.67/linux/net/ipv4/timer.c linux/net/ipv4/timer.c
--- v1.3.67/linux/net/ipv4/timer.c	Tue Feb 20 14:37:30 1996
+++ linux/net/ipv4/timer.c	Thu Feb 22 16:50:46 1996
@@ -94,7 +94,7 @@
 
 	if (sk->users)
 	{
-		sk->timer.expires = jiffies+10;
+		sk->timer.expires = jiffies+HZ;
 		add_timer(&sk->timer);
 		sti();
 		return;
@@ -134,15 +134,7 @@
 		 *	the socket to be freed.
 		 */
 
-			if(sk->wmem_alloc!=0 || sk->rmem_alloc!=0)
-			{
-				sk->wmem_alloc++;	/* So it DOESN'T go away */
-				destroy_sock (sk);
-				sk->wmem_alloc--;	/* Might now have hit 0 - fall through and do it again if so */
-				sk->users = 0;	/* This will be ok, the destroy won't totally work */
-			}
-			if(sk->wmem_alloc==0 && sk->rmem_alloc==0)
-				destroy_sock(sk);	/* Socket gone, DON'T update sk->users! */
+			destroy_sock(sk);
 			break;
 
 		case TIME_CLOSE:
@@ -152,7 +144,7 @@
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->shutdown = SHUTDOWN_MASK;
-			reset_timer (sk, TIME_DESTROY, TCP_DONE_TIME);
+			reset_timer (sk, TIME_DONE, TCP_DONE_TIME);
 			break;
 
 		default:
diff -u --recursive --new-file v1.3.67/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v1.3.67/linux/net/ipx/af_ipx.c	Sat Feb 17 16:02:59 1996
+++ linux/net/ipx/af_ipx.c	Thu Feb 22 15:20:20 1996
@@ -1614,6 +1614,7 @@
 	sk->socket=sock;
 	sk->type=sock->type;
 	sk->ipx_type=0;		/* General user level IPX */
+	sk->ipx_ncp_server = NULL;
 	sk->debug=0;
 	sk->ipx_intrfc = NULL;
 	memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
diff -u --recursive --new-file v1.3.67/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- v1.3.67/linux/net/netrom/af_netrom.c	Sat Feb 17 16:02:59 1996
+++ linux/net/netrom/af_netrom.c	Wed Feb 21 08:33:26 1996
@@ -151,7 +151,7 @@
  *	Find a socket that wants to accept the Connect Request we just
  *	received.
  */
-static struct sock *nr_find_listener(ax25_address *addr, int type)
+static struct sock *nr_find_listener(ax25_address *addr)
 {
 	unsigned long flags;
 	struct sock *s;
@@ -160,7 +160,7 @@
 	cli();
 
 	for (s = nr_list; s != NULL; s = s->next) {
-		if (ax25cmp(&s->nr->source_addr, addr) == 0 && s->type == type && s->state == TCP_LISTEN) {
+		if (ax25cmp(&s->nr->source_addr, addr) == 0 && s->state == TCP_LISTEN) {
 			restore_flags(flags);
 			return s;
 		}
@@ -173,7 +173,7 @@
 /*
  *	Find a connected NET/ROM socket given my circuit IDs.
  */
-static struct sock *nr_find_socket(unsigned char index, unsigned char id, int type)
+static struct sock *nr_find_socket(unsigned char index, unsigned char id)
 {
 	struct sock *s;
 	unsigned long flags;
@@ -182,7 +182,7 @@
 	cli();
 
 	for (s = nr_list; s != NULL; s = s->next) {
-		if (s->nr->my_index == index && s->nr->my_id == id && s->type == type) {
+		if (s->nr->my_index == index && s->nr->my_id == id) {
 			restore_flags(flags);
 			return s;
 		}
@@ -196,7 +196,7 @@
 /*
  *	Find a connected NET/ROM socket given their circuit IDs.
  */
-static struct sock *nr_find_peer(unsigned char index, unsigned char id, int type)
+static struct sock *nr_find_peer(unsigned char index, unsigned char id)
 {
 	struct sock *s;
 	unsigned long flags;
@@ -205,7 +205,7 @@
 	cli();
 
 	for (s = nr_list; s != NULL; s = s->next) {
-		if (s->nr->your_index == index && s->nr->your_id == id && s->type == type) {
+		if (s->nr->your_index == index && s->nr->your_id == id) {
 			restore_flags(flags);
 			return s;
 		}
@@ -385,8 +385,8 @@
 {
 	struct sock *sk = (struct sock *)sock->data;
 
-	if (sk->type == SOCK_SEQPACKET && sk->state != TCP_LISTEN) {
-		memset(&sk->nr->user_addr, '\0', sizeof(ax25_address));
+	if (sk->state != TCP_LISTEN) {
+		memset(&sk->nr->user_addr, '\0', AX25_ADDR_LEN);
 		sk->max_ack_backlog = backlog;
 		sk->state           = TCP_LISTEN;
 		return 0;
@@ -498,9 +498,9 @@
 	nr->state      = NR_STATE_0;
 	nr->device     = NULL;
 
-	memset(&nr->source_addr, '\0', sizeof(ax25_address));
-	memset(&nr->user_addr,   '\0', sizeof(ax25_address));
-	memset(&nr->dest_addr,   '\0', sizeof(ax25_address));
+	memset(&nr->source_addr, '\0', AX25_ADDR_LEN);
+	memset(&nr->user_addr,   '\0', AX25_ADDR_LEN);
+	memset(&nr->dest_addr,   '\0', AX25_ADDR_LEN);
 
 	nr->sk = sk;
 	sk->nr = nr;
@@ -604,54 +604,48 @@
 
 	if (sk == NULL) return 0;
 
-	if (sk->type == SOCK_SEQPACKET) {
-		switch (sk->nr->state) {
-			case NR_STATE_0:
-				sk->state     = TCP_CLOSE;
-				sk->state_change(sk);
-				sk->dead      = 1;
-				nr_destroy_socket(sk);
-				break;
-
-			case NR_STATE_1:
-				sk->nr->state = NR_STATE_0;
-				sk->state     = TCP_CLOSE;
-				sk->state_change(sk);
-				sk->dead      = 1;
-				nr_destroy_socket(sk);
-				break;
-
-			case NR_STATE_2:
-				nr_write_internal(sk, NR_DISCACK);
-				sk->nr->state = NR_STATE_0;
-				sk->state     = TCP_CLOSE;
-				sk->state_change(sk);
-				sk->dead      = 1;
-				nr_destroy_socket(sk);
-				break;			
-
-			case NR_STATE_3:
-				nr_clear_queues(sk);
-				sk->nr->n2count = 0;
-				nr_write_internal(sk, NR_DISCREQ);
-				sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
-				sk->nr->t2timer = 0;
-				sk->nr->t4timer = 0;
-				sk->nr->state   = NR_STATE_2;
-				sk->state       = TCP_CLOSE;
-				sk->state_change(sk);
-				sk->dead        = 1;
-				sk->destroy     = 1;
-				break;
+	switch (sk->nr->state) {
 
-			default:
-				break;
-		}
-	} else {
-		sk->state = TCP_CLOSE;
-		sk->state_change(sk);
-		sk->dead = 1;
-		nr_destroy_socket(sk);
+		case NR_STATE_0:
+			sk->state     = TCP_CLOSE;
+			sk->state_change(sk);
+			sk->dead      = 1;
+			nr_destroy_socket(sk);
+			break;
+
+		case NR_STATE_1:
+			sk->nr->state = NR_STATE_0;
+			sk->state     = TCP_CLOSE;
+			sk->state_change(sk);
+			sk->dead      = 1;
+			nr_destroy_socket(sk);
+			break;
+
+		case NR_STATE_2:
+			nr_write_internal(sk, NR_DISCACK);
+			sk->nr->state = NR_STATE_0;
+			sk->state     = TCP_CLOSE;
+			sk->state_change(sk);
+			sk->dead      = 1;
+			nr_destroy_socket(sk);
+			break;			
+
+		case NR_STATE_3:
+			nr_clear_queues(sk);
+			sk->nr->n2count = 0;
+			nr_write_internal(sk, NR_DISCREQ);
+			sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
+			sk->nr->t2timer = 0;
+			sk->nr->t4timer = 0;
+			sk->nr->state   = NR_STATE_2;
+			sk->state       = TCP_CLOSE;
+			sk->state_change(sk);
+			sk->dead        = 1;
+			sk->destroy     = 1;
+			break;
+
+		default:
+			break;
 	}
 
 	sock->data = NULL;	
@@ -687,8 +681,8 @@
 	if (addr->fsa_ax25.sax25_ndigis == 1) {
 		if (!suser())
 			return -EPERM;
-		memcpy(&sk->nr->user_addr,   &addr->fsa_digipeater[0],   sizeof(ax25_address));
-		memcpy(&sk->nr->source_addr, &addr->fsa_ax25.sax25_call, sizeof(ax25_address));
+		sk->nr->user_addr   = addr->fsa_digipeater[0];
+		sk->nr->source_addr = addr->fsa_ax25.sax25_call;
 	} else {
 		source = &addr->fsa_ax25.sax25_call;
 
@@ -698,8 +692,8 @@
 			user = source;
 		}
 
-		memcpy(&sk->nr->user_addr,   user,   sizeof(ax25_address));
-		memcpy(&sk->nr->source_addr, source, sizeof(ax25_address));
+		sk->nr->user_addr   = *user;
+		sk->nr->source_addr = *source;
 	}
 
 	sk->nr->device = dev;
@@ -731,7 +725,7 @@
 		return -ECONNREFUSED;
 	}
 	
-	if (sk->state == TCP_ESTABLISHED && sk->type == SOCK_SEQPACKET)
+	if (sk->state == TCP_ESTABLISHED)
 		return -EISCONN;	/* No reconnect on a seqpacket socket */
 		
 	sk->state   = TCP_CLOSE;	
@@ -754,17 +748,16 @@
 			user = source;
 		}
 
-		memcpy(&sk->nr->user_addr,   user,   sizeof(ax25_address));
-		memcpy(&sk->nr->source_addr, source, sizeof(ax25_address));
-
-		sk->nr->device = dev;
+		sk->nr->user_addr   = *user;
+		sk->nr->source_addr = *source;
+		sk->nr->device      = dev;
 
 		nr_insert_socket(sk);		/* Finish the bind */
 	}
 
-	memcpy(&sk->nr->dest_addr, &addr->sax25_call, sizeof(ax25_address));
+	sk->nr->dest_addr = addr->sax25_call;
 
-	while (nr_find_socket((unsigned char)circuit / 256, (unsigned char)circuit % 256, SOCK_SEQPACKET) != NULL)
+	while (nr_find_socket((unsigned char)circuit / 256, (unsigned char)circuit % 256) != NULL)
 		circuit++;
 
 	sk->nr->my_index = circuit / 256;
@@ -878,13 +871,13 @@
 			return -ENOTCONN;
 		sax->fsa_ax25.sax25_family = AF_NETROM;
 		sax->fsa_ax25.sax25_ndigis = 1;
-		memcpy(&sax->fsa_ax25.sax25_call, &sk->nr->user_addr, sizeof(ax25_address));
-		memcpy(&sax->fsa_digipeater[0],   &sk->nr->dest_addr, sizeof(ax25_address));
-		*uaddr_len = sizeof(struct sockaddr_ax25) + sizeof(ax25_address);
+		sax->fsa_ax25.sax25_call = sk->nr->user_addr;
+		sax->fsa_digipeater[0]   = sk->nr->dest_addr;
+		*uaddr_len = sizeof(struct sockaddr_ax25) + AX25_ADDR_LEN;
 	} else {
 		sax->fsa_ax25.sax25_family = AF_NETROM;
 		sax->fsa_ax25.sax25_ndigis = 0;
-		memcpy(&sax->fsa_ax25.sax25_call, &sk->nr->source_addr, sizeof(ax25_address));
+		sax->fsa_ax25.sax25_call   = sk->nr->source_addr;
 		*uaddr_len = sizeof(struct sockaddr_ax25);
 	}
 
@@ -929,8 +922,8 @@
 	 * Find an existing socket connection, based on circuit ID, if its
 	 * a Connect Request base it on their circuit ID.
 	 */
-	if (((frametype & 0x0F) != NR_CONNREQ && (sk = nr_find_socket(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL) ||
-	    ((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL)) {
+	if (((frametype & 0x0F) != NR_CONNREQ && (sk = nr_find_socket(circuit_index, circuit_id)) != NULL) ||
+	    ((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id)) != NULL)) {
 		skb->h.raw = skb->data;
 
 		if ((frametype & 0x0F) == NR_CONNACK && skb->len == 22)
@@ -944,9 +937,9 @@
 	if ((frametype & 0x0F) != NR_CONNREQ)
 		return 0;
 		
-	sk = nr_find_listener(dest, SOCK_SEQPACKET);
+	sk = nr_find_listener(dest);
 
-	user   = (ax25_address *)(skb->data + 21);
+	user = (ax25_address *)(skb->data + 21);
 
 	if (sk == NULL || sk->ack_backlog == sk->max_ack_backlog || (make = nr_make_new(sk)) == NULL) {
 		nr_transmit_dm(skb);
@@ -959,9 +952,9 @@
 	make->state         = TCP_ESTABLISHED;
 
 	/* Fill in his circuit details */
-	memcpy(&make->nr->source_addr, dest, sizeof(ax25_address));
-	memcpy(&make->nr->dest_addr,   src,  sizeof(ax25_address));
-	memcpy(&make->nr->user_addr,   user, sizeof(ax25_address));
+	make->nr->source_addr = *dest;
+	make->nr->dest_addr   = *src;
+	make->nr->user_addr   = *user;
 
 	make->nr->your_index = circuit_index;
 	make->nr->your_id    = circuit_id;
@@ -1033,8 +1026,8 @@
 	if (usax) {
 		if (msg->msg_namelen < sizeof(sax))
 			return -EINVAL;
-		memcpy(&sax, usax, sizeof(sax));
-		if (sk->type == SOCK_SEQPACKET && memcmp(&sk->nr->dest_addr, &sax.sax25_call, sizeof(ax25_address)) != 0)
+		sax = *usax;
+		if (ax25cmp(&sk->nr->dest_addr, &sax.sax25_call) != 0)
 			return -EISCONN;
 		if (sax.sax25_family != AF_NETROM)
 			return -EINVAL;
@@ -1042,7 +1035,7 @@
 		if (sk->state != TCP_ESTABLISHED)
 			return -ENOTCONN;
 		sax.sax25_family = AF_NETROM;
-		memcpy(&sax.sax25_call, &sk->nr->dest_addr, sizeof(ax25_address));
+		sax.sax25_call   = sk->nr->dest_addr;
 	}
 	
 	if (sk->debug)
@@ -1130,7 +1123,7 @@
 	 * This works for seqpacket too. The receiver has ordered the queue for
 	 * us! We do one quick check first though
 	 */
-	if (sk->type == SOCK_SEQPACKET && sk->state != TCP_ESTABLISHED)
+	if (sk->state != TCP_ESTABLISHED)
 		return -ENOTCONN;
 
 	/* Now we can treat all alike */
@@ -1149,9 +1142,9 @@
 		struct sockaddr_ax25 addr;
 		
 		addr.sax25_family = AF_NETROM;
-		memcpy(&addr.sax25_call, skb->data + 7, sizeof(ax25_address));
+		memcpy(&addr.sax25_call, skb->data + 7, AX25_ADDR_LEN);
 
-		memcpy(sax, &addr, sizeof(*sax));
+		*sax = addr;
 
 		*addr_len = sizeof(*sax);
 	}
@@ -1189,8 +1182,7 @@
 			put_fs_long(amount, (unsigned long *)arg);
 			return 0;
 
-		case TIOCINQ:
-		{
+		case TIOCINQ: {
 			struct sk_buff *skb;
 			/* These two are safe on a single CPU system as only user tasks fiddle here */
 			if ((skb = skb_peek(&sk->receive_queue)) != NULL)
@@ -1231,8 +1223,7 @@
 			if (!suser()) return -EPERM;
 			return nr_rt_ioctl(cmd, (void *)arg);
 
-		case SIOCNRGETPARMS:
-		{
+		case SIOCNRGETPARMS: {
 			struct nr_parms_struct nr_parms;
 			if ((err = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct nr_parms_struct))) != 0)
 				return err;
@@ -1242,8 +1233,7 @@
 			return 0;
 		}
 
-		case SIOCNRSETPARMS:
-		{
+		case SIOCNRSETPARMS: {
 			struct nr_parms_struct nr_parms;
 			if (!suser()) return -EPERM;
 			if ((err = verify_area(VERIFY_READ, (void *)arg, sizeof(struct nr_parms_struct))) != 0)
diff -u --recursive --new-file v1.3.67/linux/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c
--- v1.3.67/linux/net/netrom/nr_dev.c	Sat Nov 25 19:04:58 1995
+++ linux/net/netrom/nr_dev.c	Wed Feb 21 08:33:26 1996
@@ -55,8 +55,7 @@
 {
 	struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
 
-	if (!dev->start) 
-	{
+	if (!dev->start) {
 		stats->rx_errors++;
 		return 0;
 	}
diff -u --recursive --new-file v1.3.67/linux/net/netrom/nr_out.c linux/net/netrom/nr_out.c
--- v1.3.67/linux/net/netrom/nr_out.c	Wed Sep 27 16:00:02 1995
+++ linux/net/netrom/nr_out.c	Wed Feb 21 08:33:26 1996
@@ -150,7 +150,7 @@
 	end   = (sk->nr->va + sk->window) % NR_MODULUS;
 
 	if (!(sk->nr->condition & PEER_RX_BUSY_CONDITION) &&
-	    start != end                                   &&
+	    start != end                                  &&
 	    skb_peek(&sk->write_queue) != NULL) {
 
 		sk->nr->vs = start;
@@ -208,13 +208,13 @@
 	 */
 	dptr = skb_push(skb, NR_NETWORK_LEN);
 
-	memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
+	memcpy(dptr, &sk->nr->source_addr, AX25_ADDR_LEN);
 	dptr[6] &= ~LAPB_C;
 	dptr[6] &= ~LAPB_E;
 	dptr[6] |= SSSID_SPARE;
 	dptr += AX25_ADDR_LEN;
 
-	memcpy(dptr, &sk->nr->dest_addr,   sizeof(ax25_address));
+	memcpy(dptr, &sk->nr->dest_addr, AX25_ADDR_LEN);
 	dptr[6] &= ~LAPB_C;
 	dptr[6] |= LAPB_E;
 	dptr[6] |= SSSID_SPARE;
diff -u --recursive --new-file v1.3.67/linux/net/netrom/nr_route.c linux/net/netrom/nr_route.c
--- v1.3.67/linux/net/netrom/nr_route.c	Mon Dec 11 15:42:11 1995
+++ linux/net/netrom/nr_route.c	Wed Feb 21 08:33:27 1996
@@ -88,21 +88,20 @@
 		if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
 			return -ENOMEM;
 
-		memcpy(&nr_neigh->callsign, ax25, sizeof(ax25_address));
-
-		nr_neigh->digipeat= NULL;
-		nr_neigh->dev     = dev;
-		nr_neigh->quality = nr_default.quality;
-		nr_neigh->locked  = 0;
-		nr_neigh->count   = 0;
-		nr_neigh->number  = nr_neigh_no++;
+		nr_neigh->callsign = *ax25;
+		nr_neigh->digipeat = NULL;
+		nr_neigh->dev      = dev;
+		nr_neigh->quality  = nr_default.quality;
+		nr_neigh->locked   = 0;
+		nr_neigh->count    = 0;
+		nr_neigh->number   = nr_neigh_no++;
 
 		if (ax25_digi != NULL) {
 			if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) {
 				kfree_s(nr_neigh, sizeof(*nr_neigh));
 				return -ENOMEM;
 			}
-			memcpy(nr_neigh->digipeat, ax25_digi, sizeof(*ax25_digi));
+			*nr_neigh->digipeat = *ax25_digi;
 		}
 			
 		save_flags(flags);
@@ -118,7 +117,7 @@
 		if ((nr_node = (struct nr_node *)kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL)
 			return -ENOMEM;
 
-		memcpy(&nr_node->callsign, nr, sizeof(ax25_address));
+		nr_node->callsign = *nr;
 		memcpy(&nr_node->mnemonic, mnemonic, sizeof(nr_node->mnemonic));
 
 		nr_node->which = 0;
@@ -355,14 +354,13 @@
 	if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
 		return -ENOMEM;
 
-	memcpy(&nr_neigh->callsign, callsign, sizeof(ax25_address));
-
-	nr_neigh->digipeat= NULL;
-	nr_neigh->dev     = dev;
-	nr_neigh->quality = quality;
-	nr_neigh->locked  = 1;
-	nr_neigh->count   = 0;
-	nr_neigh->number  = nr_neigh_no++;
+	nr_neigh->callsign = *callsign;
+	nr_neigh->digipeat = NULL;
+	nr_neigh->dev      = dev;
+	nr_neigh->quality  = quality;
+	nr_neigh->locked   = 1;
+	nr_neigh->count    = 0;
+	nr_neigh->number   = nr_neigh_no++;
 
 	save_flags(flags);
 	cli();
diff -u --recursive --new-file v1.3.67/linux/net/netrom/nr_subr.c linux/net/netrom/nr_subr.c
--- v1.3.67/linux/net/netrom/nr_subr.c	Wed Sep 27 16:00:02 1995
+++ linux/net/netrom/nr_subr.c	Wed Feb 21 08:33:27 1996
@@ -192,12 +192,12 @@
 			*dptr++  = 0;
 			*dptr++  = frametype;
 			*dptr++  = sk->window;
-			memcpy(dptr, &sk->nr->user_addr, sizeof(ax25_address));
+			memcpy(dptr, &sk->nr->user_addr, AX25_ADDR_LEN);
 			dptr[6] &= ~LAPB_C;
 			dptr[6] &= ~LAPB_E;
 			dptr[6] |= SSSID_SPARE;
 			dptr    += AX25_ADDR_LEN;
-			memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
+			memcpy(dptr, &sk->nr->source_addr, AX25_ADDR_LEN);
 			dptr[6] &= ~LAPB_C;
 			dptr[6] &= ~LAPB_E;
 			dptr[6] |= SSSID_SPARE;
diff -u --recursive --new-file v1.3.67/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
--- v1.3.67/linux/net/unix/af_unix.c	Sat Feb 17 16:02:59 1996
+++ linux/net/unix/af_unix.c	Wed Feb 21 08:33:27 1996
@@ -20,6 +20,7 @@
  *		Alan Cox	:	Limit size of allocated blocks.
  *		Alan Cox	:	Fixed the stupid socketpair bug.
  *		Alan Cox	:	BSD compatibility fine tuning.
+ *		Alan Cox	:	Fixed a bug in connect when interrupted.
  *
  *
  * Known differences from reference BSD that was tested:
@@ -69,8 +70,9 @@
 #define min(a,b)	(((a)<(b))?(a):(b))
 
 /*
- * Make sure the unix name is null-terminated.
+ *	Make sure the unix name is null-terminated.
  */
+ 
 static inline void unix_mkname(struct sockaddr_un * sunaddr, unsigned long len)
 {
 	if (len >= sizeof(*sunaddr))
@@ -468,9 +470,13 @@
 			sock->state=SS_UNCONNECTED;
 			return -ECONNREFUSED;
 		}
-		if(sock->state==SS_CONNECTING)
+		if(sock->state!=SS_CONNECTING)
+			return -EISCONN;
+		if(flags&O_NONBLOCK)
 			return -EALREADY;
-		return -EISCONN;
+		/*
+		 *	Drop through the connect up logic to the wait.
+		 */
 	}
 	
 	if(addr_len < sizeof(sunaddr->sun_family)+1 || sunaddr->sun_family!=AF_UNIX)
@@ -478,15 +484,14 @@
 		
 	unix_mkname(sunaddr, addr_len);
 		
-	if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
-	{
-		sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
-		sk->protinfo.af_unix.other=NULL;
-		sock->state=SS_UNCONNECTED;
-	}
-
-	if(sock->type==SOCK_DGRAM)
+	if(sk->type==SOCK_DGRAM)
 	{
+		if(sk->protinfo.af_unix.other)
+		{
+			sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
+			sk->protinfo.af_unix.other=NULL;
+			sock->state=SS_UNCONNECTED;
+		}
 		other=unix_find_other(sunaddr->sun_path, &err);
 		if(other==NULL)
 			return err;
diff -u --recursive --new-file v1.3.67/linux/scripts/Configure linux/scripts/Configure
--- v1.3.67/linux/scripts/Configure	Sat Feb 17 16:02:59 1996
+++ linux/scripts/Configure	Thu Feb 22 14:40:02 1996
@@ -79,7 +79,8 @@
      #now pick out the right help text:
      text=$(sed -n "/^$var[ 	]*\$/,\${
 			/^$var[ 	]*\$/b
-			/^#.*/b;/^[ 	]*\$/q
+			/^#.*/b
+			/^[ 	]*\$/q
 			p
 		    }" Documentation/Configure.help)
      if [ -z "$text" ]
diff -u --recursive --new-file v1.3.67/linux/scripts/Menuconfig linux/scripts/Menuconfig
--- v1.3.67/linux/scripts/Menuconfig	Sat Feb 17 16:02:59 1996
+++ linux/scripts/Menuconfig	Thu Feb 22 14:40:00 1996
@@ -588,11 +588,12 @@
 			default="${defaults%%*}" defaults="${defaults#*}"
 			;;
 		2)	
+			echo >>dialog.out
 			read selection <dialog.out
 			default="${selection##* }"
 			case "$selection" in
 			*"-->"*) : ;;
-			*)	 eval help $selection ;;
+			*)	 eval help "$selection" ;;
 			esac
 			;;
 		255|1)
