diff -u --recursive --new-file v2.2.1/linux/CREDITS linux/CREDITS
--- v2.2.1/linux/CREDITS	Thu Jan 28 12:58:02 1999
+++ linux/CREDITS	Sat Feb  6 12:46:20 1999
@@ -1403,6 +1403,13 @@
 S: FIN-00330 Helsingfors
 S: Finland
 
+N: Trond Myklebust
+E: trond.myklebust@fys.uio.no
+D: current NFS client hacker.
+S: Dagaliveien 31e
+S: N-0391 Oslo
+S: Norway
+
 N: Matija Nalis
 E: mnalis@jagor.srce.hr
 E: mnalis@voyager.hr
diff -u --recursive --new-file v2.2.1/linux/Documentation/00-INDEX linux/Documentation/00-INDEX
--- v2.2.1/linux/Documentation/00-INDEX	Tue Dec 22 14:16:53 1998
+++ linux/Documentation/00-INDEX	Mon Feb  1 12:03:20 1999
@@ -57,6 +57,8 @@
 	- info on the in-kernel binary support for Java(tm)
 joystick.txt
 	- info on using joystick devices (and driver) with linux.
+kbuild/
+	- directory with info about the kernel build process
 kmod.txt
 	- - info on the kernel module loader/unloader (kerneld replacement)
 locks.txt
diff -u --recursive --new-file v2.2.1/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.2.1/linux/Documentation/Configure.help	Wed Jan 20 23:14:04 1999
+++ linux/Documentation/Configure.help	Sun Feb 21 17:48:50 1999
@@ -51,7 +51,7 @@
 # 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-1998 by Axel Boldt and many others and are governed by the GNU
+# 1995-1999 by Axel Boldt and many others and are governed by the GNU
 # General Public License.
 
 Prompt for development and/or incomplete code/drivers
@@ -81,30 +81,33 @@
 
 Symmetric Multi Processing
 CONFIG_SMP
-  This enables support for systems with more than one CPU.  If you have a
-  system with only one CPU, like most personal computers, say N.  If you
-  have a system with more than one CPU, say Y.
-
-  A non-SMP kernel will run on any machine, but will use only one CPU of
-  a multi-CPU machine.  An SMP kernel will run on many, but not all,
-  single-CPU machines.  On a single-CPU machine, a non-SMP kernel
-  will run faster than an SMP kernel.
-
-  i486 based SMP boards don't boot CONFIG_M586/M686 kernels. CONFIG_M686
-  SMP kernels might not work on all Pentium based boards.
-
-  People using multiprocessor machines should also say Y to "Enhanced
-  Real Time Clock Support", below.  The "Advanced Power Management"
-  code will be disabled in an SMP kernel.
+  This enables support for systems with more than one CPU. If you have
+  a system with only one CPU, like most personal computers, say N. If
+  you have a system with more than one CPU, say Y.
+
+  If you say N here, the kernel will run on single and multiprocessor
+  machines, but will use only one CPU of a multiprocessor machine. If
+  you say Y here, the kernel will run on many, but not all,
+  singleprocessor machines. On a singleprocessor machine, the kernel
+  will run faster if you say N here.
+
+  Note that if you say Y here and choose architecture "586" or
+  "Pentium" under "Processor family", the kernel will not work on 486
+  architectures. Similarly, multiprocessor kernels for the "PPro"
+  architecture may not work on all Pentium based boards.
+
+  People using multiprocessor machines who say Y here should also say
+  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
+  Management" code will be disabled if you say Y here.
 
-  If you don't know what to do here, say N.
-  
   See also: Documentation/SMP.txt, Documentation/smp.tex,
   Documentation/smp.txt, and Documentation/IO-APIC.txt.  Also see the
   SMP-FAQ on the WWW at http://www.irisa.fr/prive/mentre/smp-faq/ (to
   browse the WWW, you need to have access to a machine on the Internet
   that has a program like lynx or netscape).
   
+  If you don't know what to do here, say N.
+  
 Kernel math emulation
 CONFIG_MATH_EMULATION
   Linux can emulate a math coprocessor (used for floating point
@@ -134,9 +137,8 @@
 Kernel FP software completion
 CONFIG_MATHEMU
   This option is required for IEEE compliant floating point arithmetic
-  on the Alpha.  The only time you would ever not say Y is to say M
-  in order to debug the code.  Do not say anything but Y unless you
-  know what you are doing.
+  on the Alpha. The only time you would ever not say Y is to say M in
+  order to debug the code. Say Y unless you know what you are doing.
 
 Normal PC floppy disk support
 CONFIG_BLK_DEV_FD
@@ -276,10 +278,17 @@
   performance, look for the hdparm package at
   ftp://metalab.unc.edu:/pub/Linux/kernel/patches/diskdrives/
 
-  If you have one or more IDE drives, say Y here. If your system has
-  no IDE drives, or if memory requirements are really tight, you could
-  say N here, and select the "Old hard disk driver" instead to save
-  about 13 KB of memory in the kernel.
+  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 and
+  Documentation/ide.txt. The module will be called ide.o. Do not
+  compile this driver as a module if your root filesystem (the one
+  containing the directory /) is located on an IDE device.
+
+  If you have one or more IDE drives, say Y or M here. If your system
+  has no IDE drives, or if memory requirements are really tight, you
+  could say N here, and select the "Old hard disk driver" below
+  instead to save about 13 KB of memory in the kernel.
 
 Old hard disk (MFM/RLL/IDE) driver
 CONFIG_BLK_DEV_HD_ONLY
@@ -382,10 +391,12 @@
 CONFIG_BLK_DEV_IDEFLOPPY
   If you have an IDE floppy drive which uses the ATAPI protocol,
   answer Y. ATAPI is a newer protocol used by IDE CDROM/tape/floppy
-  drives, similar to the SCSI protocol. IDE floppy drives include the
-  LS-120 and the ATAPI ZIP (ATAPI PD-CD/CDR drives are not supported
-  by this driver; support for PD-CD/CDR drives is available if you
-  answer Y to "SCSI emulation support", below).
+  drives, similar to the SCSI protocol. 
+
+  The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by
+  this driver. (ATAPI PD-CD/CDR drives are not supported by this
+  driver; support for PD-CD/CDR drives is available if you answer Y to
+  "SCSI emulation support", below).
 
   If you say Y here, the FLOPPY drive will be identified along with
   other IDE devices, as "hdb" or "hdc", or something similar (check
@@ -519,7 +530,8 @@
   If you suspect your hardware is at all flakey, say N here.
   Do NOT email the IDE kernel people regarding this issue!
 
-  It is nearly always safe to say Y to this question.
+  It is normally safe to answer Y to this question unless your
+  motherboard uses a VIA VP2 chipset, in which case you should say N.
 
 Other IDE chipset support
 CONFIG_IDE_CHIPSETS
@@ -572,6 +584,11 @@
 CONFIG_BLK_DEV_PS2
   Say Y here if you have a PS/2 machine with a MCA bus and an ESDI
   hard disk.
+  
+  If you want to compile the 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. The module will be
+  called ps2esdi.o.
 
 Tekram TRM290 chipset support (EXPERIMENTAL)
 CONFIG_BLK_DEV_TRM290
@@ -1068,6 +1085,10 @@
   contained in the package net-tools, the location and version number
   of which are given in Documentation/Changes.
 
+  For a general introduction to Linux networking, it is highly
+  recommended to read the NET-3-HOWTO, available via FTP (user:
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
+
 Network aliasing
 CONFIG_NET_ALIAS
   If you say Y here, you will be able to set multiple network
@@ -1178,12 +1199,12 @@
 Alpha system type
 CONFIG_ALPHA_GENERIC
   This is the system type of your hardware.  A "generic" kernel will
-  run on any supported Alpha system.  Configuring a kernel for one
-  specific system can save about 200K and operate more efficiently.
+  run on any supported Alpha system. However, if you configure a
+  kernel for your specific system, it will be faster and smaller.
 
   To find out what type of Alpha system you have, you may want to
   check out the Linux/Alpha FAQ, accessible on the WWW from
-  http://www.azstarnet.com/~axplinux/ (To browse the WWW, you need to
+  http://www.alphalinux.org (To browse the WWW, you need to
   have access to a machine on the Internet that has a program like
   lynx or netscape).  In summary:
 
@@ -1197,7 +1218,8 @@
   EB64+               EB64+ 21064 evaluation board
   EB66                EB66 21066 evaluation board
   EB66+               EB66+ 21066 evaluation board
-  Jensen              DECpc 150, DEC 2000 model 300, DEC 2000 model 500
+  Jensen              DECpc 150, DEC 2000 model 300, 
+                      DEC 2000 model 500
   LX164               AlphaPC164-LX
   Miata               Personal Workstation 433a, 433au, 500a,
                       500au, 600a, or 600au
@@ -1227,7 +1249,7 @@
   which is command line driven, and ARC, which uses menus and arrow
   keys. 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
+  http://www.alphalinux.org (To browse the WWW, you need to
   have access to a machine on the Internet that has a program like
   lynx or netscape).
 
@@ -1333,34 +1355,26 @@
   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 (MCA) or
-  VESA. If you have PCI, say Y, otherwise N. The PCI-HOWTO, available
-  via FTP (user: anonymous) in
+  VESA. If you have PCI, say Y, otherwise N. 
+
+  The PCI-HOWTO, available via FTP (user: anonymous) in
   ftp://metalab.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 access mode
 CONFIG_PCI_GOBIOS
-  If you have enabled PCI bus support above, you probably want to
-  allow Linux to use your PCI BIOS to detect the PCI devices and
-  determine their configuration. Note: some old PCI motherboards have
-  BIOS bugs and may crash if you say Y here -- for such motherboards,
-  you should say N here and say Y to "PCI direct access support"
-  instead.
-
-  Except for some special cases (embedded systems with no BIOS), you
-  probably should say Y here.
-
-  If you don't want to use the PCI BIOS (e.g., because you run some
-  embedded system with no BIOS at all) or Linux says it cannot use
-  your PCI BIOS, you can enable direct PCI hardware here. It might
-  fail if your machine is based on some unusual chipset, but it
-  usually works. If both PCI BIOS and direct PCI access are enabled,
-  the use of BIOS is preferred. If unsure, say Y.
+  On PCI systems, the BIOS can be used to detect the PCI devices and
+  determine their configuration. However, some old PCI motherboards
+  have BIOS bugs and may crash if this is done. Also, some embedded
+  PCI-based systems don't have any BIOS at all. Linux can also try to
+  detect the PCI hardware directly without using the BIOS.
+
+  With this option, you can specify how Linux should detect the PCI
+  devices. If you choose "BIOS", the BIOS will be used, if you choose
+  "Direct", the BIOS won't be used, and if you choose "Any", the
+  kernel will try the direct access method and falls back to the BIOS
+  if that doesn't work. If unsure, go with the default.
 
 PCI quirks
 CONFIG_PCI_QUIRKS
@@ -1385,11 +1399,8 @@
   PCI (/proc/bus/pci) has been implemented and the old one is
   supported for compatibility reasons only; you'll get the old one (in
   addition to the new one) if you say Y here and to "/proc filesystem
-  support", below. If unsure, say Y.
-
-If you say Y here and to the "/proc filesystem support" below, you
-  will get a directory /proc/pci with information about your PCI
-  hardware. If unsure, say Y.
+  support", below. If unsure, say Y. If you say N, you'll only get the
+  new /proc/bus/pci interface.
 
 MCA support
 CONFIG_MCA
@@ -1398,7 +1409,7 @@
   Documentation/mca.txt (and especially the web page given there)
   before attempting to build an MCA bus kernel.
 
-SGI Visal Workstation support
+SGI Visual Workstation support
 CONFIG_VISWS
   The SGI Visual Workstation series is an IA32-based workstation
   based on SGI systems chips with some legacy PC hardware attached.
@@ -1593,19 +1604,21 @@
   all x86 CPU types (albeit not optimally fast), you can specify
   "386" here.
 
-  If you specify one of "486" or "Pentium" or "PPro", then the kernel
-  will not necessarily run on earlier architectures (ie a Pentium
-  optimized kernel will run on a PPro, but not necessarily on a i486).
+  If you specify one of "486" or "586" or "Pentium" or "PPro", then
+  the kernel will not necessarily run on earlier architectures (e.g. a
+  Pentium optimized kernel will run on a PPro, but not necessarily on
+  a i486).
 
   Here are the settings recommended for greatest speed:
-   - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX and
-     Cyrix/TI 486DLC/DLC2. Only "386" kernels will run on a 386 class
-     machine.
+   - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
+     486DLC/DLC2 and UMC 486SX-S. Only "386" kernels will run on a 386
+     class machine.
    - "486" for the AMD/Cyrix/IBM/Intel DX4 or 486DX/DX2/SL/SX/SX2,
      AMD/Cyrix 5x86, NexGen Nx586 and UMC U5D or U5S.
-   - "586" for generic Pentium CPU's, possibly lacking the TSC register.
-   - "Pentium" for the Intel Pentium/Pentium MMX, AMD K5, K6 and K6-3D.
-     This option will assume that you have a time stamp counter.
+   - "586" for generic Pentium CPUs, possibly lacking the TSC 
+     (time stamp counter) register.
+   - "Pentium" for the Intel Pentium/Pentium MMX, AMD K5, K6 and 
+     K6-3D.
    - "PPro" for the Cyrix/IBM/National Semiconductor 6x86MX, MII and
      Intel Pentium II/Pentium Pro.
 
@@ -1667,9 +1680,9 @@
 
   If you are compiling for the x86 architecture, you can say Y if you
   want to play with it, but it is not essential. Please note that
-  running graphical applications that directly touch the hardware (e.g.
-  and accelerated X server) and that are not frame buffer device-aware
-  may cause unexpected results. If unsure, say N.
+  running graphical applications that directly touch the hardware
+  (e.g. an accelerated X server) and that are not frame buffer
+  device-aware may cause unexpected results. If unsure, say N.
 
 Acorn VIDC support
 CONFIG_FB_ACORN
@@ -1807,64 +1820,71 @@
   This is the frame buffer device driver for generic VESA 2.0
   compliant graphic cards. The older VESA 1.2 cards are not supported.
   You will get a boot time penguin logo at no additional cost. Please
-  read Documentation/fb/vesafb.txt and the . If unsure, say Y.
+  read Documentation/fb/vesafb.txt. If unsure, say Y.
 
 Backward compatibility mode for Xpmac
 CONFIG_FB_COMPAT_XPMAC
-  If you use the Xpmac X server (common with mklinux), you'll need
-  to enable this to use X. You should consider changing to XFree86
-  which includes a server that supports the frame buffer device
-  directly (XF68_FBDev).
+  If you use the Xpmac X server (common with mklinux), you'll need to
+  say Y here to use X. You should consider changing to XFree86 which
+  includes a server that supports the frame buffer device directly
+  (XF68_FBDev).
 
 Matrox unified accelerated driver
 CONFIG_FB_MATROX
-  Say Y here  if you have  Matrox Millennium,  Matrox Millennium  II, 
+  Say Y here if you have Matrox Millennium, Matrox Millennium II,
   Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
-  Mystique G200, Matrox Millennium G200  or Matrox Marvel G200 in your 
-  box.  At this time, G100,  Mystique G200 and  Marvel G200 support is
-  untested.  If  you  want,  you  can  select M,  in this  case module
-  matroxfb.o will  be created.  You can pass parameters into driver if 
-  it is compiled  into kernel by  specifying "video=matrox:XXX", where 
-  meaning of XXX you can found at the end of main source file
-  (drivers/video/matroxfb.c)  at  boot time.  Same  parameters  can  be 
-  passed into insmod if driver is used as module.
+  Mystique G200, Matrox Millennium G200 or Matrox Marvel G200 video
+  card in your box. At this time, support for the G100, Mystique G200
+  and Marvel G200 is untested.
+
+  This driver is also available as a module ( = code which can be
+  inserted and removed from the running kernel whenever you want).
+  The module will be called matroxfb.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
+
+  You can pass several parameters to the driver at boot time or at
+  module load time. The parameters look like "video=matrox:XXX", where
+  the meaning of XXX can be found at the end of the main source file
+  (drivers/video/matroxfb.c). Please see the file
+  Documentation/fb/matroxfb.txt. 
 
 Matrox Millennium support
 CONFIG_FB_MATROX_MILLENIUM
-  Say Y here if you  have Matrox Millennium  or Matrox Millennium II in 
-  the box. If you select "Advanced lowlevel driver options", you should 
-  check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp packed pixel, 24
-  bpp  packed pixel  and 32  bpp packed  pixel. You  can also  use font 
-  widths different from 8.
+  Say Y here if you have a Matrox Millennium or Matrox Millennium II
+  video card. If you select "Advanced lowlevel driver options" below,
+  you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
+  packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
+  also use font widths different from 8.
 
 Matrox Mystique support
 CONFIG_FB_MATROX_MYSTIQUE
-  Say Y here if you have  Matrox Mystique or Matrox Mystique 220 in the 
-  box.  If you  select  "Advanced lowlevel driver options",  you should 
-  check  8 bpp packed pixel,  16 bpp packed pixel,  24 bpp packed pixel
-  and  32 bpp  packed pixel.  You can  also use  font widths  different 
-  from 8.
+  Say Y here if you have a Matrox Mystique or Matrox Mystique 220
+  video card. If you select "Advanced lowlevel driver options" below,
+  you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
+  packed pixel and 32 bpp packed pixel. You can also use font widths
+  different from 8.
 
 Matrox G100/G200 support
 CONFIG_FB_MATROX_G100
-  Say Y  here if you have Matrox Productiva G100, Matrox Mystique G200,
-  Matrox  Marvel G200  or  Matrox  Millennium G200  in the box.  If you
-  select  "Advanced lowlevel  driver options",  you should  check 8 bpp
-  packed pixel,  16 bpp packed  pixel, 24 bpp  packed pixel  and 32 bpp
-  packed pixel. You can also use font widths different from 8.
+  Say Y here if you have a Matrox Productiva G100, Matrox Mystique
+  G200, Matrox Marvel G200 or Matrox Millennium G200 video card. If
+  you select "Advanced lowlevel driver options", you should check 8
+  bpp packed pixel, 16 bpp packed pixel, 24 bpp packed pixel and 32
+  bpp packed pixel. You can also use font widths different from 8.
 
 Matrox unified driver multihead support
 CONFIG_FB_MATROX_MULTIHEAD
-  Say Y  here if you  have more  than one (supported) Matrox  device in 
-  computer  and you  want to  use all  of them.  If you  have only  one 
-  device,  you should say N because of driver compiled with Y is larger 
-  and a bit slower, especially on ia32 (ix86).
-  If you compiled  driver as module,  you are VERY  interested in speed 
-  and  you can  use 40KB  of memory  per each  Matrox  device,  you can 
-  compile driver  without multihead  support and  instead of  it insmod 
-  more module instances. In this case, you MUST specify parameter dev=N 
-  to insmod, where N is sequential number of Matrox device  (0 = first, 
-  1 = second and so on).
+  Say Y here if you have more than one (supported) Matrox device in
+  your computer and you want to use all of them. If you have only one
+  device, you should say N because the driver compiled with Y is
+  larger and a bit slower, especially on ia32 (ix86). 
+
+  If you said M to "Matrox unified accelerated driver" and N here, you
+  will still be able to use several Matrox devices simultaneously.
+  This is slightly faster but uses 40 KB of kernel memory per Matrox
+  card. You do this by inserting several instances of the module 
+  matroxfb.o into the kernel with insmod, supplying the parameter
+  "dev=N" where N is 0, 1, etc. for the different Matrox devices.
   
 MDA text console (dual-headed)
 CONFIG_MDA_CONSOLE
@@ -2145,15 +2165,20 @@
 TCP/IP networking
 CONFIG_INET
   These are the protocols used on the Internet and on most local
-  Ethernets. The safest is to say Y here (which will enlarge your
-  kernel by about 35 kB), since some programs (e.g. the X window
+  Ethernets. It is highly recommended to say Y here (this will enlarge
+  your kernel by about 35 KB), since some programs (e.g. the X window
   system) use TCP/IP even if your machine is not connected to any
   other computer. You will get the so-called loopback device which
-  allows you to ping yourself (great fun, that!). This option is 
-  also necessary if you want to use the full power of term (term 
-  is a program which gives you almost full Internet connectivity 
-  if you have a regular dial up shell account on some Internet 
-  connected Unix computer; for more information, read
+  allows you to ping yourself (great fun, that!).
+
+  For an excellent introduction to Linux networking, please read the
+  NET-3-HOWTO, available via FTP (user: anonymous) from
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
+
+  This option is also necessary if you want to use the full power of
+  term (term is a program which gives you almost full Internet
+  connectivity if you have a regular dial up shell account on some
+  Internet connected Unix computer; for more information, read
   http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html).
   
   If you say Y here and also to "/proc filesystem support" and "Sysctl
@@ -2259,7 +2284,9 @@
 CONFIG_IP_ROUTE_NAT
   If you say Y here, your router will be able to modify source and
   destination addresses of packets that pass through it, in a manner
-  you specify.
+  you specify. Please see
+  http://www.csn.tu-chemnitz.de/HyperNews/get/linux-ip-nat.html for
+  details. 
 
 IP: optimize as router not host
 CONFIG_IP_ROUTER
@@ -2293,7 +2320,7 @@
   http://www.rustcorp.com/linux/ipchains/) to allow selective blocking
   of Internet traffic based on type, origin and destination. 
   Note that the Linux firewall code has changed and the old program
-  called ipfwadm won't work anymore.
+  called ipfwadm won't work anymore. Please read the IPCHAINS-HOWTO.
 
   The type of firewall provided by ipchains and this kernel support is
   called a "packet filter". The other type of firewall, a
@@ -2330,19 +2357,16 @@
 
 IP: firewall packet netlink device
 CONFIG_IP_FIREWALL_NETLINK
-  If you say Y here, then the first 128 bytes of each packet that hit
-  your Linux firewall and was blocked are passed on to optional user
-  space monitoring software that can then look for attacks and take
-  actions such as paging the administrator of the site.
+  If you say Y here, you can use the ipchains tool to copy all or part
+  of any packet you specify that hits your Linux firewall to optional
+  user space monitoring software that can then look for attacks and
+  take actions such as paging the administrator of the site.
 
   To use this, you need to create a character special file under /dev
   with major number 36 and minor number 3 using mknod ("man mknod"),
   and you need (to write) a program that reads from that device and
   takes appropriate action.
 
-  With the ipchains tool you can specify which packets you want to go
-  to this device, as well as how many bytes from each packet.
-
 IP: kernel level autoconfiguration
 CONFIG_IP_PNP
   This enables automatic configuration of IP addresses of devices and
@@ -2433,7 +2457,7 @@
   host replies, the Linux firewall will silently forward the traffic
   to the corresponding local computer. This way, the computers on your
   local net are completely invisible to the outside world, even though
-  they can reach the outside and can be reached. This makes it
+  they can reach the outside and can receive replies. This makes it
   possible to have the computers on the local network participate on
   the Internet even if they don't have officially registered IP
   addresses. (This last problem can also be solved by connecting the
@@ -2480,8 +2504,8 @@
 IP: masquerading special modules support
 CONFIG_IP_MASQUERADE_MOD
   This provides support for special modules that can modify the
-  rewriting rules used when masquerading. Please note that this feature
-  adds a little overhead in the input packet processing chain.
+  rewriting rules used when masquerading. Please note that this
+  feature adds a little overhead in the input packet processing chain.
 
   Examples of such modules are ipautofw (allowing the masquerading of
   protocols which don't have their own protocol helpers) and port
@@ -2521,15 +2545,15 @@
   forwarding of packets from outside to inside a firewall on given
   ports. This could be useful if, for example, you want to run a web
   server behind the firewall or masquerading host and that web server
-  should be visible to the outside world. An external client connects
-  to port 80 of the firewall, the firewall forwards requests to this
-  port to the web server, the web server handles the request and the
-  results are sent through the firewall to the original client. The
-  client thinks that the firewall machine itself is running the web
-  server. This can also be used for load balancing if you have a farm
-  of identical web servers behind the firewall.
+  should be accessible from the outside world. An external client
+  sends a request to port 80 of the firewall, the firewall forwards
+  this request to the web server, the web server handles the request
+  and the results are sent through the firewall to the original
+  client. The client thinks that the firewall machine itself is
+  running the web server. This can also be used for load balancing if
+  you have a farm of identical web servers behind the firewall.
 
-  Information about it is available from
+  Information about this feature is available from
   http://www.monmouth.demon.co.uk/ipsubs/portforwarding.html (to
   browse the WWW, you need to have access to a machine on the Internet
   that has a program like lynx or netscape). For general info, please
@@ -2548,12 +2572,14 @@
 
 IP: ipmarkfw masquerade support
 CONFIG_IP_MASQUERADE_MFW
-  This provides functionality similar to port forwarding, the
-  difference is that Firewall Mark Forwarding uses "firewalling mark" 
-  to select which packets must forward (see ipchains(8), "-m" argument).
+  Firewall Mark Forwarding provides functionality similar to port
+  forwarding (see "IP: ipportfw masquerade support", above), the
+  difference being that Firewall Mark Forwarding uses "firewalling
+  mark" to select which packets must be forwarded (see ipchains(8),
+  "-m" argument).
 
-  The ip_masq_mfw code is still under development and so is currently
-  marked EXPERIMENTAL. If you want to try it, say Y.
+  This code is still under development and so is currently marked
+  EXPERIMENTAL. If you want to try it, say Y.
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -2739,22 +2765,25 @@
 
 Unix domain sockets
 CONFIG_UNIX
-  This includes Unix domain sockets, the standard Unix mechanism for
-  establishing and accessing network connections. Many commonly used
-  programs such as the X Window system and syslog use these sockets
-  even if your machine is not connected to any network. Unless you are
-  working on an embedded system or something similar, you therefore
-  definitely want to say Y here.
+  If you say Y here, you will include support for Unix domain sockets;
+  sockets are the standard Unix mechanism for establishing and
+  accessing network connections. Many commonly used programs such as
+  the X Window system and syslog use these sockets even if your
+  machine is not connected to any network. Unless you are working on
+  an embedded system or something similar, you therefore definitely
+  want to say Y here.
 
-  The socket support is also available as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want). The module will be called unix.o. If you want to compile it
-  as a module, say M here and read Documentation/modules.txt. If you
-  try building this as a module and you have said Y to "Kernel module
-  loader support" above, be sure to add 'alias net-pf-1 unix' to your
-  /etc/conf.modules file.
+  However, the socket support 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. The module will be called
+  unix.o. If you try building this as a module and you have said Y to
+  "Kernel module loader support" above, be sure to add 'alias net-pf-1
+  unix' to your /etc/conf.modules file. Note that several important
+  services won't work correctly if you say M here and then neglect to
+  load the module.
 
-  If unsure, say Y.
+  Say Y unless you know what you are doing.
 
 The IPv6 protocol
 CONFIG_IPV6
@@ -2894,14 +2923,14 @@
   for details (to browse the WWW, you need to have access to a machine
   on the Internet that has a program like lynx or netscape). EtherTalk
   is the name used for AppleTalk over Ethernet and the cheaper and
-  slower LocalTalk is AppleTalk over a proprietary apple network using
+  slower LocalTalk is AppleTalk over a proprietary Apple network using
   serial links. EtherTalk and LocalTalk are fully supported by Linux.
-  The NET-2-HOWTO, available via FTP (user: anonymous) in
-  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO contains valuable
-  information as well.
 
   General information about how to connect Linux, Windows machines and
   Macs is on the WWW at http://www.eats.com/linux_mac_win.html
+  The NET-3-HOWTO, available via FTP (user: anonymous) in
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO contains valuable
+  information as well.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -3475,7 +3504,7 @@
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. The
   SCSI-Programming-HOWTO contains information about how to add or
   remove an SCSI device from a running Linux machine without
-  rebooting. 
+  rebooting.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -3608,11 +3637,13 @@
 
 Adaptec AHA152X/2825 support
 CONFIG_SCSI_AHA152X
-  This is support for the AVA-1505 (irq etc must be manually specified), 
-  AHA-1510, AHA-1520, AHA-1522, and AHA-2825 SCSI host adapters. It is 
-  explained in section 3.3 of the SCSI-HOWTO, available via FTP 
-  (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You 
-  might also want to read the comments at the top of 
+  This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
+  SCSI host adapters. It also works for the AVA-1505, but the IRQ etc.
+  must be manually specified in this case.
+
+  It is explained in section 3.3 of the SCSI-HOWTO, available via FTP
+  (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You
+  might also want to read the comments at the top of
   drivers/scsi/aha152x.c.
 
   This driver is also available as a module ( = code which can be
@@ -3650,25 +3681,31 @@
 Adaptec AIC7xxx chipset SCSI controller support
 CONFIG_SCSI_AIC7XXX
   This is support for the various aic7xxx based Adaptec SCSI
-  controllers. These include the 274x EISA cards; 284x VLB cards; 2902,
-  2910, 293x, 294x, 394x, 3985 and several other PCI and motherboard based
-  SCSI controllers from Adaptec.  It does not support the AAA-13x RAID
-  controllers from Adaptec, nor will it likely ever support them.  It
-  does not support the 2920 cards from Adaptec that use the Future Domain
-  SCSI controller chip.  For those cards, you need the "Future Domain
-  16xx SCSI support" driver.
+  controllers. These include the 274x EISA cards; 284x VLB cards;
+  2902, 2910, 293x, 294x, 394x, 3985 and several other PCI and
+  motherboard based SCSI controllers from Adaptec. It does not support
+  the AAA-13x RAID controllers from Adaptec, nor will it likely ever
+  support them. It does not support the 2920 cards from Adaptec that
+  use the Future Domain SCSI controller chip. For those cards, you
+  need the "Future Domain 16xx SCSI support" driver.
 
   In general, if the controller is based on an Adaptec SCSI controller
-  chip from the aic777x series or the aic78xx series, it should work.  The
-  only exception is the 7810 which is specifically not supported (that's the
-  RAID controller chip on the AAA-13x cards).
+  chip from the aic777x series or the aic78xx series, this driver
+  should work. The only exception is the 7810 which is specifically
+  not supported (that's the RAID controller chip on the AAA-13x
+  cards).
+
+  Note that the AHA2920 SCSI host adapter is *not* supported by this
+  driver; choose "Future Domain 16xx SCSI support" instead if you have
+  one of those.
 
   Information on the configuration options for this controller can be
   found by checking the help file for each of the available
   configuration options. You should read drivers/scsi/README.aic7xxx
   at a minimum before contacting the maintainer with any questions.  
   The SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO can also be of great help.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO can also be of great
+  help.
 
   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),
@@ -3769,16 +3806,15 @@
 
 EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support
 CONFIG_SCSI_EATA_DMA
-  This driver is obsolete. You should normally be using the generic EATA
-  driver for this hardware.
-
   This is support for the EATA-DMA protocol compliant SCSI Host
   Adapters like the SmartCache III/IV, SmartRAID controller families
-  and the DPT PM2011B and PM2012B controllers. Note that there is
-  also another driver for the same hardware: "EATA ISA/EISA/PCI
-  support". You should only say Y to one of them. Please read the
-  SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
+  and the DPT PM2011B and PM2012B controllers. 
+
+  Note that this driver is obsolete; if you have one of the above SCSI
+  Host Adapters, you should normally say N here and Y to "EATA
+  ISA/EISA/PCI support", below. Please read the SCSI-HOWTO, available
+  via FTP (user: anonymous) at
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -3821,19 +3857,19 @@
 CONFIG_SCSI_U14_34F_LINKED_COMMANDS
   This option enables elevator sorting for all probed SCSI disks and 
   CDROMs. It definitely reduces the average seek distance when doing
-  random seeks, but this does not necessarily results in a noticeable
+  random seeks, but this does not necessarily result in a noticeable
   performance improvement: your mileage may vary...
+  
   The safe answer is N.
 
 maximum number of queued commands
 CONFIG_SCSI_U14_34F_MAX_TAGS
-  This specifies how many SCSI commands can be maximally queued for each
-  probed SCSI device. You should reduce the default value of 8 only if
-  you have disks with buggy or limited tagged command support.
+  This specifies how many SCSI commands can be maximally queued for
+  each probed SCSI device. You should reduce the default value of 8
+  only if you have disks with buggy or limited tagged command support.
   Minimum is 2 and maximum is 14. This value is also the window size
-  used by the elevator sorting option above.
-  The effective value used by the driver for each probed SCSI device is 
-  reported at boot time.
+  used by the elevator sorting option above. The effective value used
+  by the driver for each probed SCSI device is reported at boot time.
 
 Future Domain 16xx SCSI/AHA-2920A support
 CONFIG_SCSI_FUTURE_DOMAIN
@@ -3844,10 +3880,10 @@
   It is explained in section 3.7 of the SCSI-HOWTO, available via FTP
   (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
-  NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip and
-  should use the aic7xxx driver (CONFIG_SCSI_AIC7XXX).  The Future Domain
-  driver works with the older Adaptec AHA-2920A boards with a Future Domain
-  chip on them.
+  NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip
+  and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI
+  controller support"). This Future Domain driver works with the older
+  Adaptec AHA-2920A boards with a Future Domain chip on them.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -3857,9 +3893,10 @@
 Future Domain MCS-600/700 SCSI support
 CONFIG_SCSI_FD_MCS
  This is support for Future Domain MCS 600/700 MCA SCSI adapters. Some
- PS/2s are also equipped with IBM Fast SCSI Adapter/A which is an OEM
- of the MCS 700. This driver also supports Reply SB16/SCSI card (the 
- SCSI part). It supports multiple adapters in the same system.
+ PS/2 computers are equipped with IBM Fast SCSI Adapter/A which is
+ identical to the MCS 700 and hence also supported by this driver.
+ This driver also supports the Reply SB16/SCSI card (the SCSI part).
+ It supports multiple adapters in the same system.
 
 Generic NCR5380/53c400 SCSI support
 CONFIG_SCSI_GENERIC_NCR5380
@@ -3892,16 +3929,17 @@
 
 NCR53c7,8xx SCSI support
 CONFIG_SCSI_NCR53C7xx
-  This is the 53c7 and 8xx NCR family of SCSI controllers, not to be
-  confused with the NCR 5380 controllers. It is explained in section
-  3.8 of the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://metalab.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/53c7,8xx.h.
+  This is a driver for the 53c7 and 8xx NCR family of SCSI
+  controllers, not to be confused with the NCR 5380 controllers. It is
+  explained in section 3.8 of the SCSI-HOWTO, available via FTP (user:
+  anonymous) at ftp://metalab.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/53c7,8xx.h. Please read drivers/scsi/README.ncr53c7xx
+  for the available boot time command line options.
 
   Note: there is another driver for the 53c8xx family of controllers
-  ("NCR53C8XX SCSI support" below). You cannot say Y to both of them;
-  you can say M to both and build them as modules, but only one may be
+  ("NCR53C8XX SCSI support" below). If you want to use them both, you
+  need to say M to both and build them as modules, but only one may be
   active at a time. If you have a 53c8xx board, it's better to use the
   other driver.
 
@@ -3945,8 +3983,8 @@
   supports FAST-40 transfers with Ultra2 LVD devices.
 
   Note: there is another driver for the 53c8xx family of controllers
-  ("NCR53c7,8xx SCSI support" above). You cannot say Y to both of
-  them; you can say M to both and build them as modules, but only one
+  ("NCR53c7,8xx SCSI support" above). If you want to use them both,
+  you need to say M to both and build them as modules, but only one
   may be active at a time. If you have a 53c8xx board, it's best to
   use this driver.
 
@@ -4137,10 +4175,10 @@
   controller based on the NCR 53C94.  This driver will allow use of
   the controller on the 3550, and very possibly others.   
 
-  If you want to compile this as a module (= code which can be inserted
-  and removed from the running kernel whenever you want),
-  say M here and read Documentation/modules.txt.  The module will be
-  called mca_53c9x.o.
+  If you want to compile this as a module (= code which can be
+  inserted and removed from the running kernel whenever you want), say
+  M here and read Documentation/modules.txt. The module will be called
+  mca_53c9x.o.
  
 Always IN2000 SCSI support
 CONFIG_SCSI_IN2000
@@ -4158,18 +4196,7 @@
 CONFIG_SCSI_INITIO
   This is support for the Initio 91XXU(W) SCSI host adapter.
   Please read the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://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. The module will be
-  called initio.o
-
-Initio 91XXU(W) SCSI support
-CONFIG_SCSI_INITIO
-  This is support for the Initio 91XXU(W) SCSI host adapter.
-  Please read the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.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),
@@ -4224,14 +4251,18 @@
 
 Qlogic FAS SCSI support
 CONFIG_SCSI_QLOGIC_FAS
-  This driver works only with the ISA, VLB, and PCMCIA versions of the
-  Qlogic FastSCSI! cards as well as any other card based on the FASXX
-  chip (including the Control Concepts SCSI/IDE/SIO/PIO/FDC cards); it
-  does NOT support the PCI version. The PCI versions are supported by
-  the Qlogic ISP driver though. Information about this driver is
-  contained in drivers/scsi/README.qlogicfas. You should also read
-  the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
+  This is a driver for the ISA, VLB, and PCMCIA versions of the Qlogic
+  FastSCSI! cards as well as any other card based on the FASXX chip
+  (including the Control Concepts SCSI/IDE/SIO/PIO/FDC cards).
+
+  This driver does NOT support the PCI versions of these cards. The
+  PCI versions are supported by the Qlogic ISP driver ("Qlogic ISP
+  SCSI support"), below.
+
+  Information about this driver is contained in
+  drivers/scsi/README.qlogicfas. You should also read the SCSI-HOWTO,
+  available via FTP (user: anonymous) at
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -4244,7 +4275,8 @@
   IQ-PCI-10, IQ_PCI-D) except for the PCI-basic card. (This latter
   card is supported by the "AM53/79C974 PCI SCSI" driver). 
 
-  If you say Y here, make sure to say Y to "PCI BIOS support" as well.
+  If you say Y here, make sure to say Y to choose "BIOS" at the
+  question "PCI access mode".
 
   Please read the file drivers/scsi/README.qlogicisp. You should also
   read the SCSI-HOWTO, available via FTP (user: anonymous) at
@@ -4310,14 +4342,25 @@
   want). The module will be called wd7000.o. If you want to compile it
   as a module, say M here and read Documentation/modules.txt.
 
+ACARD SCSI support
+CONFIG_SCSI_ACARD
+  This driver supports the ACARD 870U/W SCSI host adapter.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called atp870u.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
 EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support
 CONFIG_SCSI_EATA
-  This driver supports all the EATA/DMA-compliant SCSI host adapters.
-  DPT ISA and all EISA i/o addresses are probed looking for the "EATA"
-  signature. If you said Y to "PCI support", the addresses of all the 
-  PCI SCSI controllers reported by the PCI subsystem are probed as well.
-  You want to read the start of drivers/scsi/eata.c and the SCSI-HOWTO,
-  available via FTP (user: anonymous) at 
+  This driver supports all EATA/DMA-compliant SCSI host adapters. DPT
+  ISA and all EISA i/o addresses are probed looking for the "EATA"
+  signature. If you chose "BIOS" at the question "PCI access mode",
+  the addresses of all the PCI SCSI controllers reported by the PCI
+  subsystem are probed as well.
+
+  You want to read the start of drivers/scsi/eata.c and the
+  SCSI-HOWTO, available via FTP (user: anonymous) at
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Note that there is also another driver for the same hardware
@@ -4333,26 +4376,25 @@
   This is a feature of SCSI-2 which improves performance: the host
   adapter can send several SCSI commands to a device's queue even if
   previous commands haven't finished yet. Most EATA adapters negotiate
-  this feature automatically with the device, even if your answer is N.
-  The safe answer is N.
+  this feature automatically with the device, even if your answer is
+  N. The safe answer is N.
         
 enable elevator sorting
 CONFIG_SCSI_EATA_LINKED_COMMANDS
   This option enables elevator sorting for all probed SCSI disks and 
-  CDROMs. It definetly reduces the average seek distance when doing
+  CDROMs. It definitely reduces the average seek distance when doing
   random seeks, but this does not necessarily result in a noticeable
   performance improvement: your mileage may vary...
   The safe answer is N.
 
 maximum number of queued commands
 CONFIG_SCSI_EATA_MAX_TAGS
-  This specifies how many SCSI commands can be maximally queued for each
-  probed SCSI device. You should reduce the default value of 16 only if
-  you have disks with buggy or limited tagged command support.
+  This specifies how many SCSI commands can be maximally queued for
+  each probed SCSI device. You should reduce the default value of 16
+  only if you have disks with buggy or limited tagged command support.
   Minimum is 2 and maximum is 62. This value is also the window size
-  used by the elevator sorting option above.
-  The effective value used by the driver for each probed SCSI device is 
-  reported at boot time.
+  used by the elevator sorting option above. The effective value used
+  by the driver for each probed SCSI device is reported at boot time.
 
 NCR53c406a SCSI support
 CONFIG_SCSI_NCR53C406A
@@ -4376,7 +4418,8 @@
   
   Note that this driver does NOT support Tekram DC390W/U/F, which are
   based on NCR/Symbios chips. Use "NCR53C8XX SCSI support" for those.
-  Also note that there is another generic Am53C974 driver.
+  Also note that there is another generic Am53C974 driver,
+  "AM53/79C974 PCI SCSI support" below. You can pick either one.
 
   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),
@@ -4406,13 +4449,24 @@
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, is for you.
 
   Note that there is another driver for AM53C974 based adapters:
-  "Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support", above.
+  "Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support", above. You
+  can pick either one.
 
   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. The module will be
   called AM53C974.o.
 
+AMI MegaRAID support
+CONFIG_SCSI_MEGARAID
+  This driver supports the AMI MegaRAID 428 and 438 (and maybe 466)
+  SCSI host adapters. 
+
+  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. The module will be
+  called megaraid.o.
+
 GDT SCSI Disk Array Controller support
 CONFIG_SCSI_GDTH
   This is a driver for all SCSI Disk Array Controllers (EISA/ISA/PCI) 
@@ -4424,36 +4478,59 @@
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.
 
-IOMEGA Parallel Port ZIP drive SCSI support
+IOMEGA parallel port (ppa - older drives)
 CONFIG_SCSI_PPA
-  This driver supports the parallel port version of IOMEGA's ZIP drive
-  (a 100 MB removable media device). For more information about this
-  driver and how to use it you should read the file
-  drivers/scsi/README.ppa. You should also read the SCSI-HOWTO, which
-  is available via FTP (user: anonymous) from
+  This driver supports older versions of IOMEGA's parallel port ZIP
+  drive (a 100 MB removable media device).
+
+  Note that you can say N here if you have the SCSI version of the ZIP
+  drive: it will be supported automatically if you said Y to the
+  generic "SCSI disk support", above.
+
+  If you have the ZIP Plus drive or a more recent parallel port ZIP
+  drive (if the supplied cable with the drive is labeled "AutoDetect")
+  then you should say N here and Y to "IOMEGA parallel port (imm -
+  newer drives)", below.
+
+  For more information about this driver and how to use it you should
+  read the file drivers/scsi/README.ppa. You should also read the
+  SCSI-HOWTO, which is available via FTP (user: anonymous) from
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you use this driver,
   you will still be able to use the parallel port for other tasks,
   such as a printer; it is safe to compile both drivers into the
   kernel.
 
+  This driver is also available as a module which can be inserted in
+  and removed from the running kernel whenever you want. To compile
+  this driver as a module, say M here and read
+  Documentation/modules.txt. The module will be called ppa.o. 
+
+IOMEGA parallel port (imm - newer drives)
+CONFIG_SCSI_IMM
+  This driver supports newer versions of IOMEGA's parallel port ZIP
+  drive (a 100 MB removable media device).
+
   Note that you can say N here if you have the SCSI version of the ZIP
   drive: it will be supported automatically if you said Y to the
   generic "SCSI disk support", above.
 
-  The ZIP Plus drive is supported by the imm driver, also more recent
-  parallel port ZIP drives use an imm compatible interface. If the
-  supplied cable with the drive is labeled "AutoDetect" then you will
-  need the imm driver.
+  If you have the ZIP Plus drive or a more recent parallel port ZIP
+  drive (if the supplied cable with the drive is labeled "AutoDetect")
+  then you should say Y here; if you have an older ZIP drive, say N
+  here and Y to "IOMEGA Parallel Port (ppa - older drives)", above.
+
+  For more information about this driver and how to use it you should
+  read the file drivers/scsi/README.ppa. You should also read the
+  SCSI-HOWTO, which is available via FTP (user: anonymous) from
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you use this driver,
+  you will still be able to use the parallel port for other tasks,
+  such as a printer; it is safe to compile both drivers into the
+  kernel.
 
   This driver is also available as a module which can be inserted in
   and removed from the running kernel whenever you want. To compile
   this driver as a module, say M here and read
-  Documentation/modules.txt. The module will be called ppa.o. 
-
-IOMEGA Parallel Port ZIP drive SCSI support
-CONFIG_SCSI_IMM
-  All "new and improved" parallel port to SCSI interface from Iomega.
-  Please read the comments for the ppa driver for further information
+  Documentation/modules.txt. The module will be called imm.o. 
 
 Force the Iomega ZIP drivers to use EPP-16
 CONFIG_SCSI_IZIP_EPP16
@@ -4463,19 +4540,20 @@
 
   Some parallel port chipsets are slower than their motherboard, and
   so we have to control the state of the chipset's FIFO queue every
-  now and then to avoid data loss. This will be done if you say Y here. 
+  now and then to avoid data loss. This will be done if you say Y
+  here.
   
   Generally, saying Y is the safe option and slows things down a bit.
 
 Assume slow parallel port control register
 CONFIG_SCSI_IZIP_SLOW_CTR
-  Some parallel ports are known to have excessive delays between changing
-  the parallel port control register and good data being available on
-  the parallel port data/status register. This option forces a small delay
-  (1.0 usec to be exact) after changing the control register to let things
-  settle out. Enabling this option may result in a big drop in performance
-  but some very old parallel ports (found in 386 vintage machines) will
-  not work properly.
+  Some parallel ports are known to have excessive delays between
+  changing the parallel port control register and good data being
+  available on the parallel port data/status register. This option
+  forces a small delay (1.0 usec to be exact) after changing the
+  control register to let things settle out. Enabling this option may
+  result in a big drop in performance but some very old parallel ports
+  (found in 386 vintage machines) will not work properly.
 
   Generally, saying N is fine.
 
@@ -4564,11 +4642,11 @@
 
 Network device support?
 CONFIG_NETDEVICES
-  You can say N here if you don't intend to connect to any other
-  computer at all or if all your connections will be over a telephone
-  line with a modem either via UUCP (UUCP is a protocol to forward
-  mail and news between unix hosts over telephone lines; read the
-  UUCP-HOWTO, available via FTP (user: anonymous) in
+  You can say N here if you don't intend to connect your Linux box to
+  any other computer at all or if all your connections will be over a
+  telephone line with a modem either via UUCP (UUCP is a protocol to
+  forward mail and news between unix hosts over telephone lines; read
+  the UUCP-HOWTO, available via FTP (user: anonymous) in
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO) or dialing up a shell
   account or a BBS, even using term (term is a program which gives you
   almost full Internet connectivity if you have a regular dial up
@@ -4588,9 +4666,9 @@
   newer replacement for SLIP) or PLIP (Parallel Line Internet Protocol
   is mainly used to create a mini network by connecting the parallel
   ports of two local machines) or AX.25/KISS (protocol for sending
-  Internet traffic over radio links).
+  Internet traffic over amateur radio links).
 
-  Make sure to read the NET-2-HOWTO. Eventually, you will have to read
+  Make sure to read the NET-3-HOWTO. Eventually, you will have to read
   Olaf Kirch's excellent and free book "Network Administrator's
   Guide", to be found in ftp://metalab.unc.edu:/pub/Linux/docs/LDP. If
   unsure, say Y.
@@ -4631,7 +4709,7 @@
   ftp://metalab.unc.edu/pub/Linux/system/network/serial/ ) which
   allows you to use SLIP over a regular dial up shell connection. If
   you plan to use SLiRP, make sure to say Y to CSLIP, below. The
-  NET-2-HOWTO, available via FTP (user: anonymous) in
+  NET-3-HOWTO, available via FTP (user: anonymous) in
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, explains how to
   configure SLIP. Note that you don't need this option if you just
   want to run term (term is a program which gives you almost full
@@ -4658,7 +4736,7 @@
   anonymous) from
   ftp://metalab.unc.edu/pub/Linux/system/network/serial/) which allows
   you to use SLIP over a regular dial up shell connection, you
-  definitely want to say Y here. The NET-2-HOWTO, available via FTP
+  definitely want to say Y here. The NET-3-HOWTO, available via FTP
   (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO,
   explains how to configure CSLIP. This won't enlarge your kernel.
 
@@ -4760,8 +4838,9 @@
   radio frequencies 900 MHz and 2.4 GHz.
   
   This driver support the ISA version of the WaveLAN card. A separate
-  driver for the pcmcia hardware is available in David Hinds'
-  pcmcia-cs package (see the file Documentation/Changes for location).
+  driver for the PCMCIA (PC-card) hardware is available in David
+  Hinds' pcmcia-cs package (see the file Documentation/Changes for
+  location).
 
   If you want to use an ISA WaveLAN card under Linux, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
@@ -4851,7 +4930,7 @@
   If you want to use PLIP, say Y and read the PLIP mini-HOWTO,
   available via FTP (user: anonymous) in
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini as well as the
-  NET-2-HOWTO in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that
+  NET-3-HOWTO in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that
   the PLIP protocol was changed and this PLIP driver won't work
   together with the PLIP support in Linux versions 1.0.x. This option
   enlarges your kernel by about 8 KB.
@@ -4867,11 +4946,15 @@
   If you have two serial connections to some other computer (this
   usually requires two modems and two telephone lines) and you use
   SLIP (the protocol for sending Internet traffic over telephone
-  lines) or PPP (a better SLIP) on them, you can make them behave
-  like one double speed connection using this driver. Naturally, this
-  has to be supported at the other end as well, either with a similar
-  EQL Linux driver or with a Livingston Portmaster 2e. Say Y if you
-  want this and read Documentation/networking/eql.txt. 
+  lines) or PPP (a better SLIP) on them, you can make them behave like
+  one double speed connection using this driver. Naturally, this has
+  to be supported at the other end as well, either with a similar EQL
+  Linux driver or with a Livingston Portmaster 2e. 
+
+  Say Y if you want this and read Documentation/networking/eql.txt.
+  You may also want to read section 6.2 of the NET-3-HOWTO, available
+  via FTP (user: anonymous) from
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -4988,16 +5071,18 @@
   With relatively inexpensive WAN interface cards available on the
   market, a perfectly usable router can be built for less than half
   the price of an external router. If you have one of those cards and
-  wish to use your Linux box as a WAN router, say Y here and to the
-  WAN driver for your card, below. You will also need a wan-tools
-  package available via FTP (user: anonymous) from
+  wish to use your Linux box as a WAN router, say Y here and also to
+  the WAN driver for your card, below. You will then need the
+  wan-tools package which is available via FTP (user: anonymous) from
   ftp://ftp.sangoma.com. Read Documentation/networking/wan-router.txt
   for more information.
 
-  WAN routing support is always built as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want). The module is called wanrouter.o. For general information
-  about modules read Documentation/modules.txt.
+  The WAN routing support is also available as a module called
+  wanrouter.o ( = 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.
+
+  If unsure, say N.
 
 Fast switching (read help!)
 CONFIG_NET_FASTROUTE
@@ -5203,30 +5288,42 @@
 Comtrol Hostess SV-11 support
 CONFIG_HOSTESS_SV11
   This is a network card for low speed synchronous serial links, at
-  up to 256Kbits. It supports both PPP and Cisco HDLC
+  up to 256Kbps. It supports both PPP and Cisco HDLC.
+  
   At this point, the driver can only be compiled as a module.
 
 COSA/SRP sync serial boards support
 CONFIG_COSA
-  This is a driver for COSA and SRP synchronous serial boards.
-  These boards enable to connect synchronous serial devices (for
-  example base-band modems, or any other device with the X.21, V.24,
-  V.35 or V.36 interface) to your Linux box. The cards can work
-  as the character device, synchronous PPP network device, or the Cisco
-  HDLC network device.
+  This is a driver for COSA and SRP synchronous serial boards. These
+  boards allow to connect synchronous serial devices (for example
+  base-band modems, or any other device with the X.21, V.24, V.35 or
+  V.36 interface) to your Linux box. The cards can work as the
+  character device, synchronous PPP network device, or the Cisco HDLC
+  network device.
 
   To actually use the COSA or SRP board, you will need user-space
-  utilities for downloading the firmware to the cards and to set 
-  them up. Look at the http://www.fi.muni.cz/~kas/cosa/ for more
+  utilities for downloading the firmware to the cards and to set them
+  up. Look at the http://www.fi.muni.cz/~kas/cosa/ for more
   information about the cards (including the pointer to the user-space
   utilities). You can also read the comment at the top of the
-  drivers/net/cosa.c for details about the cards and the driver itself.
+  drivers/net/cosa.c for details about the cards and the driver
+  itself.
 
   The driver will be compiled as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
   The module will be called cosa.o. For general information about
   modules read Documentation/modules.txt.
 
+Red Creek Hardware VPN (EXPERIMENTAL)
+CONFIG_RCPCI
+  This is a driver for hardware which provides a Virtual Private
+  Network (VPN). Say Y if you have it.
+
+  This code is also available as a module called rcpci.o ( = 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.
+  
 WAN Drivers
 CONFIG_WAN_DRIVERS
   Say Y to this option if your Linux box contains a WAN card and you
@@ -5517,7 +5614,6 @@
   say M here and read Documentation/modules.txt. This is recommended.
   The module will be called acenic.o.
 
-
 AMD LANCE and PCnet (AT1500 and NE2100) support
 CONFIG_LANCE
   If you have a network (Ethernet) card of this type, say Y and read
@@ -5525,6 +5621,11 @@
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Some LinkSys cards are
   of this type.
 
+  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. This is recommended.
+  The module will be called lance.o.
+
 3COM cards
 CONFIG_NET_VENDOR_3COM
   If you have a network (Ethernet) card belonging to this class, say Y
@@ -6151,11 +6252,11 @@
   one of those, say Y and read the Ethernet-HOWTO, available via FTP
   (user: anonymous) from ftp://metalab.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 on the FTP site
-  (user: anonymous) ftp://cb-iris.stanford.edu/pub/pcmcia and say N
-  here.
+  If you want to plug a network (or some other) card into the PCMCIA
+  (or PC-card) slot of your laptop instead (PCMCIA is the standard for
+  credit card size extension cards used by all modern laptops), you
+  need the pcmcia-cs package (location contained in the file
+  Documentation/Changes) and you can say N here.
 
   Laptop users should read the Linux Laptop home page at
   http://www.cs.utexas.edu/users/kharker/linux-laptop/ (to browse the
@@ -6286,6 +6387,16 @@
   under Linux, say Y here (you must also remember to enable the driver
   for your HIPPI card below). Most people will say N here.
   
+CERN HIPPI PCI adapter support
+CONFIG_CERN_HIPPI
+  Say Y here if this is your PCI HIPPI network card.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called cern_hippi.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt. If unsure,
+  say N.
+
 Essential RoadRunner HIPPI PCI adapter support
 CONFIG_ROADRUNNER
   Say Y here if this is your PCI HIPPI network card.
@@ -6748,7 +6859,7 @@
 vfat fs support
 CONFIG_VFAT_FS
   This option provides support for normal Windows filesystems with
-  long filenames. That includes noncompressed FAT-based filesystems
+  long filenames. That includes non-compressed FAT-based filesystems
   used by Windows 95, Windows 98, Windows NT 4.0, and mtools. 
 
   You cannot use the VFAT filesystem for your Linux root partition
@@ -6795,21 +6906,24 @@
   of the system. "Virtual" means that it doesn't take up any space on
   your hard disk: the files are created on the fly by the kernel when
   you try to access them. Also, you cannot read the files with older
-  version of the program less: you need to use more or cat. The
-  filesystem is explained in the Kernel Hacker's Guide at
-  http://www.redhat.com:8080/HyperNews/get/khg.html on the WWW (to
-  browse the WWW, you need to have access to a machine on the Internet
-  that has a program like lynx or netscape), and also on the proc(8)
-  manpage ("man 8 proc").
+  version of the program less: you need to use more or cat. 
 
   It's totally cool; for example, "cat /proc/interrupts" gives
   information about what the different IRQs are used for at the moment
   (there is a small number of Interrupt ReQuest lines in your computer
   that are used by the attached devices to gain the CPU's attention --
   often a source of trouble if two devices are mistakenly configured
-  to use the same IRQ). This option will enlarge your kernel by about
-  18 kB. Several programs depend on this, so everyone should say Y
-  here.
+  to use the same IRQ). 
+
+  The /proc filesystem is explained in the file
+  Documentation/proc.txt, in the Kernel Hacker's Guide at
+  http://www.redhat.com:8080/HyperNews/get/khg.html on the WWW (to
+  browse the WWW, you need to have access to a machine on the Internet
+  that has a program like lynx or netscape), and also on the proc(8)
+  manpage ("man 8 proc").
+
+  This option will enlarge your kernel by about 18 KB. Several
+  programs depend on this, so everyone should say Y here.
 
 NFS filesystem support
 CONFIG_NFS_FS
@@ -6837,11 +6951,11 @@
   say M here and read Documentation/modules.txt. 
 
   If you are configuring a diskless machine which will mount its root
-  filesystem over NFS at boot time, say Y here and to "Root file
-  system on NFS" and to "IP: kernel level autoconfiguration". You
-  cannot compile this driver as a module in this case. There are two
-  packages designed for booting diskless machines over the net:
-  netboot and etherboot, both available via FTP (user: anonymous) from
+  filesystem over NFS at boot time, say Y here and to "IP: kernel
+  level autoconfiguration" above and to "Root file system on NFS"
+  below. You cannot compile this driver as a module in this case.
+  There are two packages designed for booting diskless machines over
+  the net: netboot and etherboot, both available via FTP from
   ftp://metalab.unc.edu/pub/Linux/system/boot/ethernet/ .
 
   If you don't know what all this is about, say N.
@@ -6945,7 +7059,7 @@
   tar" or preferably "info tar"). Note also that this option has
   nothing whatsoever to do with the option "System V IPC". Read about
   the System V filesystem in Documentation/filesystems/sysv-fs.txt.
-  Saying Y here will enlarge your kernel by about 34 kB.
+  Saying Y here will enlarge your kernel by about 34 KB.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -7007,7 +7121,9 @@
 QNX filesystem support (EXPERIMENTAL)
 CONFIG_QNX4FS_FS  
   This is the filesystem used by the operating system QNX 4. Say Y if
-  you intend to mount QNX hard disks or floppies.
+  you intend to mount QNX hard disks or floppies. Unless you say Y to
+  "QNXFS read-write support" below, you will only be able to read
+  these filesystems.
 
   This filesystem support is also available as a module ( = code which
   can be inserted in and removed from the running kernel whenever you
@@ -7016,6 +7132,10 @@
 
   If unsure, say N.
 
+QNXFS read-write support (FOR TESTING ONLY)
+CONFIG_QNX4FS_RW
+  Say Y if you want to test write support for QNX filesystems.
+
 Kernel automounter support
 CONFIG_AUTOFS_FS
   The automounter is a tool to automatically mount remote filesystems
@@ -7041,7 +7161,8 @@
   OpenBSD and NeXTstep) use a filesystem called UFS. Some System V
   Unixes can create and mount hard disk partitions and diskettes using
   this filesystem as well. Saying Y here will allow you to read from
-  these partitions and diskettes.
+  these partitions; if you also want to write to them, say Y to the
+  experimental "UFS filesystem write support", below.
 
   If you only intend to mount files from some other Unix over the
   network using NFS, you don't need the UFS filesystem support (but
@@ -7063,44 +7184,42 @@
 
   If you haven't heard about all of this before, it's safe to say N.
 
-UFS filesystem write support
+UFS filesystem write support (experimental)
 CONFIG_UFS_FS_WRITE
-  You will be able to write to 4.4BSD (e.g. FreeBSD, NetBSD and
-  OpenBSD) and SunOS partitions and diskettes if you say Y to this
-  option in addition to "UFS filesystem support", above.
+  Say Y here if you want to try writing to UFS partitions. This is
+  experimental, so you should back up your UFS partitions beforehand.
 
 BSD disklabel (FreeBSD partition tables) support
 CONFIG_BSD_DISKLABEL
   FreeBSD uses its own hard disk partition scheme on your PC. It
   requires only one entry in the primary partition table of your disk
   and manages it similarly to DOS extended partitions, putting in its
-  first sector a new partition table in disklabel format. Saying Y
+  first sector a new partition table in BSD disklabel format. Saying Y
   here allows you to read these disklabels and further mount FreeBSD
-  partitions read-only from within Linux if you have also said Y to
-  "UFS filesystem support", above. If you don't know what all this
-  is about, say N.
+  partitions from within Linux if you have also said Y to "UFS
+  filesystem support", above. If you don't know what all this is
+  about, say N.
 
 SMD disklabel (Sun partition tables) support
 CONFIG_SMD_DISKLABEL
   Like most systems, SunOS uses its own hard disk partition table
   format, incompatible with all others. Saying Y here allows you to
-  read these partition tables and further mount SunOS disks read-only
-  from within Linux if you have also said Y to "UFS filesystem
-  support", above. This is mainly used to carry data from a SPARC
-  under SunOS to your Linux box via a removable medium like
-  magneto-optical or ZIP drives; note however that a good portable way
-  to transport files and directories between unixes (and even other
-  operating systems) is given by the tar program ("man tar" or
-  preferably "info tar"). If you don't know what all this is about,
-  say N.
+  read these partition tables and further mount SunOS disks from
+  within Linux if you have also said Y to "UFS filesystem support",
+  above. This is mainly used to carry data from a SPARC under SunOS to
+  your Linux box via a removable medium like magneto-optical or ZIP
+  drives; note however that a good portable way to transport files and
+  directories between unixes (and even other operating systems) is
+  given by the tar program ("man tar" or preferably "info tar"). If
+  you don't know what all this is about, say N.
 
 Solaris (x86) partition table support
 CONFIG_SOLARIS_X86_PARTITION
   Like most systems, Solaris x86 uses its own hard disk partition
   table format, incompatible with all others. Saying Y here allows you
   to read these partition tables and further mount Solaris x86 disks
-  read-only from within Linux if you have also said Y to "UFS
-  filesystem support", above.
+  from within Linux if you have also said Y to "UFS filesystem
+  support", above.
 
 ADFS filesystem support (read only) (EXPERIMENTAL)
 CONFIG_ADFS_FS
@@ -7130,27 +7249,29 @@
   to acquire a pseudo terminal, a process opens /dev/ptmx; the number
   of the pseudo terminal is then made available to the process and the
   pseudo terminal slave can be accessed as /dev/pts/<number>. What was
-  traditionally /dev/ttyp2 will then be /dev/pts/2, for example. The
-  GNU C library glibc 2.1 contains the requisite support for this mode
-  of operation; you also need clients that use the Unix98 API.
+  traditionally /dev/ttyp2 will then be /dev/pts/2, for example. 
+
+  The GNU C library glibc 2.1 contains the requisite support for this
+  mode of operation; you also need client programs that use the Unix98
+  API.
 
-Unixware slices support (EXPERIMENTAL)
+UnixWare slices support (EXPERIMENTAL)
 CONFIG_UNIXWARE_DISKLABEL
-  Like some systems, Unixware uses, except DOS-like partition table,
-  its own slice table inside a partition (VTOC - Virtual Table of
-  Contents). Its format is incompatible with all other OSes. Saying Y
-  here allows you to read VTOC and further mount Unixware partitions
-  read-only from within Linux if you have also said Y to "UFS 
-  filesystem support" or "System V and Coherent filesystem support", 
-  above.
+  Like some systems, UnixWare uses its own slice table inside a
+  partition (VTOC - Virtual Table of Contents). Its format is
+  incompatible with all other OSes. Saying Y here allows you to read
+  VTOC and further mount UnixWare partitions read-only from within
+  Linux if you have also said Y to "UFS filesystem support" or "System
+  V and Coherent filesystem support", above.
 
-  This is mainly used to carry data from a Unixware box to your
+  This is mainly used to carry data from a UnixWare box to your
   Linux box via a removable medium like magneto-optical, ZIP or
   removable IDE drives. Note, however, that a good portable way to
   transport files and directories between unixes (and even other
   operating systems) is given by the tar program ("man tar" or
-  preferably "info tar"). If you don't know what all this is about,
-  say N.
+  preferably "info tar"). 
+
+  If you don't know what all this is about, say N.
 
 Macintosh partition map support
 CONFIG_MAC_PARTITION
@@ -7289,29 +7410,6 @@
   servers. Do not say Y if security is primary for you because root
   can read your session key (from /proc/kcore).
 
-nls: Native language codepages and Unicode support
-CONFIG_NLS
-  This is required by the FAT and NTFS filesystems and by the ISO 9660
-  filesystem when it is compiled with Joliet support. Joliet is a
-  Microsoft extension for CDROMs that supports Unicode. This allows
-  translation between different character sets. 
-
-  When dealing with the FAT based filesystems, there are two character
-  sets that are important. The first is the codepage. Codepages are
-  character sets that are used by DOS to allow filenames to have
-  native language characters when character sets were limited to 256
-  characters. The codepage is the character set that is used to store
-  native language characters on disk. The two most common codepages
-  are 437 in the United States and 850 in much of Europe.
-
-  The second important character set is the input/output character
-  set. This is the character set that is displayed on the screen. In
-  the United States, this will almost always be the ISO 8859-1
-  character set. This is the default.
-
-  Linux will only translate the FAT filenames, not the contents of the
-  files.
-
 nls codepage 437
 CONFIG_NLS_CODEPAGE_437
   The Microsoft fat filesystem family can deal with filenames in
@@ -7854,14 +7952,22 @@
   and read Documentation/modules.txt. The module will be called esp.o.
   If unsure, say N.
 
+Multi-Tech multiport card support
+CONFIG_ISI
+  This is a driver for the Multi-Tech cards which provide several
+  serial ports. The driver is experimental and can currently only be
+  built as a module ( = code which can be inserted in and removed from
+  the running kernel whenever you want). Please read
+  Documentation/modules.txt. The module will be called isicom.o
+
 Unix98 PTY support
 CONFIG_UNIX98_PTYS
   A pseudo terminal (PTY) is a software device consisting of two
   halves: a master and a slave. The slave device behaves identical to
   a physical terminal; the master device is used by a process to
   read data from and write data to the slave, thereby emulating a
-  terminal. Typical programs for the master side are xterm and telnet
-  servers. 
+  terminal. Typical programs for the master side are telnet servers
+  and xterms.
   
   Linux has traditionally used the BSD-like names /dev/ptyxx for
   masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
@@ -7876,9 +7982,10 @@
   filesystem; therefore, if you say Y here you should say Y to
   "/dev/pts filesystem for Unix98 PTYs" as well.
 
-  You should say Y here only if your C library is glibc 2.1 or later
-  (equal to libc-6.1, check with "ls -l /lib/libc.so.*"). Read the
-  instructions in Documentation/Changes.
+  If you want to say Y here, you need to have the C library glibc 2.1
+  or later (equal to libc-6.1, check with "ls -l /lib/libc.so.*").
+  Read the instructions in Documentation/Changes pertaining to pseudo
+  terminals. It's save to say N.
 
 Maximum number of Unix98 PTYs in use (0-2048)
 CONFIG_UNIX98_PTY_COUNT
@@ -8186,7 +8293,7 @@
 
   Ftape can print lots of debugging messages to the system console
   resp. kernel log files. Reducing the amount of possible debugging
-  output reduces the size of the kernel module by some kb, so it might
+  output reduces the size of the kernel module by some KB, so it might
   be a good idea to use "None" for emergency boot floppies.
 
   If you want to save memory then the following strategy is
@@ -8501,36 +8608,28 @@
 CONFIG_APM_IGNORE_SUSPEND_BOUNCE
   This option is necessary on the Dell Inspiron 3200 and others, but
   should be safe for all other laptops. When enabled, a system suspend
-  event that occurs within three seconds of a resume is ignored. Without
-  this the Inspiron will shut itself off a few seconds after you open
-  the lid, requiring you to press the power button to resume it a
-  second time.
-  Say Y.
+  event that occurs within three seconds of a resume is ignored.
+  Without this the Inspiron will shut itself off a few seconds after
+  you open the lid, requiring you to press the power button to resume
+  it a second time. Say Y.
 
 RTC stores time in GMT
 CONFIG_APM_RTC_IS_GMT
-  This option can be used when your RTC (Real Time Clock aka. Hardware
-  Clock) stores the time in GMT (Greenwich Mean Time) rather than
-  localtime. When suspending/resuming, the kernel needs to know what
-  is stored in the RTC so it can update the system clock (which is
-  always GMT). Without this option the kernel attempts to measure
-  the offset between the RTC and the system clock. This means you
-  can loose one second on each suspend/resume cycle.
-  Also, on the Dell Inspiron 3200, the hardware slows down the system
-  even before the kernel can measure the RTC/system clock offset. It
-  can then take 15 seconds to do this measurement and it can be
-  incorrect by several seconds.
-  Say Y if GMT is stored in your RTC.
-  GMT is usually the best anyway, because you don't have to worry about
-  daylight savings time changes. The only reason to not use GMT in
-  your RTC is if you also run a broken OS that doesn't understand GMT.
+  Say Y here if your RTC (Real Time Clock a.k.a. hardware clock)
+  stores the time in GMT (Greenwich Mean Time). Say N if your RTC
+  stores localtime.
+
+  It is in fact recommended to store GMT in your RTC, because then you
+  don't have to worry about daylight savings time changes. The only
+  reason not to use GMT in your RTC is if you also run a broken OS
+  that doesn't understand GMT.
 
 Allow interrupts during APM BIOS calls
 CONFIG_APM_ALLOW_INTS
   Normally we disable external interrupts while we are making calls to
   the APM BIOS as a measure to lessen the effects of a badly behaving
-  BIOS implementation.  The BIOS should reeanble interrupts if it
-  needs to.  Unfortunately, some BIOS's do not - especially those in
+  BIOS implementation.  The BIOS should reenable interrupts if it
+  needs to.  Unfortunately, some BIOSes do not - especially those in
   many of the newer IBM Thinkpads.  If you experience hangs when you
   suspend, try setting this to Y.  Otherwise, say N.
 
@@ -8643,8 +8742,9 @@
   24 hour alarm. It reports status information via the file /proc/rtc
   and its behaviour is set by various ioctls on /dev/rtc.
 
-  If you enabled CONFIG_SMP, you should say Y here to read and set the
-  RTC clock in an SMP compatible fashion.
+  If you run Linux on a multiprocessor machine and said Y to
+  "Symmetric Multi Processing" above, you should say Y here to read
+  and set the RTC clock in an SMP compatible fashion.
 
   If you think you have a use for such a device (such as periodic data
   sampling), then say Y here, and read Documentation/rtc.txt for
@@ -8664,14 +8764,16 @@
   with major number 10 and minor number 144 using mknod ("man mknod"),
   you get read and write access to the 50 bytes of non-volatile memory
   in the real time clock (RTC), which is contained in every PC and
-  most Ataris. This memory is conventionally called "CMOS RAM" on PCs
-  and "NVRAM" on Ataris. /dev/nvram may be used to view settings
-  there, or to change them (with some utility). It could also be used
-  to frequently save a few bits of very important data that may not be
-  lost over power-off and for which writing to disk is too insecure. Note
-  however that most NVRAM space in a PC belongs to the BIOS and you should
-  NEVER idly tamper with it. See Ralf Browns interrupt list for a guide to 
-  the use of CMOS bytes by your BIOS.
+  most Ataris. 
+
+  This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
+  on Ataris. /dev/nvram may be used to view settings there, or to
+  change them (with some utility). It could also be used to frequently
+  save a few bits of very important data that may not be lost over
+  power-off and for which writing to disk is too insecure. Note
+  however that most NVRAM space in a PC belongs to the BIOS and you
+  should NEVER idly tamper with it. See Ralf Brown's interrupt list
+  for a guide to the use of CMOS bytes by your BIOS.
 
   On Atari machines, /dev/nvram is always configured and does not need
   to be selected.
@@ -8764,7 +8866,7 @@
   Say Y here if you have the TurboGraFX interface by Steffen Schwenke,
   and want to use it with Multiststem -- Atari, Amiga, Commodore,
   Amstrad CPC joystick. For more information on how to use the driver
-  please read Documentation/joystick-parport.txt and
+  please read Documentation/joystick.txt and
   Documentation/joystick-parport.txt
 
 Amiga joysticks
@@ -8789,12 +8891,14 @@
   If you have a sound card in your computer, i.e. if it can say more
   than an occasional beep, say Y. Be sure to have all the information
   about your sound card and its configuration down (I/O port,
-  interrupt and DMA channel), because you will be asked for it. You
-  want to read the Sound-HOWTO, available via FTP (user: anonymous)
-  from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. There is also some
-  information in various README files in drivers/sound, esp. in
-  Readme.cards which you should read first to find out whether your
-  card is supported by Linux, and, if yes, which driver to use.
+  interrupt and DMA channel), because you will be asked for it. 
+
+  You want to read the Sound-HOWTO, available via FTP (user:
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. General
+  information about the modular sound system is contained in the files
+  Documentation/sound/Introduction. The file
+  Documentation/sound/README.OSS contains some slightly outdated but
+  still useful information as well.
 
   If you have a PnP sound card and you want to configure it at boot
   time using the ISA PnP tools (read
@@ -8805,7 +8909,8 @@
   from the running kernel whenever you want) and load that module
   after the PnP configuration is finished. To do this, say M here and
   read Documentation/modules.txt as well as
-  drivers/sound/Readme.modules; the module will be called sound.o.
+  Documentation/sound/README.modules; the module will be called
+  sound.o.
 
   I'm told that even without a sound card, you can make your computer
   say more than an occasional beep, by programming the PC speaker.
@@ -8828,7 +8933,7 @@
 
 Support for AD1816(A) based cards (EXPERIMENTAL)
 CONFIG_SOUND_AD1816
-  Say M here if you have a soundcard based on the Analog Devices 
+  Say M here if you have a sound card based on the Analog Devices 
   AD1816(A) chip.
 
   NOTE: This driver is still EXPERIMENTAL. 
@@ -8849,25 +8954,23 @@
 
 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support
 CONFIG_SOUND_SB
-  Answer Y if you have an original Sound Blaster card made by
-  Creative Labs or a 100% hardware compatible clone (like the
-  Thunderboard or SM Games). If your card was in the list of supported
-  cards look at the card specific instructions in the
-  drivers/sound/Readme.cards file before answering this question. For
-  an unknown card you may answer Y if the card claims to be
-  Sound Blaster-compatible. 
+  Answer Y if you have an original Sound Blaster card made by Creative
+  Labs or a 100% hardware compatible clone (like the Thunderboard or
+  SM Games). For an unknown card you may answer Y if the card claims
+  to be Sound Blaster-compatible.
 
-  You can say M here to compile this driver as a module; the module is
-  called sb.o.
+  Please read the file Documentation/sound/Soundblaster.
 
   You should also say Y here for cards based on the Avance Logic
-  ALS-007 chip (read Documentation/sound/ALS007) and for ESS1688 and
-  ESS1868 cards (read Documentation/sound/ESS1868). If you have an SB
-  AWE 32 or SB AWE 64, say Y here and also to "Additional lowlevel
-  drivers" and to "SB32/AWE support" below. If you have an IBM Mwave
-  card, say Y here and read Documentation/sound/mwave.
+  ALS-007 chip (read Documentation/sound/ALS007) and for cards based
+  on ESS chips (read Documentation/sound/ESS1868 and
+  Documentation/sound/ESS). If you have an SB AWE 32 or SB AWE 64, say
+  Y here and also to "Additional lowlevel drivers" and to "SB32/AWE
+  support" below and read Documentation/sound/INSTALL.awe. If you have
+  an IBM Mwave card, say Y here and read Documentation/sound/mwave.
   
-  Please read Documentation/sound/Soundblaster.
+  You can say M here to compile this driver as a module; the module is
+  called sb.o.
 
 Generic OPL2/OPL3 FM synthesizer support
 CONFIG_SOUND_ADLIB
@@ -9168,19 +9271,20 @@
 
 ACI mixer (miroPCM12/PCM20)
 CONFIG_ACI_MIXER
-  Audio Command Interface (ACI) driver. ACI is a protocol used to
-  communicate with the microcontroller on some sound cards produced by
-  miro, e.g. the miroSOUND PCM12 and PCM20. The main function of the
-  ACI is to control the mixer and to get a product identification.
+  ACI (Audio Command Interface) is a protocol used to communicate with
+  the microcontroller on some sound cards produced by miro, e.g. the
+  miroSOUND PCM12 and PCM20. The main function of the ACI is to
+  control the mixer and to get a product identification. 
+
   This Voxware ACI driver currently only supports the ACI functions on
   the miroSOUND PCM12 and PCM20 cards. On the PCM20, ACI also controls
-  the radio tuner. This is supported in the video4linux radio-miropcm20
-  driver.
+  the radio tuner. This is supported in the video4linux
+  radio-miropcm20 driver.
 
 SB32/AWE support
 CONFIG_AWE32_SYNTH
   Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
-  similar sound card. See drivers/sound/lowlevel/README.awe,
+  similar sound card. See Documentation/sound/README.awe,
   Documentation/sound/AWE32 and the Soundblaster-AWE mini-HOWTO,
   available via FTP (user: anonymous) from
   ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini for more info.
@@ -9243,9 +9347,9 @@
 
 Audio Excel DSP 16 DMA
 CONFIG_AEDSP16_MSS_DMA
-  This is the IRQ of the Audio Excel DSP 16 card. It must be 0, 1 or 3.
-  If you compiled aedsp16.o as a module you can specify this parameter
-  as 'dma=NN'.
+  This is the IRQ of the Audio Excel DSP 16 card. It must be 0, 1 
+  or 3. If you compiled aedsp16.o as a module you can specify this
+  parameter as 'dma=NN'.
 
 SC-6600 based audio cards (new Audio Excel DSP 16)
 CONFIG_SC6600
@@ -9255,28 +9359,30 @@
 
 SC-6600 Joystick Interface
 CONFIG_SC6600_JOY
-  This option activate the Joystick interface of Audio Excel DSP 16 card.
+  Say Y here in order to use the joystick interface of the Audio Excel
+  DSP 16 card.
 
 SC-6600 CDROM Interface
 CONFIG_SC6600_CDROM
-  This option activate the CDROM interface of Audio Excel DSP 16 card.
-  Required parameter can be: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for
-  no CDROM present.
+  This is used to activate the the CDROM interface of the Audio Excel
+  DSP 16 card. Enter: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for no
+  CDROM present.
 
 Audio Excel DSP 16 (MPU401 emulation)
 CONFIG_AEDSP16_MPU401
   Answer Y if you want your audio card to emulate the MPU-401 midi
-  interface. You should then say Y to "MPU-401 support".
-  You have to note that the I/O base for MPU-401 support of aedsp16 is
-  the same you have selected for "MPU-401 support". If you are using
-  this driver as a module you have to specify the MPU I/O base address
-  with the parameter 'mpu_base=0xNNN'.
+  interface. You should then also say Y to "MPU-401 support".
+  
+  Note that the I/O base for MPU-401 support of aedsp16 is the same
+  you have selected for "MPU-401 support". If you are using this
+  driver as a module you have to specify the MPU I/O base address with
+  the parameter 'mpu_base=0xNNN'.
 
 MPU401 IRQ for Audio Excel DSP 16
 CONFIG_AEDSP16_MPU_IRQ
-  This is the IRQ of the MPU-401 emulation of Audio Excel DSP 16 card.
-  It must be 5, 7, 9, 10 or 0 (to disable MPU-401 interface). If you
-  compiled aedsp16.o as a module you can specify this parameter as
+  This is the IRQ of the MPU-401 emulation of your Audio Excel DSP 16
+  card. It must be 5, 7, 9, 10 or 0 (to disable MPU-401 interface). If
+  you compiled aedsp16.o as a module you can specify this parameter as
   'mpu_irq=NN'.
 
 Ensoniq ES1370 based PCI sound cards
@@ -9304,14 +9410,18 @@
   models are either ES1370 or ES1371 based. This driver differs
   slightly from OSS/Free, so PLEASE READ Documentation/sound/es1371.
 
+Joystick support at boot time
+CONFIG_SOUND_ES1371_JOYPORT_BOOT
+  Say Y here to use the joystick port of your sound card.
+
 Gameport I/O-range selection
 CONFIG_SOUND_ES1371_GAMEPORT
-  Select the I/O-range of the gameport on a ES1371 based soundcard.
+  Select the I/O-range of the gameport on a ES1371 based sound card.
   The card uses 8 ioports and the gameport is available at all eight
   ioports. Legal hexadecimal values are 200, 208, 210 and 218.
   The joystick driver will by default use 0x201. 
   Leave the default 200 unless you have a joystick not attached
-  to your soundcard.
+  to your sound card.
 
 S3 SonicVibes based PCI sound cards
 CONFIG_SOUND_SONICVIBES
@@ -9747,12 +9857,10 @@
 
 HP9000/300 support
 CONFIG_HP300
-  This option enables support for the HP9000/300 series of workstations.
-  Support for these machines is still very experimental.  If you plan to
-  try to use the kernel on such a machine say Y here.  Everybody else
-  says N.
-
-# CONFIG_APOLLO, etc. coming soon (?)
+  This option enables support for the HP9000/300 series of
+  workstations. Support for these machines is still very experimental.
+  If you plan to try to use the kernel on such a machine say Y here.
+  Everybody else says N.
 
 68020 support
 CONFIG_M68020
@@ -10202,13 +10310,14 @@
 
 HP on-board LANCE support
 CONFIG_HPLANCE
-  If you want to use the builtin "LANCE" Ethernet controller on an HP300
-  machine, say Y here.
+  If you want to use the builtin "LANCE" Ethernet controller on an
+  HP300 machine, say Y here.
 
 DIO bus support
 CONFIG_DIO
-  Say Y here to enable support for the "DIO" expansion bus used in HP300
-  machines. If you are using such a system you almost certainly want this.
+  Say Y here to enable support for the "DIO" expansion bus used in
+  HP300 machines. If you are using such a system you almost certainly
+  want this.
 
 MSDOS partition support
 CONFIG_MSDOS_PARTITION
@@ -10519,16 +10628,17 @@
 
 Include support for CATS boards
 CONFIG_CATS
-  Say Y here if you wish to include support for the extra hardware found
-  in Chalice CATS machines. The resulting kernel will still run on an 
-  EBSA-285 but will be slightly larger. If in doubt say N.
+  Say Y here if you wish to include support for the extra hardware
+  found in Chalice CATS machines. The resulting kernel will still run
+  on an EBSA-285 but will be slightly larger. If in doubt say N.
 
 Debug kernel errors
 CONFIG_DEBUG_ERRORS
-  This option controls verbose debugging information which can be printed
-  when the kernel detects an internal error.  Verbose debugging information
-  is useful when tracking down kernel problems, but it will be meaning less
-  for non-kernel hackers.  It's safe for everyone to say Y.
+  This option controls verbose debugging information which can be
+  printed when the kernel detects an internal error. Verbose debugging
+  information is useful when tracking down kernel problems, but it
+  will be meaning less for non-kernel hackers. It's safe for everyone
+  to say Y.
 
 Build Tools Selection
 CONFIG_BINUTILS_NEW
@@ -10544,30 +10654,35 @@
 
 Initial kernel command line
 CONFIG_CMDLINE
-  On some architectures (EBSA285, EBSA110 and Corel NetWinder), there is
-  currently no way for the boot loader to pass arguments to the kernel.
-  For these architectures, you should supply some command-line options
-  at build time by entering them here.  As a minimum, you should specify
-  the memory size and the root device (eg, mem=64M root=/dev/nfs)
+  On some architectures (EBSA285, EBSA110 and Corel NetWinder), there
+  is currently no way for the boot loader to pass arguments to the
+  kernel. For these architectures, you should supply some command-line
+  options at build time by entering them here. As a minimum, you
+  should specify the memory size and the root device (e.g., mem=64M
+  root=/dev/nfs)
 
 IrDA Protocols
 CONFIG_IRDA
-  Say Y here if you want to build support for the IrDA (TM)
-  protocols. The Infrared Data Associations (tm) specifies standards
-  for wireless infrared communication and is supported by most laptops
-  and PDA's If you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  Say Y here if you want to build support for the IrDA (TM) protocols.
+  The Infrared Data Associations (tm) specifies standards for wireless
+  infrared communication and is supported by most laptops and PDA's.
 
   To use Linux support for the IrDA (tm) protocols, you will also need
   some user-space utilities like the irmanager and probably irattach
-  as well. For more information, visit
-  http://www.cs.uit.no/~dagb/irda/
+  as well. For more information, see the file
+  Documentation/networking/irda.txt. You also want to read the
+  IR-HOWTO, available from
+  ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO.
+
+  This support is also available as a module. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. The
+  module will be called 
 
 IrDA Cache last LSAP
 CONFIG_IRDA_CACHE_LAST_LSAP
   Say Y here if you want IrLMP to cache the last LSAP used. This makes
-  sense since most frames will be sent/received on the same connection.
-  Enabling this option will save a hash-lookup per frame.
+  sense since most frames will be sent/received on the same
+  connection. Enabling this option will save a hash-lookup per frame.
 
   If unsure, say Y.
 
@@ -10575,8 +10690,8 @@
 CONFIG_IRDA_FAST_RR
   Say Y here is you want IrLAP to send fast RR (Receive Ready) frames
   when acting as a primary station. This will make IrLAP send out a RR
-  frame immediately when receiving a frame if its own transmit queue is
-  currently empty. This will give a lot of speed improvement when
+  frame immediately when receiving a frame if its own transmit queue
+  is currently empty. This will give a lot of speed improvement when
   receiving much data since the secondary station will not have to
   wait the max. turn around time before it is allowed to transmit the
   next time. If the transmit queue of the secondary is also empty the
@@ -10600,8 +10715,8 @@
 
 IrDA Debug
 CONFIG_IRDA_DEBUG
-  Say Y here if you want the IrDA subsystem to write debug information to
-  your syslog. You can change the debug level in
+  Say Y here if you want the IrDA subsystem to write debug information
+  to your syslog. You can change the debug level in
   /proc/sys/net/irda/debug
 
   If unsure, say Y (since it makes it easier to find the bugs).
@@ -10611,22 +10726,27 @@
   Compression is _not_ part of the IrDA(tm) protocol specification,
   but it's working great! Linux is the first to try out compression
   support at the IrLAP layer. This means that you will only benefit
-  from compression if you are running a Linux <-> Linux configuration
+  from compression if you are running a Linux <-> Linux configuration.
+  
+  If you say Y here, you also need to say Y or M to a compression
+  protocol below.
 
 IrLAP Deflate Compression Protocol
 CONFIG_IRDA_DEFLATE
   Say Y here if you want to build support for the Deflate compression
-  protocol. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt. The deflate compression (GZIP) is exactly
-  the same as used by the PPP protocol. Enabling this option will
-  build a module called irda_deflate.o
+  protocol. The deflate compression (GZIP) is exactly
+  the same as the one used by the PPP protocol. 
+
+  If you want to compile this compression support as a module, say M
+  here and read Documentation/modules.txt. The module will be called
+  irda_deflate.o.
 
 IrLAN Protocol 
 CONFIG_IRLAN
   Say Y here if you want to build support for the IrLAN protocol. If
   you want to compile it as a module, say M here and read
   Documentation/modules.txt. IrLAN emulates an Ethernet and makes it
-  possible to put up an wireless LAN using infrared beams.
+  possible to put up a wireless LAN using infrared beams.
 
 IrLAN Client Protocol 
 CONFIG_IRLAN_CLIENT
@@ -10635,7 +10755,7 @@
   Documentation/modules.txt. The IrLAN client protocol can be used to
   talk with infrared access points like the HP NetbeamIR, or the ESI
   JetEye NET. You can also connect to another Linux machine running
-  the IrLAN server protocol for ac-hoc networking!
+  the IrLAN server protocol for ad-hoc networking!
 
 IrLAN Server Protocol 
 CONFIG_IRLAN_SERVER
@@ -10645,15 +10765,14 @@
   possible to set up a wireless LAN with a machine running the IrLAN
   client protocol. Notice that the IrLAN server protocol currently
   only emulates an access point and does not implement the ad-hoc
-  specification of IrLAN, but this will not be noticeable for the
-  user.
+  specification of IrLAN, but this will not be noticeable by the user.
 
 IrOBEX Protocol
 CONFIG_IROBEX
   Say Y here if you want to build support for the IrOBEX protocol. If
   you want to compile it as a module, say M here and read
   Documentation/modules.txt. The module does not actually implement
-  the IrOBEX protocol since that protocol lives in userspace, but it 
+  the IrOBEX protocol since that protocol lives in user space, but it 
   contains the necessary functions to interface the user-space stuff
   with the kernel. So you will need to have the user-space library and
   programs that can use this library installed as well to be able to
@@ -10710,11 +10829,11 @@
 
 Winbond W83977AF IrDA Device Driver
 CONFIG_WINBOND_FIR
-  Say Y here if you want to build IrDA support for the Winbond W83977AF
-  super-io chipset. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt. This driver should be used for
-  the IrDA chipset in the Corel NetWinder. The driver supports SIR,
-  MIR and FIR (4Mbps) speeds.
+  Say Y here if you want to build IrDA support for the Winbond
+  W83977AF super-io chipset. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. This driver should be
+  used for the IrDA chipset in the Corel NetWinder. The driver
+  supports SIR, MIR and FIR (4Mbps) speeds.
 
 NSC PC87108 IrDA Device Driver
 CONFIG_NSC_FIR
@@ -10839,11 +10958,13 @@
 
 #
 # A couple of things I keep forgetting:
-#   capitalize: AppleTalk, Ethernet, DMA, FTP, Internet, Intel, IRQ, 
-#               Linux, NetWare, NFS, PCI, SCSI, SPARC
+#   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, 
+#               Intel, IRQ, Linux, MSDOS, NetWare, NetWinder, NFS, 
+#               PCI, SCSI, SPARC
 #   two words:  hard drive, hard disk, sound card, home page
 #   other:      it's safe to save; daemon; use --, not - or ---
 #
+#
 # This is used by Emacs' spell checker ispell.el:
 #
 # LocalWords:  CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp metalab
@@ -10866,7 +10987,7 @@
 # LocalWords:  COM ELPLUS Com EtherLinkIII VLB Arcnet Cabletron DEPCA DE carlos
 # LocalWords:  depca EtherWorks EWRK ewrk SEEQ EtherExpress EEXPRESS NI xxx dia
 # LocalWords:  EtherExpress WaveLAN wavelan PCLAN HPLAN VG SK Ansel Xen de ZNET
-# LocalWords:  PCMCIA cb stanford pcmcia LAN TEC RealTek ATP atp DLINK NetTools
+# LocalWords:  PCMCIA cb stanford LAN TEC RealTek ATP atp DLINK NetTools VISWS
 # LocalWords:  TR Sony CDU caddyless cdu Mitsumi MCD cd mcd XA MultiSession CDA
 # LocalWords:  Matsushita Panasonic SBPCD Soundblaster Longshine sbpcd Aztech
 # LocalWords:  Okano Wearnes AZTCD CDD SE aztcd sonycd Goldstar GSCD Philips fs
@@ -10896,7 +11017,7 @@
 # LocalWords:  PMAX MILO Alphas Multia Tseng linuxelf endian mipsel mips drv HT
 # LocalWords:  kerneld callouts AdvanSys advansys Admin WDT DataStor EP verden
 # LocalWords:  wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI
-# LocalWords:  QD qd UMC umc ALI ali lena fnet fr azstarnet axplinux cdr fb MDA
+# LocalWords:  QD qd UMC umc ALI ali lena fnet fr azstarnet cdr fb MDA ps esdi
 # LocalWords:  Avanti XL AlphaStations Jensen DECpc AXPpci UDB Cabriolet MCA RC
 # LocalWords:  AlphaPC mca AOUT OUTput PPro sipx gwdg lo nwe FourPort Boca unm
 # LocalWords:  Keepalive linefill RELCOM keepalive analogue CDR conf CDI INIT
@@ -11045,4 +11166,20 @@
 # LocalWords:  PowerMacs Winbond Algorithmics ALGOR algor ECOFF IRIX SGI SGI's
 # LocalWords:  gfx virtualized Xpmac mklinux XFree FBDev Woodhouse mvhi Seeq fp
 # LocalWords:  SGISEEQ HIgh ADB ADBMOUSE crosscompiler CROSSCOMPILE FPE GDB gdb
-# LocalWords:  JOYPORT rp spoofing DawiControl NOGENSUPP EEPROM HSSI
+# LocalWords:  JOYPORT rp spoofing DawiControl NOGENSUPP EEPROM HSSI Alessandro
+# LocalWords:  singleprocessor tex MATHEMU FRIQ Maxell friq Alcor XLT AlphaBook
+# LocalWords:  AlphaPCI DP LX Miata Mikasa Noritake RPX UX BX Takara EV PRIMO
+# LocalWords:  TSC Matrox Productiva matroxfb matrox multihead ia linuxhq MFW
+# LocalWords:  mfw AAA MCS Initio XXU initio imm AutoDetect IZIP CTR usec HDLC
+# LocalWords:  COSA SRP muni cz kas cosa Alteon AceNIC acenic VTOC OSes GMT SAx
+# LocalWords:  Inspiron localtime INTS Thinkpads Ralf Brown's Flightstick NNN
+# LocalWords:  Xterminator Blackhawk NN mpu ioports DCA HPDCA HPLANCE DIO Corel
+# LocalWords:  GemTek gemtek CMDLINE IrDA PDA's irmanager irattach RR AVA DN
+# LocalWords:  uit dagb irda LSAP IrLMP RR's IrLAP IR alloc skb's kfree skb's
+# LocalWords:  GZIP IrLAN NetbeamIR ESI JetEye IrOBEX IrCOMM TTY's minicom dti
+# LocalWords:  ircomm ircomm pluto thiguchi IrTTY Linux's bps NetWinder MIR NSC
+# LocalWords:  ACTiSYS Dongle dongle dongles esi actisys IrMate tekram BVM MVME
+# LocalWords:  BVME BVME WRITETHROUGH copyback writethrough fwmark syncookie tu
+# LocalWords:  alphalinux GOBIOS csn chemnitz nat ACARD AMI MegaRAID megaraid
+# LocalWords:  QNXFS ISI isicom xterms Apollos VPN RCPCI rcpci sgi visws pcmcia
+# LocalWords:  IrLPT UIRCC Tecra
diff -u --recursive --new-file v2.2.1/linux/Documentation/fb/vesafb.txt linux/Documentation/fb/vesafb.txt
--- v2.2.1/linux/Documentation/fb/vesafb.txt	Tue Jan 19 11:32:50 1999
+++ linux/Documentation/fb/vesafb.txt	Sat Feb  6 12:47:42 1999
@@ -11,7 +11,7 @@
 This means we decide at boot time whenever we want to run in text or
 graphics mode.  Switching mode later on (in protected mode) is
 impossible; BIOS calls work in real mode only.  VESA BIOS Extentions
-Version 2.0 are required, becauce we need a linear frame buffer.
+Version 2.0 are required, because we need a linear frame buffer.
 
 Advantages:
 
@@ -75,7 +75,7 @@
 1. Note: LILO cannot handle hex, for booting directly with 
          "vga=mode-number" you have to transform the numbers to decimal.
 2. Note: Some newer versions of LILO appear to work with those hex values,
-         if you set the 0x infront of the numbers.
+         if you set the 0x in front of the numbers.
 
 X11
 ===
diff -u --recursive --new-file v2.2.1/linux/Documentation/kbuild/00-INDEX linux/Documentation/kbuild/00-INDEX
--- v2.2.1/linux/Documentation/kbuild/00-INDEX	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/kbuild/00-INDEX	Mon Feb  1 12:03:20 1999
@@ -0,0 +1,8 @@
+00-INDEX
+    	- this file: info on the kernel build process
+bug-list.txt
+	- known bugs in kbuild programs
+commands.txt
+	- overview of kbuild commands
+config-language.txt
+	- specification of Config Language, the language in Config.in files
diff -u --recursive --new-file v2.2.1/linux/Documentation/kbuild/bug-list.txt linux/Documentation/kbuild/bug-list.txt
--- v2.2.1/linux/Documentation/kbuild/bug-list.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/kbuild/bug-list.txt	Mon Feb  1 12:03:20 1999
@@ -0,0 +1,22 @@
+Bug List
+21 January 1999
+Michael Elizabeth Chastain, <mailto:mec@shout.net>
+
+- If a variable has a value of "m" in the previous .config file,
+  and a type of bool in the Config script, then all the interpreters
+  get confused.  This happens frequently when someone changes a
+  tristate option to a bool option and people in the field have
+  .config files with a value of 'm'.  For example: CONFIG_PSMOUSE.
+
+- CONFIG_MODVERSIONS has incorrect dependencies.  If you have a
+  problem building the kernel, and you have CONFIG_MODVERSIONS turned
+  on, do a 'make dep' followed by 'make clean' before you try anything
+  else.
+
+- 'make dep' uses multistage dependencies, so the .hdepend file contains
+  'touch' commands.  As a result, building a kernel often touches files
+  in include/linux/*.h.  This messes up CVS and other systems which like
+  to rely on file dates.
+
+- 'make dep' fails for C files which include other C files, such as
+  drivers/cdrom/sbpcd2.c.
diff -u --recursive --new-file v2.2.1/linux/Documentation/kbuild/commands.txt linux/Documentation/kbuild/commands.txt
--- v2.2.1/linux/Documentation/kbuild/commands.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/kbuild/commands.txt	Mon Feb  1 12:03:20 1999
@@ -0,0 +1,113 @@
+Overview of Kbuild Commands
+24 January 1999
+Michael Elizabeth Chastain, <mailto:mec@shout.net>
+
+
+
+=== Introduction
+
+Someday we'll get our arms around all this stuff and clean it up
+a little!  Meanwhile, this file describes the system as it is today.
+
+
+
+=== Quick Start
+
+If you are building a kernel for the first time, here are the commands
+you need:
+
+    make config
+    make dep
+    make bzImage
+
+Instead of 'make config', you can run 'make menuconfig' for a full-screen
+text interface, or 'make xconfig' for an X interface using TCL/TK.
+
+'make bzImage' will leave your new kernel image in arch/i386/boot/bzImage.
+You can also use 'make bzdisk' or 'make bzlilo'.
+
+See the lilo documentation for more information on how to use lilo.
+You can also use the 'loadlin' program to boot Linux from MS-DOS.
+
+Some computers won't work with 'make bzImage', either due to hardware
+problems or very old versions of lilo or loadlin.  If your kernel image
+is small, you may use 'make zImage', 'make zdisk', or 'make zlilo'
+on theses systems.
+
+If you find a file name 'vmlinux' in the top directory of the source tree,
+just ignore it.  This is an intermediate file and you can't boot from it.
+
+Other architectures: the information above is oriented towards the
+i386.  On other architectures, there are no 'bzImage' files; simply
+use 'zImage' or 'vmlinux' as appropriate for your architecture.
+
+Note: the difference between 'zImage' files and 'bzImage' files is that
+'bzImage' uses a different layout and a different loading algorithm,
+and thus has a larger capacity.  Both files use gzip compression.
+The 'bz' in 'bzImage' stands for 'big zImage', not for 'bzip'!
+
+
+
+=== Top Level Makefile targets
+
+Here are the targets available at the top level:
+
+    make config, make oldconfig, make menuconfig, make xconfig
+
+	Configure the Linux kernel.  You must do this before almost
+	anything else.
+
+	config		line-oriented interface
+	oldconfig	line-oriented interface, re-uses old values
+	menuconfig	curses-based full-screen interface
+	xconfig		X window system interface
+
+    make checkconfig
+
+	This runs a little perl script that checks the source tree for
+	missing instances of #include <linux/config.h>.  Someone needs to
+	do this occasionally, because the C preprocessor will silently give
+	bad results if these symbols haven't been included (it treats
+	undefined symbols in preprocessor directives as defined to 0).
+	Superfluous uses of #include <linux/config.h> are also reported,
+	but you can ignore these, because smart CONFIG_* dependencies
+	make them harmless.
+
+	You can run 'make checkconfig' without configuring the kernel.
+	Also, 'make checkconfig' does not modify any files.
+
+    make checkhelp
+
+	This runs another little perl script that checks the source tree
+	for options that are in Config.in files but are not documented
+	in scripts/Configure.help.  Again, someone needs to do this
+	occasionally.  If you are adding configuration options, it's
+	nice if you do it before you publish your patch!
+
+	You can run 'make checkhelp' withoug configuring the kernel.
+	Also, 'make checkhelp' does not modify any files.
+
+    make dep, make depend
+
+	'make dep' is a synonym for the long form, 'make depend'.
+
+	This command does two things.  First, it computes dependency
+	information about which .o files depend on which .h files.
+	It records this information in a top-level file named .hdepend
+	and in one file per source directory named .depend.
+
+	Second, if you have CONFIG_MODVERSIONS enabled, 'make dep'
+	computes symbol version information for all of the files that
+	export symbols (note that both resident and modular files may
+	export symbols).
+
+	If you do not enable CONFIG_MODVERSIONS, you only have to run
+	'make dep' once, right after the first time you configure
+	the kernel.  The .hdepend files and the .depend file are
+	independent of your configuration.
+
+	If you do enable CONFIG_MODVERSIONS, you must run 'make dep'
+	every time you change your configuration, because the module
+	symbol version information depends on the configuration.
+
+[to be continued ...]
diff -u --recursive --new-file v2.2.1/linux/Documentation/kbuild/config-language.txt linux/Documentation/kbuild/config-language.txt
--- v2.2.1/linux/Documentation/kbuild/config-language.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/kbuild/config-language.txt	Mon Feb  1 12:03:20 1999
@@ -0,0 +1,630 @@
+Config Language Specification
+21 January 1999
+Michael Elizabeth Chastain, <mailto:mec@shout.net>
+
+
+
+=== Introduction
+
+Config Language is not 'bash'.
+
+This document describes Config Language, the Linux Kernel Configuration
+Language.  config.in and Config.in files are written in this language.
+
+Although it looks, and usually acts, like a subset of the 'sh' language,
+Config Language has a restricted syntax and different semantics.
+
+Here is a basic guideline for Config Language programming: use only the
+programming idioms that you see in existing Config.in files.  People often
+draw on their shell programming experience to invent idioms that look
+reasonable to shell programmers, but silently fail in Config Language.
+
+Config Language is not 'bash'.
+
+
+
+=== Interpreters
+
+Four different configuration programs read Config Language:
+
+    scripts/Configure   make config, make oldconfig
+    scripts/Menuconfig  make menuconfig
+    scripts/tkparse     make xconfig
+    mconfig             (in development)
+
+'Configure' is a bash script which interprets Config.in files by sourcing
+them.  Some of the Config Language commands are native bash commands;
+simple bash functions implement the rest of the commands.
+
+'Menuconfig' is another bash script.  It scans the input files with a
+small awk script, builds a shell function for each menu, sources the
+shell functions that it builds, and then executes the shell functions
+in a user-driven order.  Menuconfig uses 'lxdialog', a back-end utility
+program, to perform actual screen output.  'lxdialog' is a C program
+which uses curses.
+
+'scripts/tkparse' is a C program with an ad hoc parser which translates
+a Config Language script to a huge TCL/TK program.  'make xconfig'
+then hands this TCL/TK program to 'wish', which executes it.
+
+'mconfig' is the next generation of Config Language interpreters.  It is a
+C program with a bison parser which translates a Config Language script
+into an internal syntax tree and then hands the syntax tree to one of
+several user-interface front ends.
+
+This document describes the behaviour of all four interpreters, even though
+mconfig has not been released at the time of writing.
+
+
+
+=== Statements
+
+A Config Language script is a list of statements.  There are 21 simple
+statements; an 'if' statement; menu blocks; and a 'source' statement.
+
+A '\' at the end of a line marks a line continuation.
+
+'#' usually introduces a comment, which continues to the end of the line.
+Lines of the form '# ... is not set', however, are not comments.  They
+are semantically meaningful, and all four config interpreters implement
+this meaning.
+
+Newlines are significant.  You may not substitute semicolons for newlines.
+The 'if' statement does accept a semicolon in one position; you may use
+a newline in that position instead.
+
+Here are the basic grammar elements.
+
+    A /prompt/ is a single-quoted string or a double-quoted string.
+    If the word is double-quoted, it may not have any $ substitutions.
+
+    A /word/ is a single unquoted word, a single-quoted string, or a
+    double-quoted string.  If the word is unquoted or double quoted,
+    then $-substition will be performed on the word.
+
+    A /symbol/ is a single unquoted word.
+
+    A /dep/ is a dependency.  Syntactically, it is a /word/.  At run
+    time, a /dep/ must evaluate to "y", "m", "n", or "".
+
+    An /expr/ is a bash-like expression using the operators
+    '=', '!=', '-a', '-o', and '!'.
+
+Here are all the statements:
+
+    Text statements:
+
+        mainmenu_name   /prompt/
+        comment         /prompt/
+        text            /prompt/
+
+    Ask statements:
+
+        bool            /prompt/ /symbol/
+        hex             /prompt/ /symbol/ /word/
+        int             /prompt/ /symbol/ /word/
+        string          /prompt/ /symbol/ /word/
+        tristate        /prompt/ /symbol/
+
+    Define statements:
+
+        define_bool     /symbol/ /word/
+        define_hex      /symbol/ /word/
+        define_int      /symbol/ /word/
+        define_string   /symbol/ /word/
+        define_tristate /symbol/ /word/
+
+    Dependent statements:
+
+        dep_bool        /prompt/ /symbol/ /dep/ ...
+        dep_hex         /prompt/ /symbol/ /word/ /dep/ ...
+        dep_int         /prompt/ /symbol/ /word/ /dep/ ...
+        dep_string      /prompt/ /symbol/ /word/ /dep/ ...
+        dep_tristate    /prompt/ /symbol/ /dep/ ...
+
+    Unset statement:
+
+        unset /symbol/ ...
+
+    Choice statements:
+
+        choice          /prompt/ /word/ /word/
+        nchoice         /prompt/ /symbol/ /prompt/ /symbol/ ...
+
+    If statements:
+
+        if [ /expr/ ] ; then
+	  /statement/
+	  ...
+        fi
+
+        if [ /expr/ ] ; then
+	  /statement/
+	  ...
+        else
+	  /statement/
+	  ...
+        fi
+
+    Menu block:
+
+        mainmenu_option next_comment
+        comment /prompt/
+          /statement/
+	  ...
+        endmenu
+
+    Source statement:
+
+        source /word/
+
+
+
+=== mainmenu_name /prompt/
+
+This verb is a lot less important than it looks.  It specifies the top-level
+name of this Config Language file.
+
+Configure:  ignores this line
+Menuconfig: ignores this line
+Xconfig:    uses /prompt/ for the label window.
+mconfig:    ignores this line (mconfig does a better job without it).
+
+Example:
+
+    # arch/sparc/config.in
+    mainmenu_name "Linux/SPARC Kernel Configuration"
+
+
+
+=== comment /prompt/
+
+This verb displays its prompt to the user during the configuration process
+and also echoes it to the output files during output.  Note that the
+prompt, like all prompts, is a quoted string with no dollar substitution.
+
+The 'comment' verb is not a Config Language comment.  It causes the
+user interface to display text, and it causes output to appear in the
+output files.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    does not display, but writes to output files
+mconfig:    implemented
+
+Example:
+
+    # drivers/net/Config.in
+    comment 'CCP compressors for PPP are only built as modules.'
+
+
+
+=== text /prompt/
+
+This verb displays the prompt to the user with no adornment whatsoever.
+It does not echo the prompt to the output file.  mconfig uses this verb
+internally for its help facility.
+
+Configure:  not implemented
+Menuconfig: not implemented
+Xconfig:    not implemented
+mconfig:    implemented
+
+Example:
+
+    # mconfig internal help text
+    text 'Here are all the mconfig command line options.'
+
+
+
+=== bool /prompt/ /symbol/
+
+This verb displays /prompt/ to the user, accepts a value from the user,
+and assigns that value to /symbol/.  The legal input values are "n" and
+"y".
+
+Note that the bool verb does not have a default value.  People keep
+trying to write Config Language scripts with a default value for bool,
+but *all* of the existing language interpreters discard additional values.
+Feel free to submit a multi-interpreter patch to linux-kbuild if you
+want to implement this as an enhancment.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+Example:
+
+    # arch/i386/config.in
+    bool 'Symmetric multi-processing support' CONFIG_SMP
+
+
+
+=== hex /prompt/ /symbol/ /word/
+
+This verb displays /prompt/ to the user, accepts a value from the user,
+and assigns that value to /symbol/.  Any hexadecimal number is a legal
+input value.  /word/ is the default value.
+
+The hex verb does not accept range parameters.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+Example:
+
+    # drivers/sound/Config.in
+    hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220
+
+
+
+=== int /prompt/ /symbol/ /word/
+
+This verb displays /prompt/ to the user, accepts a value from the user,
+and assigns that value to /symbol/.  /word/ is the default value.
+Any decimal number is a legal input value.
+
+The int verb does not accept range parameters.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+Example:
+
+    # drivers/char/Config.in
+    int 'Maximum number of Unix98 PTYs in use (0-2048)' \
+        CONFIG_UNIX98_PTY_COUNT 256
+
+
+
+=== string /prompt/ /symbol/ /word/
+
+This verb displays /prompt/ to the user, accepts a value from the user,
+and assigns that value to /symbol/.  /word/ is the default value.  Legal
+input values are any ASCII string, except for the characters '"' and '\\'.
+
+The default value is mandatory.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+Example:
+
+    # drivers/sound/Config.in
+    string '  Full pathname of DSPxxx.LD firmware file' \
+        CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld
+
+
+
+=== tristate /prompt/ /symbol/
+
+This verb displays /prompt/ to the user, accepts a value from the user,
+and assigns that value to /symbol/.  Legal values are "n", "m", or "y".
+
+The value "m" stands for "module"; it indicates that /symbol/ should
+be built as a kernel module.  The value "m" is legal only if the symbol
+CONFIG_MODULES currently has the value "y".
+
+The tristate verb does not have a default value.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+Example:
+
+    # fs/Config.in
+    tristate 'NFS filesystem support' CONFIG_NFS_FS
+
+
+
+=== define_bool /symbol/ /word/
+
+This verb the value of /word/ to /symbol/.  Legal values are "n" or "y".
+
+For compatibility reasons, the value of "m" is also legal, because it
+will be a while before define_tristate is implemented everywhere.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+Example:
+
+    # arch/alpha/config.in
+    if [ "$CONFIG_ALPHA_GENERIC" = "y" ]
+    then
+            define_bool CONFIG_PCI y
+            define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
+    fi
+
+
+
+=== define_hex /symbol/ /word/
+
+This verb assigns the value of /word/ to /symbol/.  Any hexadecimal
+number is a legal value.
+
+Configure:  implemented
+Menuconfig: not implemented
+Xconfig:    not implemented
+mconfig:    implemented
+
+Example:
+
+    # Not from the corpus
+    bool 'Specify custom serial port' CONFIG_SERIAL_PORT_CUSTOM
+    if [ "$CONFIG_SERIAL_PORT_CUSTOM" = "y" ]; then
+	hex 'Serial port number' CONFIG_SERIAL_PORT
+    else
+	define_hex CONFIG_SERIAL_PORT 0x3F8
+    fi
+
+
+
+=== define_int /symbol/ /word/
+
+This verb assigns /symbol/ the value /word/.  Any decimal number is a
+legal value.
+
+Configure:  implemented
+Menuconfig: not implemented
+Xconfig:    not implemented
+mconfig:    implemented
+
+Example:
+
+    # Not from the corpus
+    define_int CONFIG_UID_TORVALDS 2026
+
+
+
+=== define_string /symbol/ /word/
+
+This verb assigns the value of /word/ to /symbol/.  Legal input values
+are any ASCII string, except for the characters '"' and '\\'.
+
+Configure:  implemented
+Menuconfig: not implemented
+Xconfig:    not implemented
+mconfig:    implemented
+
+Example
+
+    # Not from the corpus
+    define_string CONFIG_VERSION "2.2.0"
+
+
+
+=== define_tristate /symbol/ /word/
+
+This verb assigns the value of /word/ to /symbol/.  Legal input values
+are "n", "m", and "y".
+
+As soon as this verb is implemented in all interpreters, please use it
+instead of define_bool to define tristate values.  This aids in static
+type checking.
+
+Configure:  not implemented
+Menuconfig: not implemented
+Xconfig:    not implemented
+mconfig:    implemented
+
+Example:
+
+    # not from the corpus
+    if [ "$CONFIG_ZFTAPE" != "n" ]; then
+      comment 'The compressor will be built as a module only!'
+      define_tristate CONFIG_ZFT_COMPRESSOR m
+    fi
+
+
+
+=== dep_bool /prompt/ /symbol/ /dep/ ...
+
+This verb evaluates all of the dependencies in the dependency list.
+Any dependency which has a value of "y" does not restrict the input
+range.  Any dependency which has a value of "n", or which has some
+other value, restricts the input range to "n".
+
+If the input range is restricted to the single choice "n", dep_bool
+silently assigns "n" to /symbol/.  If the input range has more than
+one choice, dep_bool displays /prompt/ to the user, accepts a value
+from the user, and assigns that value to /symbol/.
+
+Configure:  not implemented
+Menuconfig: not implemented
+XConfig:    not implemented
+mconfig:    implemented
+
+    # not from the corpus
+    dep_bool 'RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_PCI
+
+
+
+=== dep_hex /prompt/ /symbol/ /word/ /dep/ ...
+=== dep_int /prompt/ /symbol/ /word/ /dep/ ...
+=== dep_string /prompt/ /symbol/ /word/ /dep/ ...
+
+I am still thinking about the semantics of these verbs.
+
+Configure:  not implemented
+Menuconfig: not implemented
+XConfig:    not implemented
+mconfig:    not implemented
+
+
+
+=== dep_tristate /prompt/ /symbol /dep/ ...
+
+This verb evaluates all of the dependencies in the dependency list.
+Any dependency which as a value of "y" does not restrict the input range.
+Any dependency which has a value of "m" restricts the input range to
+"m" or "n".  Any dependency which has a value of "n", or which has some
+other value, restricts the input range to "n".
+
+If the input range is restricted to the single choice "n", dep_tristate
+silently assigns "n" to /symbol/.  If the input range has more than
+one choice, dep_tristate displays /prompt/ to the user, accepts a value
+from the user, and assigns that value to /symbol/.
+
+Configure:  implemented
+Menuconfig: implemented (but silently ignores dependencies after the first)
+Xconfig:    implemented (but silently ignores dependencies after the first)
+mconfig:    implemented
+
+
+
+=== unset /symbol/ ...
+
+This verb assigns the value "" to /symbol/, but does not cause /symbol/
+to appear in the output.  The existence of this verb is a hack; it covers
+up deeper problems with variable semantics in a random-execution language.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    not implemented
+mconfig:    implemented
+
+
+
+=== choice /prompt/ /word/ /word/
+
+This verb implements a choice list or "radio button list" selection.
+It displays /prompt/ to the user, as well as a group of sub-prompts
+which have corresponding symbols.
+
+When the user selects a value, the choice verb sets the corresponding
+symbol to "y" and sets all the other symbols in the choice list to "n".
+
+The second argument is a single-quoted or double-quoted word that
+describes a series of sub-prompts and symbol names.  The interpreter
+breaks up the word at white space boundaries into a list of sub-words.
+The first sub-word is the first prompt; the second sub-word is the
+first symbol.  The third sub-word is the second prompt; the fourth
+sub-word is the second symbol.  And so on, for all the sub-words.
+
+The third word is a literal word.  Its value must be a unique abbreviation
+for exactly one of the prompts.  The symbol corresponding to this prompt
+is the default enabled symbol.
+
+Note that because of the syntax of the choice verb, the sub-prompts
+may not have spaces in them.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+
+
+=== nchoice /prompt/ /symbol/ /prompt/ /symbol/ ...
+
+This verb has the same semantics as the choice verb, but with a sensible
+syntax.
+
+The first /prompt/ is the master prompt for the entire choice list.
+
+The first /symbol/ is the default symbol to enable (notice that this
+is a symbol, not a unique prompt abbreviation).
+
+The subsequent /prompt/ and /symbol/ pairs are the prompts and symbols
+for the choice list.
+
+Configure:  not implemented
+Menuconfig: not implemented
+XConfig:    not implemented
+mconfig:    implemented
+
+
+
+=== if [ /expr/ ] ; then
+
+This is a conditional statement, with an optional 'else' clause.  You may
+substitute a newline for the semicolon if you choose.
+
+/expr/ may contain the following atoms and operators.  Note that, unlike
+shell, you must use double quotes around every atom.
+
+    "..."		a literal
+    "$..."		a variable
+
+    /atom/  = /atom/	true if atoms have identical value
+    /atom/ != /atom/	true if atoms have different value
+
+    /expr/ -o /expr/	true if either expression is true
+    /expr/ -a /expr/	true if both expressions are true
+    ! /expr/		true if expression is not true
+
+Configure:  implemented
+Menuconfig: implemented
+XConfig:    implemented, with bugs
+mconfig:    implemented
+
+Xconfig has several known bugs, and probably some unknown bugs too:
+
+- In a comparison, if the left-hand atom is a variable and that variable
+  is from a choice list, the right-hand atom must be "y".
+
+- In a comparison, if the right-hand atom is a variable and that variable
+  is from a choice list, you lose.  tkparse will throw a segmentation
+  violation, silently generate bizarre TCL code, or something else.
+
+- tkparse gives the wrong precedence to -o, -a, and !.  Don't use both
+  -o and -a in an expression.  Don't use ! at all.
+
+
+
+=== mainmenu_option next_comment
+
+This verb introduces a new menu.  The next statement must have a comment
+verb.  The /prompt/ of that comment verb becomes the title of the menu.
+(I have no idea why the original designer didn't create a 'menu ...' verb).
+
+Statements outside the scope of any menu are in the implicit top menu.
+The title of the top menu comes from a variety of sources, depending on
+the interpreter.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+
+
+=== endmenu
+
+This verb closes the scope of a menu.
+
+Configure:  implemented
+Menuconfig: implemented
+Xconfig:    implemented
+mconfig:    implemented
+
+
+
+=== source /word/
+
+This verb interprets the literal /word/ as a filename, and interpolates
+the contents of that file.  The word must be a single unquoted literal
+word.
+
+Some interpreters interpret this verb at run time; some interpreters
+interpret it at parse time.
+
+Inclusion is textual inclusion, like the C preprocessor #include facility.
+The source verb does not imply a submenu or any kind of block nesting.
+
+Configure:  implemented (run time)
+Menuconfig: implemented (parse time)
+Xconfig:    implemented (parse time)
+mconfig:    implemented (parse time)
diff -u --recursive --new-file v2.2.1/linux/Documentation/proc.txt linux/Documentation/proc.txt
--- v2.2.1/linux/Documentation/proc.txt	Thu Jan 28 12:58:02 1999
+++ linux/Documentation/proc.txt	Sat Feb  6 12:46:20 1999
@@ -50,7 +50,7 @@
 the work back to the Linux community. This work is based on the
 2.1.132 and 2.2.0-pre-kernel versions. I'm afraid it's still far from
 complete, but we hope it will be useful. As far as we know, it is the
-first 'all-in-one’ document about the /proc file system. It is
+first 'all-in-one' document about the /proc file system. It is
 focused on the Intel x86 hardware, so if you are looking for PPC, ARM,
 SPARC, APX, etc., features, you probably won't find what you are
 looking for. It also only covers IPv4 networking, not IPv6 nor other
@@ -657,7 +657,7 @@
 
 sg-big-buff
    This file shows the size of the generic SCSI (sg) buffer. At this
-   point, you can’t tune it yet, but you can change it at compile time
+   point, you can't tune it yet, but you can change it at compile time
    by editing include/scsi/sg.h and changing the value of
    SG_BIG_BUFF.
 
@@ -794,9 +794,9 @@
   swap_cluster
      This is probably the greatest influence on system
      performance. swap_cluster is the number of pages kswapd writes in
-     one turn. You’ll want this value to be large so that kswapd does
-     its I/O in large chunks and the disk doesn’t have to seek as
-     often., but you don’t want it to be too large since that would
+     one turn. You'll want this value to be large so that kswapd does
+     its I/O in large chunks and the disk doesn't have to seek as
+     often., but you don't want it to be too large since that would
      flood the request queue.
 
 overcommit_memory
@@ -1140,7 +1140,7 @@
 accept_source_route
    Should source routed packages be accepted or declined. The
    default is dependent on the kernel configuration. It's 'yes' for
-   routers and 'np' for hosts.
+   routers and 'no' for hosts.
 
 bootp_relay
    Accept packets with source address 0.b.c.d destined not to this
diff -u --recursive --new-file v2.2.1/linux/Documentation/sound/ESS linux/Documentation/sound/ESS
--- v2.2.1/linux/Documentation/sound/ESS	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/sound/ESS	Mon Feb  1 14:04:39 1999
@@ -0,0 +1,33 @@
+Documentation for the ESS AudioDrive chips
+
+In 2.2 kernels the SoundBlaster driver not only tries to detect an ESS chip, it
+tries to detect the type of ESS chip too. The correct detection of the chip 
+doesn't always succeed however, so the default behaviour is 2.0 behaviour
+which means: only detect ES688 and ES1688.
+
+All ESS chips now have a recording level setting. This is a need-to-have for
+people who want to use their ESS for recording sound.
+
+Every chip that's detected as a later-than-es1688 chip has a 6 bits logarithmic
+master volume control.
+
+Every chip that's detected as a ES1887 now has Full Duplex support. Made a 
+little testprogram that showes that is works, haven't seen a real program that
+needs this however.
+
+For ESS chips an additional parameter "esstype" can be specified. This controls
+the (auto) detection of the ESS chips. It can have 3 kinds of values:
+
+-1   Act like 2.0 kernels: only detect ES688 or ES1688.
+0	 Try to auto-detect the chip (may fail for ES1688)
+688  The chip will be treated as  ES688
+1688  ,,  ,,   ,,  ,,    ,,   ,, ES1688
+1868  ,,  ,,   ,,  ,,    ,,   ,, ES1868
+1869  ,,  ,,   ,,  ,,    ,,   ,, ES1869
+1788  ,,  ,,   ,,  ,,    ,,   ,, ES1788
+1887  ,,  ,,   ,,  ,,    ,,   ,, ES1887
+1888  ,,  ,,   ,,  ,,    ,,   ,, ES1888
+
+Because Full Duplex is supported for ES1887 you can specify a second DMA
+channel by specifying module parameter dma16. It can be one of: 0, 1, 3 or 5.
+
diff -u --recursive --new-file v2.2.1/linux/Documentation/sound/OPL3-SA linux/Documentation/sound/OPL3-SA
--- v2.2.1/linux/Documentation/sound/OPL3-SA	Tue Aug 18 22:02:01 1998
+++ linux/Documentation/sound/OPL3-SA	Mon Feb  1 10:41:47 1999
@@ -2,8 +2,7 @@
 
 ---
 Note: This howto only describes how to setup the OPL3-SA1 chip; this info
-does not apply to the SA2, SA3, or SA4. Contact hannu@opensound.com for
-the support details of these other SAx chips.
+does not apply to the SA2, SA3, or SA4. 
 ---
 
 The Yamaha OPL3-SA1 sound chip is usually found built into motherboards, and
diff -u --recursive --new-file v2.2.1/linux/Documentation/video4linux/bttv/INSTALL linux/Documentation/video4linux/bttv/INSTALL
--- v2.2.1/linux/Documentation/video4linux/bttv/INSTALL	Thu Nov 12 16:21:17 1998
+++ linux/Documentation/video4linux/bttv/INSTALL	Sat Feb  6 12:46:20 1999
@@ -41,6 +41,9 @@
    10: Newer Hauppage (Bt878)
    11: Miro PCTV Pro
    12: ADS Tech Channel Surfer TV (and maybe TV+FM)
+   13: AVerMedia TVCapture 98
+   14: Aimslab VHX
+   15: Zoltrix TV-Max
 
   - You may have to adjust BTTV_MAJOR to a different number depending on your
     kernel version. The official number 81 does not work on some setups.
diff -u --recursive --new-file v2.2.1/linux/Documentation/video4linux/bttv/README.FIRST linux/Documentation/video4linux/bttv/README.FIRST
--- v2.2.1/linux/Documentation/video4linux/bttv/README.FIRST	Wed Aug 26 11:37:33 1998
+++ linux/Documentation/video4linux/bttv/README.FIRST	Sat Feb  6 12:46:20 1999
@@ -1,4 +1,4 @@
 o Please direct queries about the in kernel version of this driver to
   Alan Cox first not to Ralph, or better yet join the video4linux mailing
-  list (mail majordomo@phunk.org with "subscribe video4linux")
+  list (mail video4linux-list-request@redhat.com with "subscribe")
 
diff -u --recursive --new-file v2.2.1/linux/MAINTAINERS linux/MAINTAINERS
--- v2.2.1/linux/MAINTAINERS	Wed Jan 20 23:14:04 1999
+++ linux/MAINTAINERS	Sat Feb  6 12:46:20 1999
@@ -530,6 +530,12 @@
 L:	netdev@roxanne.nuclecu.unam.mx
 S:	Maintained
 
+NFS CLIENT
+P:      Trond Myklebust
+M:      trond.myklebust@fys.uio.no
+L:      linux-kernel@vger.rutgers.edu
+S:      Maintained
+
 NI5010 NETWORK DRIVER
 P:     Jan-Pascal van Best and Andreas Mohr
 M:     jvbest@qv3pluto.leidenuniv.nl (Best)
diff -u --recursive --new-file v2.2.1/linux/Makefile linux/Makefile
--- v2.2.1/linux/Makefile	Thu Jan 28 12:58:02 1999
+++ linux/Makefile	Mon Feb  1 12:03:19 1999
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 2
-SUBLEVEL = 1
+SUBLEVEL = 2
 EXTRAVERSION =
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
@@ -221,35 +221,27 @@
 		mkdir include/linux/modules; \
 	fi
 
-oldconfig: symlinks scripts/split-include
+oldconfig: symlinks
 	$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
-	if [ -r include/linux/autoconf.h ]; then \
-	    scripts/split-include include/linux/autoconf.h include/config; \
-	fi
 
-xconfig: symlinks scripts/split-include
+xconfig: symlinks
 	$(MAKE) -C scripts kconfig.tk
 	wish -f scripts/kconfig.tk
-	if [ -r include/linux/autoconf.h ]; then \
-	    scripts/split-include include/linux/autoconf.h include/config; \
-	fi
 
-menuconfig: include/linux/version.h symlinks scripts/split-include
+menuconfig: include/linux/version.h symlinks
 	$(MAKE) -C scripts/lxdialog all
 	$(CONFIG_SHELL) scripts/Menuconfig arch/$(ARCH)/config.in
-	if [ -r include/linux/autoconf.h ]; then \
-	    scripts/split-include include/linux/autoconf.h include/config; \
-	fi
 
-config: symlinks scripts/split-include
+config: symlinks
 	$(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in
-	if [ -r include/linux/autoconf.h ]; then \
-	    scripts/split-include include/linux/autoconf.h include/config; \
-	fi
+
+include/config/MARKER: scripts/split-include include/linux/autoconf.h
+	scripts/split-include include/linux/autoconf.h include/config
+	@ touch include/config/MARKER
 
 linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))
 
-$(patsubst %, _dir_%, $(SUBDIRS)) : dummy
+$(patsubst %, _dir_%, $(SUBDIRS)) : dummy include/config/MARKER
 	$(MAKE) -C $(patsubst _dir_%, %, $@)
 
 $(TOPDIR)/include/linux/version.h: include/linux/version.h
@@ -286,10 +278,10 @@
 	@echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver
 	@mv -f .ver $@
 
-init/version.o: init/version.c include/linux/compile.h
+init/version.o: init/version.c include/linux/compile.h include/config/MARKER
 	$(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c
 
-init/main.o: init/main.c
+init/main.o: init/main.c include/config/MARKER
 	$(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
 
 fs lib mm ipc kernel drivers net: dummy
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.2.1/linux/arch/alpha/config.in	Tue Jan 19 11:32:50 1999
+++ linux/arch/alpha/config.in	Mon Feb  1 12:03:20 1999
@@ -243,7 +243,7 @@
 endmenu
 
 mainmenu_option next_comment
-comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
 bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
 if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v2.2.1/linux/arch/alpha/kernel/entry.S	Mon Jan 25 17:44:34 1999
+++ linux/arch/alpha/kernel/entry.S	Mon Feb  1 10:41:47 1999
@@ -186,6 +186,18 @@
 	jsr	$31,do_entIF
 .end entIF
 
+.align 3
+.globl	entDbg
+.ent	entDbg
+entDbg:
+	SAVE_ALL
+	lda	$8,0x3fff
+	bic	$30,$8,$8
+	lda	$26,ret_from_sys_call
+	jsr	$31,do_entDbg
+.end entDbg
+
+
 /*
  * Fork() is one of the special system calls: it needs to
  * save the callee-saved regs so that the regs can be found
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- v2.2.1/linux/arch/alpha/kernel/osf_sys.c	Wed Jan 20 23:14:04 1999
+++ linux/arch/alpha/kernel/osf_sys.c	Sun Feb 21 11:38:36 1999
@@ -317,8 +317,8 @@
 	struct super_block * sb = inode->i_sb;
 	int error;
 
-	error = -ENOSYS;
-	if (sb->s_op->statfs) {
+	error = -ENODEV;
+	if (sb && sb->s_op && sb->s_op->statfs) {
 		set_fs(KERNEL_DS);
 		error = sb->s_op->statfs(sb, &linux_stat, sizeof(linux_stat));
 		set_fs(USER_DS);
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h
--- v2.2.1/linux/arch/alpha/kernel/proto.h	Wed Jan 13 15:00:41 1999
+++ linux/arch/alpha/kernel/proto.h	Sun Feb 21 19:06:36 1999
@@ -165,7 +165,7 @@
 extern void SMC93x_Init(void);
 
 /* smc37c669.c */
-extern void SMC669_Init(void);
+extern void SMC669_Init(int);
 
 /* es1888.c */
 extern void es1888_init(void);
@@ -187,6 +187,7 @@
 extern void entMM(void);
 extern void entSys(void);
 extern void entUna(void);
+extern void entDbg(void);
 
 /* process.c */
 extern void generic_kill_arch (int mode, char *reboot_cmd);
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/smc37c669.c linux/arch/alpha/kernel/smc37c669.c
--- v2.2.1/linux/arch/alpha/kernel/smc37c669.c	Fri Nov 27 13:09:22 1998
+++ linux/arch/alpha/kernel/smc37c669.c	Sun Feb 21 19:06:36 1999
@@ -862,7 +862,7 @@
 */
 
 SMC37c669_CONFIG_REGS *SMC37c669_detect( 
-    void 
+    int
 );
 
 unsigned int SMC37c669_enable_device( 
@@ -1015,6 +1015,29 @@
     };
 
 /*
+** The following definition is for the MONET (XP1000) IRQ 
+** translation table.
+*/
+static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[]
+__initdata = 
+    { 
+	{ SMC37c669_DEVICE_IRQ_A, -1 }, 
+	{ SMC37c669_DEVICE_IRQ_B, -1 }, 
+	{ SMC37c669_DEVICE_IRQ_C, 6 }, 
+	{ SMC37c669_DEVICE_IRQ_D, 7 }, 
+	{ SMC37c669_DEVICE_IRQ_E, 4 }, 
+	{ SMC37c669_DEVICE_IRQ_F, 3 }, 
+	{ SMC37c669_DEVICE_IRQ_H, -1 }, 
+	{ -1, -1 } /* End of table */
+    };
+
+static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata =
+    {
+	SMC37c669_default_irq_table,
+	SMC37c669_monet_irq_table
+    }; 
+
+/*
 ** DRQ Translation Table
 **
 ** The DRQ translation table is a list of SMC37c669 device and
@@ -1163,7 +1186,7 @@
 **
 **--
 */
-SMC37c669_CONFIG_REGS * __init SMC37c669_detect( void )
+SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index )
 {
     int i;
     SMC37c669_DEVICE_ID_REGISTER id;
@@ -1196,7 +1219,7 @@
 /*
 ** Initialize the IRQ and DRQ translation tables.
 */
-    	    SMC37c669_irq_table = SMC37c669_default_irq_table;
+    	    SMC37c669_irq_table = SMC37c669_irq_tables[ index ];
 	    SMC37c669_drq_table = SMC37c669_default_drq_table;
 /*
 ** erfix
@@ -2516,13 +2539,13 @@
  *      None
  *
  */
-void __init SMC669_Init ( void )
+void __init SMC669_Init ( int index )
 {
     SMC37c669_CONFIG_REGS *SMC_base;
     unsigned long flags;
 
     __save_and_cli(flags);
-    if ( ( SMC_base = SMC37c669_detect( ) ) != NULL ) {
+    if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
 #if SMC_DEBUG
 	SMC37c669_config_mode( TRUE );
 	SMC37c669_dump_registers( );
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
--- v2.2.1/linux/arch/alpha/kernel/sys_dp264.c	Wed Jan 13 15:00:41 1999
+++ linux/arch/alpha/kernel/sys_dp264.c	Sun Feb 21 19:06:36 1999
@@ -316,7 +316,7 @@
 {
 	layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
 	common_pci_fixup(dp264_map_irq, common_swizzle);
-	SMC669_Init();
+	SMC669_Init(0);
 }
 
 static void __init
@@ -325,7 +325,7 @@
 	layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
 	common_pci_fixup(monet_map_irq, monet_swizzle);
 	/* es1888_init(); */ /* later? */
-	SMC669_Init();
+	SMC669_Init(1);
 }
 
 static void __init
@@ -333,7 +333,7 @@
 {
 	layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
 	common_pci_fixup(webbrick_map_irq, common_swizzle);
-	SMC669_Init();
+	SMC669_Init(0);
 }
 
 
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c
--- v2.2.1/linux/arch/alpha/kernel/sys_miata.c	Fri Nov 27 13:09:22 1998
+++ linux/arch/alpha/kernel/sys_miata.c	Sun Feb 21 19:06:36 1999
@@ -267,7 +267,7 @@
 {
 	layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
 	common_pci_fixup(miata_map_irq, miata_swizzle);
-	SMC669_Init(); /* it might be a GL (fails harmlessly if not) */
+	SMC669_Init(0); /* it might be a GL (fails harmlessly if not) */
 	es1888_init();
 }
 
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c
--- v2.2.1/linux/arch/alpha/kernel/sys_sx164.c	Fri Oct 23 22:01:19 1998
+++ linux/arch/alpha/kernel/sys_sx164.c	Sun Feb 21 19:06:36 1999
@@ -183,7 +183,7 @@
 {
 	layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
 	common_pci_fixup(sx164_map_irq, common_swizzle);
-	SMC669_Init();
+	SMC669_Init(0);
 }
 
 
diff -u --recursive --new-file v2.2.1/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.2.1/linux/arch/alpha/kernel/traps.c	Fri Oct 23 22:01:19 1998
+++ linux/arch/alpha/kernel/traps.c	Mon Feb  1 10:41:47 1999
@@ -121,9 +121,9 @@
 #endif
 
 asmlinkage void
-do_entArith(unsigned long summary, unsigned long write_mask, unsigned long a2,
-	    unsigned long a3, unsigned long a4, unsigned long a5,
-	    struct pt_regs regs)
+do_entArith(unsigned long summary, unsigned long write_mask,
+	    unsigned long a2, unsigned long a3, unsigned long a4,
+	    unsigned long a5, struct pt_regs regs)
 {
 	if ((summary & 1)) {
 		/*
@@ -145,9 +145,10 @@
 	unlock_kernel();
 }
 
-asmlinkage void do_entIF(unsigned long type, unsigned long a1,
-			 unsigned long a2, unsigned long a3, unsigned long a4,
-			 unsigned long a5, struct pt_regs regs)
+asmlinkage void
+do_entIF(unsigned long type, unsigned long a1,
+	 unsigned long a2, unsigned long a3, unsigned long a4,
+	 unsigned long a5, struct pt_regs regs)
 {
 	lock_kernel();
 	die_if_kernel("Instruction fault", &regs, type, 0);
@@ -230,6 +231,25 @@
 	unlock_kernel();
 }
 
+/* There is an ifdef in the PALcode in MILO that enables a 
+   "kernel debugging entry point" as an unprivilaged call_pal.
+
+   We don't want to have anything to do with it, but unfortunately
+   several versions of MILO included in distributions have it enabled,
+   and if we don't put something on the entry point we'll oops.  */
+
+asmlinkage void
+do_entDbg(unsigned long type, unsigned long a1,
+	  unsigned long a2, unsigned long a3, unsigned long a4,
+	  unsigned long a5, struct pt_regs regs)
+{
+	lock_kernel();
+	die_if_kernel("Instruction fault", &regs, type, 0);
+	force_sig(SIGILL, current);
+	unlock_kernel();
+}
+
+
 /*
  * entUna has a different register layout to be reasonably simple. It
  * needs access to all the integer registers (the kernel doesn't use
@@ -895,4 +915,5 @@
 	wrent(entIF, 3);
 	wrent(entUna, 4);
 	wrent(entSys, 5);
+	wrent(entDbg, 6);
 }
diff -u --recursive --new-file v2.2.1/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.2.1/linux/arch/i386/config.in	Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/config.in	Mon Feb  1 12:03:20 1999
@@ -158,7 +158,7 @@
 endmenu
 
 mainmenu_option next_comment
-comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
 bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
 if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
diff -u --recursive --new-file v2.2.1/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.2.1/linux/arch/i386/defconfig	Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/defconfig	Tue Feb 16 11:50:11 1999
@@ -241,7 +241,7 @@
 # CONFIG_ISDN is not set
 
 #
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+# Old CD-ROM drivers (not SCSI, not IDE)
 #
 # CONFIG_CD_NO_IDESCSI is not set
 
diff -u --recursive --new-file v2.2.1/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.2.1/linux/arch/i386/kernel/i386_ksyms.c	Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/kernel/i386_ksyms.c	Wed Feb 17 09:34:13 1999
@@ -43,6 +43,7 @@
 
 EXPORT_SYMBOL_NOVERS(__down_failed);
 EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
+EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
 EXPORT_SYMBOL_NOVERS(__up_wakeup);
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_partial_copy);
diff -u --recursive --new-file v2.2.1/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.2.1/linux/arch/i386/kernel/io_apic.c	Mon Dec 28 15:00:52 1998
+++ linux/arch/i386/kernel/io_apic.c	Tue Feb 16 14:20:05 1999
@@ -202,7 +202,7 @@
 DO_ACTION( mask,    0, |= 0x00010000, io_apic_sync())		/* mask = 1 */
 DO_ACTION( unmask,  0, &= 0xfffeffff, )				/* mask = 0 */
 
-static void __init clear_IO_APIC_pin(unsigned int pin)
+static void clear_IO_APIC_pin(unsigned int pin)
 {
 	struct IO_APIC_route_entry entry;
 
@@ -215,6 +215,13 @@
 	io_apic_write(0x11 + 2 * pin, *(((int *)&entry) + 1));
 }
 
+static void clear_IO_APIC (void)
+{
+	int pin;
+
+	for (pin = 0; pin < nr_ioapic_registers; pin++)
+		clear_IO_APIC_pin(pin);
+}
 
 /*
  * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
@@ -562,6 +569,9 @@
 		printk("WARNING: ASSIGN_IRQ_VECTOR wrapped back to %02X\n",
 		       current_vector);
 	}
+	if (current_vector == SYSCALL_VECTOR)
+		panic("ran out of interrupt sources!");
+
 	IO_APIC_VECTOR(irq) = current_vector;
 	return current_vector;
 }
@@ -625,7 +635,7 @@
 /*
  * Set up a certain pin as ExtINT delivered interrupt
  */
-void __init setup_ExtINT_pin(unsigned int pin)
+void __init setup_ExtINT_pin(unsigned int pin, int irq)
 {
 	struct IO_APIC_route_entry entry;
 
@@ -635,11 +645,16 @@
 	memset(&entry,0,sizeof(entry));
 
 	entry.delivery_mode = dest_ExtINT;
-	entry.dest_mode = 1;				/* logical delivery */
+	entry.dest_mode = 0;				/* physical delivery */
 	entry.mask = 0;					/* unmask IRQ now */
-	entry.dest.logical.logical_dest = 0x01;		/* logical CPU #0 */
+	/*
+	 * We use physical delivery to get the timer IRQ
+	 * to the boot CPU. 'boot_cpu_id' is the physical
+	 * APIC ID of the boot CPU.
+	 */
+	entry.dest.physical.physical_dest = boot_cpu_id;
 
-	entry.vector = 0;				/* it's ignored */
+	entry.vector = assign_irq_vector(irq);
 
 	entry.polarity = 0;
 	entry.trigger = 0;
@@ -681,9 +696,11 @@
 
 	printk(".... register #01: %08X\n", *(int *)&reg_01);
 	printk(".......     : max redirection entries: %04X\n", reg_01.entries);
-	if (	(reg_01.entries != 0x0f) && /* ISA-only Neptune boards */
-		(reg_01.entries != 0x17) && /* ISA+PCI boards */
-		(reg_01.entries != 0x3F)    /* Xeon boards */
+	if (	(reg_01.entries != 0x0f) && /* older (Neptune) boards */
+		(reg_01.entries != 0x17) && /* typical ISA+PCI boards */
+		(reg_01.entries != 0x1b) && /* Compaq Proliant boards */
+		(reg_01.entries != 0x1f) && /* dual Xeon boards */
+		(reg_01.entries != 0x3F)    /* bigger Xeon boards */
 	)
 		UNEXPECTED_IO_APIC();
 	if (reg_01.entries == 0x0f)
@@ -754,7 +771,7 @@
 
 static void __init init_sym_mode(void)
 {
-	int i, pin;
+	int i;
 
 	for (i = 0; i < PIN_MAP_SIZE; i++) {
 		irq_2_pin[i].pin = -1;
@@ -784,8 +801,7 @@
 	/*
 	 * Do not trust the IO-APIC being empty at bootup
 	 */
-	for (pin = 0; pin < nr_ioapic_registers; pin++)
-		clear_IO_APIC_pin(pin);
+	clear_IO_APIC();
 }
 
 /*
@@ -793,6 +809,15 @@
  */
 void init_pic_mode(void)
 {
+	/*
+	 * Clear the IO-APIC before rebooting:
+	 */
+	clear_IO_APIC();
+
+	/*
+	 * Put it back into PIC mode (has an effect only on
+	 * certain boards)
+	 */
 	printk("disabling symmetric IO mode... ");
 		outb_p(0x70, 0x22);
 		outb_p(0x00, 0x23);
@@ -1143,7 +1168,7 @@
 	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
 	 */
 	for (i = 0; i < NR_IRQS ; i++) {
-		if (IO_APIC_IRQ(i)) {
+		if (IO_APIC_VECTOR(i) > 0) {
 			if (IO_APIC_irq_trigger(i))
 				irq_desc[i].handler = &ioapic_level_irq_type;
 			else
@@ -1153,8 +1178,15 @@
 			 */
 			if (i < 16)
 				disable_8259A_irq(i);
-		}
+		} else
+			/*
+			 * we have no business changing low ISA
+			 * IRQs.
+			 */
+			if (IO_APIC_IRQ(i))
+				irq_desc[i].handler = &no_irq_type;
 	}
+	init_IRQ_SMP();
 }
 
 /*
@@ -1178,7 +1210,7 @@
 
 		if (pin2 != -1) {
 			printk(".. (found pin %d) ...", pin2);
-			setup_ExtINT_pin(pin2);
+			setup_ExtINT_pin(pin2, 0);
 			make_8259A_irq(0);
 		}
 
@@ -1258,14 +1290,12 @@
 		construct_default_ISA_mptable();
 	}
 
-	init_IO_APIC_traps();
-
 	/*
 	 * Set up the IO-APIC IRQ routing table by parsing the MP-BIOS
 	 * mptable:
 	 */
 	setup_IO_APIC_irqs();
-	init_IRQ_SMP();
+	init_IO_APIC_traps();
 	check_timer();
 
 	print_IO_APIC();
diff -u --recursive --new-file v2.2.1/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.2.1/linux/arch/i386/kernel/irq.c	Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/kernel/irq.c	Tue Feb 16 14:20:05 1999
@@ -70,11 +70,34 @@
  */
 spinlock_t irq_controller_lock;
 
-
 /*
  * Dummy controller type for unused interrupts
  */
-static void do_none(unsigned int irq, struct pt_regs * regs) { }
+static void do_none(unsigned int irq, struct pt_regs * regs)
+{
+	/*
+	 * we are careful. While for ISA irqs it's common to happen
+	 * outside of any driver (think autodetection), this is not
+	 * at all nice for PCI interrupts. So we are stricter and
+	 * print a warning when such spurious interrupts happen.
+	 * Spurious interrupts can confuse other drivers if the PCI
+	 * IRQ line is shared.
+	 *
+	 * Such spurious interrupts are either driver bugs, or
+	 * sometimes hw (chipset) bugs.
+	 */
+	printk("unexpected IRQ vector %d on CPU#%d!\n",irq, smp_processor_id());
+
+#ifdef __SMP__
+	/*
+	 * [currently unexpected vectors happen only on SMP and APIC.
+	 *  if we want to have non-APIC and non-8259A controllers
+	 *  in the future with unexpected vectors, this ack should
+	 *  probably be made controller-specific.]
+	 */
+	ack_APIC_irq();
+#endif
+}
 static void enable_none(unsigned int irq) { }
 static void disable_none(unsigned int irq) { }
 
@@ -82,7 +105,7 @@
 #define startup_none	enable_none
 #define shutdown_none	disable_none
 
-static struct hw_interrupt_type no_irq_type = {
+struct hw_interrupt_type no_irq_type = {
 	"none",
 	startup_none,
 	shutdown_none,
@@ -141,10 +164,10 @@
  * fed to the CPU IRQ line directly.
  *
  * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
- * this 'mixed mode' IRQ handling costs us one more branch in do_IRQ,
- * but we have _much_ higher compatibility and robustness this way.
+ * this 'mixed mode' IRQ handling costs nothing because it's only used
+ * at IRQ setup time.
  */
-unsigned long long io_apic_irqs = 0;
+unsigned long io_apic_irqs = 0;
 
 /*
  * These have to be protected by the irq controller spinlock
@@ -254,32 +277,43 @@
 
 
 BUILD_COMMON_IRQ()
+
+#define BI(x,y) \
+	BUILD_IRQ(##x##y)
+
+#define BUILD_16_IRQS(x) \
+	BI(x,0) BI(x,1) BI(x,2) BI(x,3) \
+	BI(x,4) BI(x,5) BI(x,6) BI(x,7) \
+	BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
+	BI(x,c) BI(x,d) BI(x,e) BI(x,f)
+
 /*
  * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
+ * (these are usually mapped to vectors 0x20-0x30)
  */
-BUILD_IRQ(0)  BUILD_IRQ(1)  BUILD_IRQ(2)  BUILD_IRQ(3)
-BUILD_IRQ(4)  BUILD_IRQ(5)  BUILD_IRQ(6)  BUILD_IRQ(7)
-BUILD_IRQ(8)  BUILD_IRQ(9)  BUILD_IRQ(10) BUILD_IRQ(11)
-BUILD_IRQ(12) BUILD_IRQ(13) BUILD_IRQ(14) BUILD_IRQ(15)
+BUILD_16_IRQS(0x0)
 
 #ifdef CONFIG_X86_IO_APIC
 /*
- * The IO-APIC gives us many more interrupt sources..
+ * The IO-APIC gives us many more interrupt sources. Most of these 
+ * are unused but an SMP system is supposed to have enough memory ...
+ * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
+ * across the spectrum, so we really want to be prepared to get all
+ * of these. Plus, more powerful systems might have more than 64
+ * IO-APIC registers.
+ *
+ * (these are usually mapped into the 0x30-0xff vector range)
  */
-BUILD_IRQ(16) BUILD_IRQ(17) BUILD_IRQ(18) BUILD_IRQ(19)
-BUILD_IRQ(20) BUILD_IRQ(21) BUILD_IRQ(22) BUILD_IRQ(23)
-BUILD_IRQ(24) BUILD_IRQ(25) BUILD_IRQ(26) BUILD_IRQ(27)
-BUILD_IRQ(28) BUILD_IRQ(29) BUILD_IRQ(30) BUILD_IRQ(31)
-BUILD_IRQ(32) BUILD_IRQ(33) BUILD_IRQ(34) BUILD_IRQ(35)
-BUILD_IRQ(36) BUILD_IRQ(37) BUILD_IRQ(38) BUILD_IRQ(39)
-BUILD_IRQ(40) BUILD_IRQ(41) BUILD_IRQ(42) BUILD_IRQ(43)
-BUILD_IRQ(44) BUILD_IRQ(45) BUILD_IRQ(46) BUILD_IRQ(47)
-BUILD_IRQ(48) BUILD_IRQ(49) BUILD_IRQ(50) BUILD_IRQ(51)
-BUILD_IRQ(52) BUILD_IRQ(53) BUILD_IRQ(54) BUILD_IRQ(55)
-BUILD_IRQ(56) BUILD_IRQ(57) BUILD_IRQ(58) BUILD_IRQ(59)
-BUILD_IRQ(60) BUILD_IRQ(61) BUILD_IRQ(62) BUILD_IRQ(63)
+                   BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
+BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
+BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
+BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
 #endif
 
+#undef BUILD_16_IRQS
+#undef BI
+
+
 #ifdef __SMP__
 /*
  * The following vectors are part of the Linux architecture, there
@@ -303,37 +337,35 @@
 
 #endif
 
+#define IRQ(x,y) \
+	IRQ##x##y##_interrupt
+
+#define IRQLIST_16(x) \
+	IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
+	IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
+	IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
+	IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
+
 static void (*interrupt[NR_IRQS])(void) = {
-	IRQ0_interrupt, IRQ1_interrupt, IRQ2_interrupt, IRQ3_interrupt,
-	IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
-	IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
-	IRQ12_interrupt, IRQ13_interrupt, IRQ14_interrupt, IRQ15_interrupt
+	IRQLIST_16(0x0),
+
 #ifdef CONFIG_X86_IO_APIC
-	,IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,
-	IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,
-	IRQ24_interrupt, IRQ25_interrupt, IRQ26_interrupt, IRQ27_interrupt,
-	IRQ28_interrupt, IRQ29_interrupt,
-	IRQ30_interrupt, IRQ31_interrupt, IRQ32_interrupt, IRQ33_interrupt,
-	IRQ34_interrupt, IRQ35_interrupt, IRQ36_interrupt, IRQ37_interrupt,
-	IRQ38_interrupt, IRQ39_interrupt,
-	IRQ40_interrupt, IRQ41_interrupt, IRQ42_interrupt, IRQ43_interrupt,
-	IRQ44_interrupt, IRQ45_interrupt, IRQ46_interrupt, IRQ47_interrupt,
-	IRQ48_interrupt, IRQ49_interrupt,
-	IRQ50_interrupt, IRQ51_interrupt, IRQ52_interrupt, IRQ53_interrupt,
-	IRQ54_interrupt, IRQ55_interrupt, IRQ56_interrupt, IRQ57_interrupt,
-	IRQ58_interrupt, IRQ59_interrupt,
-	IRQ60_interrupt, IRQ61_interrupt, IRQ62_interrupt, IRQ63_interrupt
+	                 IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
+	IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
+	IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
+	IRQLIST_16(0xc), IRQLIST_16(0xd)
 #endif
 };
 
+#undef IRQ
+#undef IRQLIST_16
+
 
 /*
- * Initial irq handlers.
+ * Special irq handlers.
  */
 
-void no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-}
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
 
 #ifndef CONFIG_VISWS
 /*
@@ -770,7 +802,7 @@
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 */
-	unsigned int irq = regs.orig_eax & 0xff;
+	int irq = regs.orig_eax & 0xff; /* subtle, see irq.h */
 	int cpu = smp_processor_id();
 
 	kstat.irqs[cpu][irq]++;
@@ -986,42 +1018,6 @@
 	return irq_found;
 }
 
-/*
- * Silly, horrible hack
- */
-static char uglybuffer[10*256];
-
-__asm__("\n" __ALIGN_STR"\n"
-	"common_unexpected:\n\t"
-	SAVE_ALL
-	"pushl $ret_from_intr\n\t"
-	"jmp strange_interrupt");
-
-void strange_interrupt(int irqnum)
-{
-	printk("Unexpected interrupt %d\n", irqnum & 255);
-	for (;;);
-}
-
-extern int common_unexpected;
-__initfunc(void init_unexpected_irq(void))
-{
-	int i;
-	for (i = 0; i < 256; i++) {
-		char *code = uglybuffer + 10*i;
-		unsigned long jumpto = (unsigned long) &common_unexpected;
-
-		jumpto -= (unsigned long)(code+10);
-		code[0] = 0x68;		/* pushl */
-		*(int *)(code+1) = i - 512;
-		code[5] = 0xe9;		/* jmp */
-		*(int *)(code+6) = jumpto;
-
-		set_intr_gate(i,code);
-	}
-}
-
-
 void init_ISA_irqs (void)
 {
 	int i;
@@ -1033,7 +1029,7 @@
 
 		if (i < 16) {
 			/*
-			 * 16 old-style INTA-cycle interrupt gates:
+			 * 16 old-style INTA-cycle interrupts:
 			 */
 			irq_desc[i].handler = &i8259A_irq_type;
 		} else {
@@ -1054,9 +1050,16 @@
 #else
 	init_VISWS_APIC_irqs();
 #endif
-
-	for (i = 0; i < 16; i++)
-		set_intr_gate(0x20+i,interrupt[i]);
+	/*
+	 * Cover the whole vector space, no vector can escape
+	 * us. (some of these will be overridden and become
+	 * 'special' SMP interrupts)
+	 */
+	for (i = 0; i < NR_IRQS; i++) {
+		int vector = FIRST_EXTERNAL_VECTOR + i;
+		if (vector != SYSCALL_VECTOR) 
+			set_intr_gate(vector, interrupt[i]);
+	}
 
 #ifdef __SMP__	
 
@@ -1067,13 +1070,9 @@
 	set_intr_gate(IRQ0_TRAP_VECTOR, interrupt[0]);
 
 	/*
-	 * The reschedule interrupt slowly changes it's functionality,
-	 * while so far it was a kind of broadcasted timer interrupt,
-	 * in the future it should become a CPU-to-CPU rescheduling IPI,
-	 * driven by schedule() ?
+	 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
+	 * IPI, driven by wakeup.
 	 */
-
-	/* IPI for rescheduling */
 	set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
 
 	/* IPI for invalidation */
diff -u --recursive --new-file v2.2.1/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.2.1/linux/arch/i386/kernel/irq.h	Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/kernel/irq.h	Mon Feb 22 14:51:46 1999
@@ -16,6 +16,7 @@
 	void (*disable)(unsigned int irq);
 };
 
+extern struct hw_interrupt_type no_irq_type;
 
 /*
  * IRQ line status.
@@ -41,6 +42,18 @@
 } irq_desc_t;
 
 /*
+ * IDT vectors usable for external interrupt sources start
+ * at 0x20:
+ */
+#define FIRST_EXTERNAL_VECTOR	0x20
+
+#define SYSCALL_VECTOR		0x80
+
+/*
+ * Vectors 0x20-0x2f are used for ISA interrupts.
+ */
+
+/*
  * Special IRQ vectors used by the SMP architecture:
  *
  * (some of the following vectors are 'rare', they might be merged
@@ -54,7 +67,7 @@
 #define MTRR_CHANGE_VECTOR	0x50
 
 /*
- * First vector available to drivers: (vectors 0x51-0xfe)
+ * First APIC vector available to drivers: (vectors 0x51-0xfe)
  */
 #define IRQ0_TRAP_VECTOR	0x51
 
@@ -94,7 +107,9 @@
 extern void init_pic_mode(void);
 extern void print_IO_APIC(void);
 
-extern unsigned long long io_apic_irqs;
+extern unsigned long io_apic_irqs;
+
+extern char _stext, _etext;
 
 #define MAX_IRQ_SOURCES 128
 #define MAX_MP_BUSSES 32
@@ -126,7 +141,7 @@
 	hardirq_exit(cpu);
 }
 
-#define IO_APIC_IRQ(x) ((1<<x) & io_apic_irqs)
+#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
 
 #else
 
@@ -201,6 +216,13 @@
 	"pushl $ret_from_intr\n\t" \
 	"jmp "SYMBOL_NAME_STR(do_IRQ));
 
+/*
+ * subtle. orig_eax is used by the signal code to distinct between
+ * system calls and interrupted 'random user-space'. Thus we have
+ * to put a negative value into orig_eax here. (the problem is that
+ * both system calls and IRQs want to have small integer numbers in
+ * orig_eax, and the syscall code has won the optimization conflict ;)
+ */
 #define BUILD_IRQ(nr) \
 asmlinkage void IRQ_NAME(nr); \
 __asm__( \
@@ -216,7 +238,6 @@
 static inline void x86_do_profile (unsigned long eip)
 {
 	if (prof_buffer && current->pid) {
-		extern int _stext;
 		eip -= (unsigned long) &_stext;
 		eip >>= prof_shift;
 		/*
diff -u --recursive --new-file v2.2.1/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.2.1/linux/arch/i386/kernel/setup.c	Mon Jan 25 17:44:34 1999
+++ linux/arch/i386/kernel/setup.c	Tue Feb 16 11:34:29 1999
@@ -807,7 +807,7 @@
 			       c->x86_model,
 			       c->x86_model_id[0] ? c->x86_model_id : "unknown");
 		
-		if (c->x86_mask)
+		if (c->x86_mask || c->cpuid_level >= 0)
 			p += sprintf(p, "stepping\t: %d\n", c->x86_mask);
 		else
 			p += sprintf(p, "stepping\t: unknown\n");
diff -u --recursive --new-file v2.2.1/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.2.1/linux/arch/i386/kernel/smp.c	Mon Jan 25 17:44:34 1999
+++ linux/arch/i386/kernel/smp.c	Tue Feb 16 14:20:05 1999
@@ -42,7 +42,7 @@
 
 #include "irq.h"
 
-extern unsigned long start_kernel, _etext;
+extern unsigned long start_kernel;
 extern void update_one_process( struct task_struct *p,
 				unsigned long ticks, unsigned long user,
 				unsigned long system, int cpu);
@@ -147,6 +147,17 @@
 #define APIC_DEFAULT_PHYS_BASE 0xfee00000
 
 /*
+ * Reads and clears the Pentium Timestamp-Counter
+ */
+#define READ_TSC(x)	__asm__ __volatile__ (  "rdtsc" \
+				:"=a" (((unsigned long*)&(x))[0]),  \
+				 "=d" (((unsigned long*)&(x))[1]))
+
+#define CLEAR_TSC \
+	__asm__ __volatile__ ("\t.byte 0x0f, 0x30;\n"::\
+		"a"(0x00001000), "d"(0x00001000), "c"(0x10):"memory")
+
+/*
  *	Setup routine for controlling SMP activation
  *
  *	Command-line option of "nosmp" or "maxcpus=0" will disable SMP
@@ -308,8 +319,17 @@
 						printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS);
 					else
 					{
+						int ver = m->mpc_apicver;
+
 						cpu_present_map|=(1<<m->mpc_apicid);
-						apic_version[m->mpc_apicid]=m->mpc_apicver;
+						/*
+						 * Validate version
+						 */
+						if (ver == 0x0) {
+							printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
+							ver = 0x10;
+						}
+						apic_version[m->mpc_apicid] = ver;
 					}
 				}
 				mpt+=sizeof(*m);
@@ -710,24 +730,19 @@
 	value |= 0xff;			/* Set spurious IRQ vector to 0xff */
  	apic_write(APIC_SPIV,value);
 
- 	value = apic_read(APIC_TASKPRI);
- 	value &= ~APIC_TPRI_MASK;	/* Set Task Priority to 'accept all' */
- 	apic_write(APIC_TASKPRI,value);
-
 	/*
-	 * Set arbitrarion priority to 0
+	 * Set Task Priority to 'accept all'
 	 */
- 	value = apic_read(APIC_ARBPRI);
- 	value &= ~APIC_ARBPRI_MASK;
- 	apic_write(APIC_ARBPRI, value);
+ 	value = apic_read(APIC_TASKPRI);
+ 	value &= ~APIC_TPRI_MASK;
+ 	apic_write(APIC_TASKPRI,value);
 
 	/*
-	 * Set the logical destination ID to 'all', just to be safe.
+	 * Clear the logical destination ID, just to be safe.
 	 * also, put the APIC into flat delivery mode.
 	 */
  	value = apic_read(APIC_LDR);
 	value &= ~APIC_LDR_MASK;
-	value |= SET_APIC_LOGICAL_ID(0xff);
  	apic_write(APIC_LDR,value);
 
  	value = apic_read(APIC_DFR);
@@ -735,8 +750,6 @@
  	apic_write(APIC_DFR, value);
 
 	udelay(100);			/* B safe */
-	ack_APIC_irq();
-	udelay(100);
 }
 
 unsigned long __init init_smp_mappings(unsigned long memory_start)
@@ -1802,8 +1815,10 @@
  */
 asmlinkage void smp_spurious_interrupt(void)
 {
-	/* ack_APIC_irq();   see sw-dev-man vol 3, chapter 7.4.13.5 */
-	printk("spurious APIC interrupt, ayiee, should never happen.\n");
+	ack_APIC_irq();
+	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
+	printk("spurious APIC interrupt on CPU#%d, should never happen.\n",
+			smp_processor_id());
 }
 
 /*
@@ -1815,10 +1830,6 @@
  * closely follows bus clocks.
  */
 
-#define RDTSC(x)	__asm__ __volatile__ (  "rdtsc" \
-				:"=a" (((unsigned long*)&x)[0]),  \
-				 "=d" (((unsigned long*)&x)[1]))
-
 /*
  * The timer chip is already set up at HZ interrupts per second here,
  * but we do not accept timer interrupts yet. We only allow the BP
@@ -1937,7 +1948,7 @@
 	/*
 	 * We wrapped around just now. Let's start:
 	 */
-	RDTSC(t1);
+	READ_TSC(t1);
 	tt1=apic_read(APIC_TMCCT);
 
 #define LOOPS (HZ/10)
@@ -1948,7 +1959,7 @@
 		wait_8254_wraparound ();
 
 	tt2=apic_read(APIC_TMCCT);
-	RDTSC(t2);
+	READ_TSC(t2);
 
 	/*
 	 * The APIC bus clock counter is 32 bits only, it
@@ -2058,3 +2069,4 @@
 }
 
 #undef APIC_DIVISOR
+
diff -u --recursive --new-file v2.2.1/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v2.2.1/linux/arch/i386/kernel/traps.c	Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/kernel/traps.c	Tue Feb 16 14:20:05 1999
@@ -42,6 +42,8 @@
 #include <asm/lithium.h>
 #endif
 
+#include "irq.h"
+
 asmlinkage int system_call(void);
 asmlinkage void lcall7(void);
 
@@ -125,7 +127,6 @@
 	unsigned long esp;
 	unsigned short ss;
 	unsigned long *stack, addr, module_start, module_end;
-	extern char _stext, _etext;
 
 	esp = (unsigned long) (1+regs);
 	ss = __KERNEL_DS;
@@ -669,9 +670,6 @@
 #endif
 void __init trap_init(void)
 {
-	/* Initially up all of the IDT to jump to unexpected */
-	init_unexpected_irq();
-
 	if (readl(0x0FFFD9) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
 		EISA_bus = 1;
 	set_call_gate(&default_ldt,lcall7);
@@ -693,7 +691,7 @@
 	set_trap_gate(15,&spurious_interrupt_bug);
 	set_trap_gate(16,&coprocessor_error);
 	set_trap_gate(17,&alignment_check);
-	set_system_gate(0x80,&system_call);
+	set_system_gate(SYSCALL_VECTOR,&system_call);
 
 	/* set up GDT task & ldt entries */
 	set_tss_desc(0, &init_task.tss);
diff -u --recursive --new-file v2.2.1/linux/arch/i386/lib/semaphore.S linux/arch/i386/lib/semaphore.S
--- v2.2.1/linux/arch/i386/lib/semaphore.S	Tue Oct 14 18:24:09 1997
+++ linux/arch/i386/lib/semaphore.S	Wed Feb 17 09:34:13 1999
@@ -31,6 +31,15 @@
 	popl %edx	/* restore %edx */
 	ret
 
+/* Don't save/restore %eax, because that will be our return value */
+ENTRY(__down_failed_trylock)
+	pushl %edx	/* save %edx */
+	pushl %ecx	/* save %ecx (and argument) */
+	call SYMBOL_NAME(__down_trylock)
+	popl %ecx	/* restore %ecx (count on __down_trylock not changing it) */
+	popl %edx	/* restore %edx */
+	ret
+
 ENTRY(__up_wakeup)
 	pushl %eax	/* save %eax */
 	pushl %edx	/* save %edx */
diff -u --recursive --new-file v2.2.1/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.2.1/linux/arch/m68k/config.in	Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/config.in	Mon Feb  1 12:03:20 1999
@@ -346,13 +346,13 @@
 source fs/Config.in
 
 if [ "$CONFIG_VME" = "n" ]; then
+  mainmenu_option next_comment
+  comment 'Console drivers'
   if [ "$CONFIG_HP300" = "y" ]; then
     bool 'Frame buffer support' CONFIG_FB
   else
     define_bool CONFIG_FB y
   fi
-  mainmenu_option next_comment
-  comment 'Console drivers'
   source drivers/video/Config.in
   endmenu
 fi
diff -u --recursive --new-file v2.2.1/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.2.1/linux/arch/mips/config.in	Tue Jan 19 11:32:51 1999
+++ linux/arch/mips/config.in	Mon Feb  1 12:03:20 1999
@@ -179,7 +179,7 @@
 	endmenu
 
 	mainmenu_option next_comment
-	comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
+	comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
 	bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
 	if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
diff -u --recursive --new-file v2.2.1/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.2.1/linux/arch/ppc/config.in	Tue Jan 19 11:32:51 1999
+++ linux/arch/ppc/config.in	Mon Feb  1 12:03:20 1999
@@ -152,7 +152,7 @@
 endmenu
 
 mainmenu_option next_comment
-comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
 bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
 if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
diff -u --recursive --new-file v2.2.1/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.2.1/linux/drivers/block/genhd.c	Wed Jan 13 15:00:41 1999
+++ linux/drivers/block/genhd.c	Mon Feb  1 17:25:53 1999
@@ -130,6 +130,14 @@
 		SYS_IND(p) == LINUX_EXTENDED_PARTITION);
 }
 
+static int sector_partition_scale(kdev_t dev)
+{
+       if (hardsect_size[MAJOR(dev)] != NULL)
+               return (hardsect_size[MAJOR(dev)][MINOR(dev)]/512);
+       else
+               return (1);
+}
+
 static unsigned int get_ptable_blocksize(kdev_t dev)
 {
   int ret = 1024;
@@ -149,6 +157,7 @@
    * the natural blocksize for the device so that we don't have to try
    * and read partial sectors.  Anything smaller should be just fine.
    */
+
   switch( blksize_size[MAJOR(dev)][MINOR(dev)] )
     {
     case 2048:
@@ -196,6 +205,7 @@
 	struct partition *p;
 	unsigned long first_sector, first_size, this_sector, this_size;
 	int mask = (1 << hd->minor_shift) - 1;
+	int sector_size = sector_partition_scale(dev);
 	int i;
 
 	first_sector = hd->part[MINOR(dev)].start_sect;
@@ -233,22 +243,22 @@
 		 * First process the data partition(s)
 		 */
 		for (i=0; i<4; i++, p++) {
-		    if (!NR_SECTS(p) || is_extended_partition(p))
-		      continue;
+			if (!NR_SECTS(p) || is_extended_partition(p))
+				continue;
 
-		    /* Check the 3rd and 4th entries -
-		       these sometimes contain random garbage */
-		    if (i >= 2
-			&& START_SECT(p) + NR_SECTS(p) > this_size
-			&& (this_sector + START_SECT(p) < first_sector ||
-			    this_sector + START_SECT(p) + NR_SECTS(p) >
-			     first_sector + first_size))
-		      continue;
-
-		    add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
-		    current_minor++;
-		    if ((current_minor & mask) == 0)
-		      goto done;
+			/* Check the 3rd and 4th entries -
+			   these sometimes contain random garbage */
+			if (i >= 2
+				&& START_SECT(p) + NR_SECTS(p) > this_size
+				&& (this_sector + START_SECT(p) < first_sector ||
+				    this_sector + START_SECT(p) + NR_SECTS(p) >
+				     first_sector + first_size))
+				continue;
+
+			add_partition(hd, current_minor, this_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size);
+			current_minor++;
+			if ((current_minor & mask) == 0)
+				goto done;
 		}
 		/*
 		 * Next, process the (first) extended partition, if present.
@@ -262,20 +272,21 @@
 		 */
 		p -= 4;
 		for (i=0; i<4; i++, p++)
-		  if(NR_SECTS(p) && is_extended_partition(p))
-		    break;
+			if(NR_SECTS(p) && is_extended_partition(p))
+				break;
 		if (i == 4)
-		  goto done;	 /* nothing left to do */
+			goto done;	 /* nothing left to do */
 
-		hd->part[current_minor].nr_sects = NR_SECTS(p);
-		hd->part[current_minor].start_sect = first_sector + START_SECT(p);
-		this_sector = first_sector + START_SECT(p);
+		hd->part[current_minor].nr_sects = NR_SECTS(p) * sector_size; /* JSt */
+		hd->part[current_minor].start_sect = first_sector + START_SECT(p) * sector_size;
+		this_sector = first_sector + START_SECT(p) * sector_size;
 		dev = MKDEV(hd->major, current_minor);
 		brelse(bh);
 	}
 done:
 	brelse(bh);
 }
+
 #ifdef CONFIG_SOLARIS_X86_PARTITION
 static void
 solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) {
@@ -317,11 +328,13 @@
 #endif
 
 #ifdef CONFIG_BSD_DISKLABEL
-static void check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p)
+static void check_and_add_bsd_partition(struct gendisk *hd,
+					struct bsd_partition *bsd_p, kdev_t dev)
 {
 	struct hd_struct *lin_p;
 		/* check relative position of partitions.  */
-	for (lin_p = hd->part + 1; lin_p - hd->part < current_minor; lin_p++) {
+	for (lin_p = hd->part + 1 + MINOR(dev);
+	     lin_p - hd->part - MINOR(dev) < current_minor; lin_p++) {
 			/* no relationship -> try again */
 		if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset 
 			|| lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size)
@@ -383,7 +396,7 @@
 			break;
 
 		if (p->p_fstype != BSD_FS_UNUSED) 
-			check_and_add_bsd_partition(hd, p);
+			check_and_add_bsd_partition(hd, p, dev);
 	}
 	brelse(bh);
 
@@ -436,6 +449,7 @@
 	struct partition *p;
 	unsigned char *data;
 	int mask = (1 << hd->minor_shift) - 1;
+	int sector_size = sector_partition_scale(dev);
 #ifdef CONFIG_BSD_DISKLABEL
 	/* no bsd disklabel as a default */
 	kdev_t bsd_kdev = 0;
@@ -538,7 +552,7 @@
 	for (i=1 ; i<=4 ; minor++,i++,p++) {
 		if (!NR_SECTS(p))
 			continue;
-		add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
+               add_partition(hd, minor, first_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size);
 		if (is_extended_partition(p)) {
 			printk(" <");
 			/*
@@ -790,7 +804,7 @@
 	struct sgi_partition *p;
 #define SGI_LABEL_MAGIC 0x0be5a941
 
-	if(!(bh = bread(dev, 0, 1024))) {
+	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
 		printk("Dev %s: unable to read partition table\n", kdevname(dev));
 		return -1;
 	}
@@ -854,11 +868,18 @@
 	int			 blk;
 	int			 part, res;
 
+	/*
+	 *	Don't bother touching M/O 2K media.
+	 */
+	 
+	if (get_ptable_blocksize(dev) != 1024)
+		return 0;
+		
 	set_blocksize(dev,512);
 	res = 0;
 
 	for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
-		if(!(bh = bread(dev,blk,512))) {
+		if(!(bh = bread(dev,blk,get_ptable_blocksize(dev)))) {
 			printk("Dev %s: unable to read RDB block %d\n",
 			       kdevname(dev),blk);
 			goto rdb_done;
@@ -875,7 +896,7 @@
 			blk = htonl(rdb->rdb_PartitionList);
 			brelse(bh);
 			for (part = 1; blk > 0 && part <= 16; part++) {
-				if (!(bh = bread(dev,blk,512))) {
+				if (!(bh = bread(dev,blk, get_ptable_blocksize(dev)))) {
 					printk("Dev %s: unable to read partition block %d\n",
 						       kdevname(dev),blk);
 					goto rdb_done;
@@ -908,6 +929,10 @@
 	}
 
 rdb_done:
+	/*
+	 *	FIXME: should restore the original size. Then we could clean
+	 *	up the M/O skip. Amiga people ?
+	 */
 	set_blocksize(dev,BLOCK_SIZE);
 	return res;
 }
@@ -1089,7 +1114,7 @@
 	      partsect = extensect = pi->st;
 	      while (1)
 		{
-		  xbh = bread (dev, partsect / 2, 1024);
+		  xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev));
 		  if (!xbh)
 		    {
 		      printk (" block %ld read failed\n", partsect);
diff -u --recursive --new-file v2.2.1/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c
--- v2.2.1/linux/drivers/block/ide-disk.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/block/ide-disk.c	Sat Jan 30 10:06:14 1999
@@ -101,20 +101,6 @@
 		id->cyls = lba_sects / (16 * 63); /* correct cyls */
 		return 1;	/* lba_capacity is our only option */
 	}
-	/*
-	 * This is a split test for drives less than 8 Gig only.
-	 * Drives less than 8GB sometimes declare that they have 15 heads.
-	 * This is an accounting trick (0-15) == (1-16), just an initial
-	 * zero point difference.
-	 */
-	if ((id->lba_capacity < 16514064) && (lba_sects > chs_sects) &&
-	    ((id->heads == 15) || (id->heads == 16)) && (id->sectors == 63)) {
-		if (id->heads == 15)
-			id->cyls = lba_sects / (15 * 63); /* correct cyls */
-		if (id->heads == 16)
-			id->cyls = lba_sects / (16 * 63); /* correct cyls */
-		return 1;	/* lba_capacity is our only option */
-	}
 	/* perform a rough sanity check on lba_sects:  within 10% is "okay" */
 	if ((lba_sects - chs_sects) < _10_percent) {
 		return 1;	/* lba_capacity is good */
diff -u --recursive --new-file v2.2.1/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c
--- v2.2.1/linux/drivers/block/ide-probe.c	Thu Jan  7 15:11:36 1999
+++ linux/drivers/block/ide-probe.c	Sat Feb  6 12:46:20 1999
@@ -124,6 +124,10 @@
 			case ide_tape:
 				printk ("TAPE");
 				break;
+			case ide_optical:
+				printk ("OPTICAL");
+				drive->removable = 1;
+				break;
 			default:
 				printk("UNKNOWN (type %d)", type);
 				break;
@@ -720,17 +724,39 @@
 	}
 	if (register_blkdev (hwif->major, hwif->name, ide_fops)) {
 		printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major);
-	} else if (init_irq (hwif)) {
-		printk("%s: UNABLE TO GET IRQ %d\n", hwif->name, hwif->irq);
-		(void) unregister_blkdev (hwif->major, hwif->name);
-	} else {
-		init_gendisk(hwif);
-		blk_dev[hwif->major].data = hwif;
-		blk_dev[hwif->major].request_fn = rfn;
-		blk_dev[hwif->major].queue = ide_get_queue;
-		read_ahead[hwif->major] = 8;	/* (4kB) */
-		hwif->present = 1;	/* success */
+		return (hwif->present = 0);
 	}
+	
+	if (init_irq (hwif)) {
+		int i = hwif->irq;
+		/*
+		 *	It failed to initialise. Find the default IRQ for 
+		 *	this port and try that.
+		 */
+		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) 
+		{
+			printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, i);
+			(void) unregister_blkdev (hwif->major, hwif->name);
+			return (hwif->present = 0);
+		}
+		if(init_irq (hwif)) 
+		{
+			printk("%s: probed IRQ %d and default IRQ %d failed.\n",
+				hwif->name, i, hwif->irq);
+			(void) unregister_blkdev (hwif->major, hwif->name);
+			return (hwif->present = 0);
+		}
+		printk("%s: probed IRQ %d failed, using default.\n",
+			hwif->name, hwif->irq);
+	}
+	
+	init_gendisk(hwif);
+	blk_dev[hwif->major].data = hwif;
+	blk_dev[hwif->major].request_fn = rfn;
+	blk_dev[hwif->major].queue = ide_get_queue;
+	read_ahead[hwif->major] = 8;	/* (4kB) */
+	hwif->present = 1;	/* success */
+
 #if (DEBUG_SPINLOCK > 0)
 {
 	static int done = 0;
diff -u --recursive --new-file v2.2.1/linux/drivers/block/ide.h linux/drivers/block/ide.h
--- v2.2.1/linux/drivers/block/ide.h	Thu Dec 31 10:28:59 1998
+++ linux/drivers/block/ide.h	Mon Feb 22 14:50:34 1999
@@ -182,6 +182,7 @@
 
 #define ide_scsi	0x21
 #define ide_disk	0x20
+#define ide_optical	0x7
 #define ide_cdrom	0x5
 #define ide_tape	0x1
 #define ide_floppy	0x0
diff -u --recursive --new-file v2.2.1/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.2.1/linux/drivers/char/bttv.c	Mon Jan 25 17:44:34 1999
+++ linux/drivers/char/bttv.c	Wed Feb 17 09:35:08 1999
@@ -120,6 +120,7 @@
 
 #define I2C_TIMING (0x7<<4)
 #define I2C_DELAY   10
+
 #define I2C_SET(CTRL,DATA) \
     { btwrite((CTRL<<1)|(DATA), BT848_I2C); udelay(I2C_DELAY); }
 #define I2C_GET()   (btread(BT848_I2C)&1)
@@ -244,6 +245,7 @@
 {
         struct bttv *btv = (struct bttv*)bus->data;
 	btwrite((ctrl<<1)|data, BT848_I2C);
+	btread(BT848_I2C); /* flush buffers */
 	udelay(I2C_DELAY);
 }
 
@@ -537,6 +539,8 @@
 	{ 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
         /* Aimslab VHX */
         { 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}},
+        /* Zoltrix TV-Max */
+        { 3, 1, 0, 2,15, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}},
 };
 #define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
 
@@ -2880,9 +2884,6 @@
 
 		} else if (I2CRead(&(btv->i2c), I2C_STBEE)>=0) {
 			btv->type=BTTV_STB;
-		} else 
-		        if (I2CRead(&(btv->i2c), I2C_VHX)>=0) {
-			        btv->type=BTTV_VHX;
 		} else {
 			if (I2CRead(&(btv->i2c), 0x80)>=0) /* check for msp34xx */
 				btv->type = BTTV_MIROPRO;
@@ -2907,8 +2908,8 @@
         }
         if(btv->type==BTTV_AVERMEDIA98)
         {
-          btv->pll.pll_ifreq=28636363;
-          btv->pll.pll_crystal=BT848_IFORM_XT0;
+        	btv->pll.pll_ifreq=28636363;
+        	btv->pll.pll_crystal=BT848_IFORM_XT0;
         }
           
 	if (btv->have_tuner && btv->tuner_type != -1) 
diff -u --recursive --new-file v2.2.1/linux/drivers/char/bttv.h linux/drivers/char/bttv.h
--- v2.2.1/linux/drivers/char/bttv.h	Mon Jan 25 17:44:34 1999
+++ linux/drivers/char/bttv.h	Mon Feb  1 14:04:42 1999
@@ -206,7 +206,8 @@
 #define BTTV_MIROPRO       0x0b
 #define BTTV_ADSTECH_TV    0x0c
 #define BTTV_AVERMEDIA98   0x0d
-#define BTTV_VHX   	   0x0e
+#define BTTV_VHX           0x0e
+#define BTTV_ZOLTRIX       0x0f
 
 #define AUDIO_TUNER        0x00
 #define AUDIO_RADIO        0x01
diff -u --recursive --new-file v2.2.1/linux/drivers/char/msp3400.c linux/drivers/char/msp3400.c
--- v2.2.1/linux/drivers/char/msp3400.c	Mon Jan 25 17:44:34 1999
+++ linux/drivers/char/msp3400.c	Wed Feb 17 09:37:51 1999
@@ -774,7 +774,6 @@
 			goto done;
 		dprintk("msp3410: thread: sleep\n");
 		down_interruptible(&sem);
-		sem.owner = 0;
 		dprintk("msp3410: thread: wakeup\n");
 		if (msp->rmmod)
 			goto done;
diff -u --recursive --new-file v2.2.1/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- v2.2.1/linux/drivers/char/pc_keyb.c	Mon Jan 25 17:44:34 1999
+++ linux/drivers/char/pc_keyb.c	Sun Feb  7 00:23:04 1999
@@ -10,6 +10,9 @@
  * because they share the same hardware.
  * Johan Myreen <jem@iki.fi> 1998-10-08.
  *
+ * Code fixes to handle mouse ACKs properly.
+ * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
+ *
  */
 
 #include <linux/config.h>
@@ -74,6 +77,8 @@
 
 static struct aux_queue *queue;	/* Mouse data buffer. */
 static int aux_count = 0;
+/* used when we send commands to the mouse that expect an ACK. */
+static unsigned char mouse_reply_expected = 0;
 
 #define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
 #define AUX_INTS_ON  (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
@@ -99,7 +104,7 @@
  * Controller Status register are set 0."
  */
 
-static inline void kb_wait(void)
+static void kb_wait(void)
 {
 	unsigned long timeout = KBC_TIMEOUT;
 
@@ -400,6 +405,33 @@
 	    return 0200;
 }
 
+static inline void handle_mouse_event(unsigned char scancode)
+{
+#ifdef CONFIG_PSMOUSE
+	if (mouse_reply_expected) {
+		if (scancode == AUX_ACK) {
+			mouse_reply_expected--;
+			return;
+		}
+		mouse_reply_expected = 0;
+	}
+
+	add_mouse_randomness(scancode);
+	if (aux_count) {
+		int head = queue->head;
+
+		queue->buf[head] = scancode;
+		head = (head + 1) & (AUX_BUF_SIZE-1);
+		if (head != queue->tail) {
+			queue->head = head;
+			if (queue->fasync)
+				kill_fasync(queue->fasync, SIGIO);
+			wake_up_interruptible(&queue->proc_list);
+		}
+	}
+#endif
+}
+
 /*
  * This reads the keyboard status port, and does the
  * appropriate action.
@@ -417,21 +449,7 @@
 		scancode = inb(KBD_DATA_REG);
 
 		if (status & KBD_STAT_MOUSE_OBF) {
-#ifdef CONFIG_PSMOUSE
-			/* Mouse data. */
-			if (aux_count) {
-				int head = queue->head;
-				queue->buf[head] = scancode;
-				add_mouse_randomness(scancode);
-				head = (head + 1) & (AUX_BUF_SIZE-1);
-				if (head != queue->tail) {
-					queue->head = head;
-					if (queue->fasync)
-						kill_fasync(queue->fasync, SIGIO);
-					wake_up_interruptible(&queue->proc_list);
-				}
-			}
-#endif
+			handle_mouse_event(scancode);
 		} else {
 			if (do_acknowledge(scancode))
 				handle_scancode(scancode);
@@ -716,9 +734,7 @@
 static int __init detect_auxiliary_port(void)
 {
 	unsigned long flags;
-	unsigned char status;
-	unsigned char val;
-	int loops = 5;
+	int loops = 10;
 	int retval = 0;
 
 	spin_lock_irqsave(&kbd_controller_lock, flags);
@@ -736,20 +752,19 @@
 	kb_wait();
 	outb(0x5a, KBD_DATA_REG); /* 0x5a is a random dummy value. */
 
-	status = inb(KBD_STATUS_REG);
-	while (!(status & KBD_STAT_OBF) && loops--) {
-		mdelay(1);
-		status = inb(KBD_STATUS_REG);
-	}
+	do {
+		unsigned char status = inb(KBD_STATUS_REG);
 
-	if (status & KBD_STAT_OBF) {
-		val = inb(KBD_DATA_REG);
-		if (status & KBD_STAT_MOUSE_OBF) {
-			printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
-			retval = 1;
+		if (status & KBD_STAT_OBF) {
+			(void) inb(KBD_DATA_REG);
+			if (status & KBD_STAT_MOUSE_OBF) {
+				printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
+				retval = 1;
+			}
+			break;
 		}
-	}
-
+		mdelay(1);
+	} while (--loops);
 	spin_unlock_irqrestore(&kbd_controller_lock, flags);
 
 	return retval;
@@ -770,16 +785,33 @@
 	spin_unlock_irqrestore(&kbd_controller_lock, flags);
 }
 
-static unsigned int get_from_queue(void)
+/*
+ * Send a byte to the mouse & handle returned ack
+ */
+static void aux_write_ack(int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	kb_wait();
+	outb(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG);
+	kb_wait();
+	outb(val, KBD_DATA_REG);
+	/* we expect an ACK in response. */
+	mouse_reply_expected++;
+	kb_wait();
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+
+static unsigned char get_from_queue(void)
 {
-	unsigned int result;
+	unsigned char result;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&kbd_controller_lock, flags);
 	result = queue->buf[queue->tail];
 	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
 	return result;
 }
 
@@ -834,7 +866,7 @@
 	kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE);	/* Enable the
 							   auxiliary port on
 							   controller. */
-	aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */
+	aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
 	kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
 
 	return 0;
@@ -951,11 +983,11 @@
 
 #ifdef INITIALIZE_MOUSE
 	kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE);	/* Enable Aux. */
-	aux_write_dev(AUX_SET_SAMPLE);
-	aux_write_dev(100);			/* 100 samples/sec */
-	aux_write_dev(AUX_SET_RES);
-	aux_write_dev(3);			/* 8 counts per mm */
-	aux_write_dev(AUX_SET_SCALE21);		/* 2:1 scaling */
+	aux_write_ack(AUX_SET_SAMPLE);
+	aux_write_ack(100);			/* 100 samples/sec */
+	aux_write_ack(AUX_SET_RES);
+	aux_write_ack(3);			/* 8 counts per mm */
+	aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
 #endif /* INITIALIZE_MOUSE */
 	kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
 	kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
diff -u --recursive --new-file v2.2.1/linux/drivers/char/pc_keyb.h linux/drivers/char/pc_keyb.h
--- v2.2.1/linux/drivers/char/pc_keyb.h	Tue Jan 19 11:32:51 1999
+++ linux/drivers/char/pc_keyb.h	Sat Feb  6 12:46:20 1999
@@ -114,8 +114,12 @@
 #define AUX_ENABLE_DEV		0xF4	/* Enable aux device */
 #define AUX_DISABLE_DEV		0xF5	/* Disable aux device */
 #define AUX_RESET		0xFF	/* Reset aux device */
+#define AUX_ACK			0xFA	/* Command byte ACK. */
 
-#define AUX_BUF_SIZE		2048
+#define AUX_BUF_SIZE		2048	/* This might be better divisible by
+					   three to make overruns stay in sync
+					   but then the read function would need
+					   a lock etc - ick */
 
 struct aux_queue {
 	unsigned long head;
diff -u --recursive --new-file v2.2.1/linux/drivers/char/pty.c linux/drivers/char/pty.c
--- v2.2.1/linux/drivers/char/pty.c	Mon Oct  5 13:13:39 1998
+++ linux/drivers/char/pty.c	Sat Feb  6 17:28:37 1999
@@ -84,7 +84,6 @@
 	wake_up_interruptible(&tty->link->write_wait);
 	set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 	if (tty->driver.subtype == PTY_TYPE_MASTER) {
-		tty_hangup(tty->link);
 		set_bit(TTY_OTHER_CLOSED, &tty->flags);
 #ifdef CONFIG_UNIX98_PTYS
 		{
@@ -95,6 +94,7 @@
 			}
 		}
 #endif
+		tty_vhangup(tty->link);
 	}
 }
 
diff -u --recursive --new-file v2.2.1/linux/drivers/char/vt.c linux/drivers/char/vt.c
--- v2.2.1/linux/drivers/char/vt.c	Wed Jan 13 15:00:41 1999
+++ linux/drivers/char/vt.c	Wed Feb  3 22:57:41 1999
@@ -165,7 +165,7 @@
 			val = K_HOLE;
 		} else
 		    val = (i ? K_HOLE : K_NOSUCHMAP);
-		return __put_user(val, &user_kbe->kb_value);
+		return put_user(val, &user_kbe->kb_value);
 	case KDSKBENT:
 		if (!perm)
 			return -EPERM;
@@ -244,7 +244,7 @@
 	case KDGETKEYCODE:
 		kc = getkeycode(tmp.scancode);
 		if (kc >= 0)
-			kc = __put_user(kc, &user_kbkc->keycode);
+			kc = put_user(kc, &user_kbkc->keycode);
 		break;
 	case KDSETKEYCODE:
 		if (!perm)
@@ -282,8 +282,8 @@
 		p = func_table[i];
 		if(p)
 			for ( ; *p && sz; p++, sz--)
-				__put_user(*p, q++);
-		__put_user('\0', q);
+				put_user(*p, q++);
+		put_user('\0', q);
 		return ((p && *p) ? -EOVERFLOW : 0);
 	case KDSKBSENT:
 		if (!perm)
@@ -603,12 +603,10 @@
 	{
 		struct kbdiacrs *a = (struct kbdiacrs *)arg;
 
-		i = verify_area(VERIFY_WRITE, (void *) a, sizeof(struct kbdiacrs));
-		if (i)
-			return i;
-		__put_user(accent_table_size, &a->kb_cnt);
-		__copy_to_user(a->kbdiacr, accent_table,
-			    accent_table_size*sizeof(struct kbdiacr));
+		if (put_user(accent_table_size, &a->kb_cnt))
+			return -EFAULT;
+		if (copy_to_user(a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr)))
+			return -EFAULT;
 		return 0;
 	}
 
@@ -619,14 +617,13 @@
 
 		if (!perm)
 			return -EPERM;
-		i = verify_area(VERIFY_READ, (void *) a, sizeof(struct kbdiacrs));
-		if (i)
-			return i;
-		__get_user(ct,&a->kb_cnt);
+		if (get_user(ct,&a->kb_cnt))
+			return -EFAULT;
 		if (ct >= MAX_DIACR)
 			return -EINVAL;
 		accent_table_size = ct;
-		__copy_from_user(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));
+		if (copy_from_user(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr)))
+			return -EFAULT;
 		return 0;
 	}
 
@@ -717,12 +714,12 @@
 		i = verify_area(VERIFY_WRITE,(void *)vtstat, sizeof(struct vt_stat));
 		if (i)
 			return i;
-		__put_user(fg_console + 1, &vtstat->v_active);
+		put_user(fg_console + 1, &vtstat->v_active);
 		state = 1;	/* /dev/tty0 is always open */
 		for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; ++i, mask <<= 1)
 			if (VT_IS_IN_USE(i))
 				state |= mask;
-		return __put_user(state, &vtstat->v_state);
+		return put_user(state, &vtstat->v_state);
 	}
 
 	/*
@@ -856,8 +853,8 @@
 		i = verify_area(VERIFY_READ, (void *)vtsizes, sizeof(struct vt_sizes));
 		if (i)
 			return i;
-		__get_user(ll, &vtsizes->v_rows);
-		__get_user(cc, &vtsizes->v_cols);
+		get_user(ll, &vtsizes->v_rows);
+		get_user(cc, &vtsizes->v_cols);
 		return vc_resize_all(ll, cc);
 	}
 
@@ -870,12 +867,12 @@
 		i = verify_area(VERIFY_READ, (void *)vtconsize, sizeof(struct vt_consize));
 		if (i)
 			return i;
-		__get_user(ll, &vtconsize->v_rows);
-		__get_user(cc, &vtconsize->v_cols);
-		__get_user(vlin, &vtconsize->v_vlin);
-		__get_user(clin, &vtconsize->v_clin);
-		__get_user(vcol, &vtconsize->v_vcol);
-		__get_user(ccol, &vtconsize->v_ccol);
+		get_user(ll, &vtconsize->v_rows);
+		get_user(cc, &vtconsize->v_cols);
+		get_user(vlin, &vtconsize->v_vlin);
+		get_user(clin, &vtconsize->v_clin);
+		get_user(vcol, &vtconsize->v_vcol);
+		get_user(ccol, &vtconsize->v_ccol);
 		vlin = vlin ? vlin : video_scan_lines;
 		if ( clin )
 		  {
diff -u --recursive --new-file v2.2.1/linux/drivers/misc/parport_ieee1284.c linux/drivers/misc/parport_ieee1284.c
--- v2.2.1/linux/drivers/misc/parport_ieee1284.c	Wed Jan 20 23:14:05 1999
+++ linux/drivers/misc/parport_ieee1284.c	Sat Feb 20 09:31:08 1999
@@ -52,7 +52,7 @@
 		& ~1 ) & ~2);
 	udelay(1);
 	parport_write_data(port, mode);
-	udelay(1);
+	udelay(400);
 	/* nSelectIn high, nAutoFd low */
 	parport_write_control(port, (parport_read_control(port) & ~8) | 2);
 	if (parport_wait_peripheral(port, 0x78, 0x38)) {
diff -u --recursive --new-file v2.2.1/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.2.1/linux/drivers/net/Space.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/net/Space.c	Thu Feb 18 16:28:49 1999
@@ -518,7 +518,7 @@
 	&& dfx_probe(dev)
 #endif
 #ifdef CONFIG_APFDDI
-	&& apfddi_init(dev);
+	&& apfddi_init(dev)
 #endif
 	&& 1 ) {
 	    return 1;	/* -ENODEV or -EAGAIN would be more accurate. */
diff -u --recursive --new-file v2.2.1/linux/drivers/net/defxx.c linux/drivers/net/defxx.c
--- v2.2.1/linux/drivers/net/defxx.c	Fri May  8 23:14:48 1998
+++ linux/drivers/net/defxx.c	Sat Feb  6 12:46:21 1999
@@ -2881,6 +2881,22 @@
 	return(DFX_K_SUCCESS);
 	}
 
+
+/*
+ *	Align an sk_buff to a boundary power of 2
+ *
+ */
+ 
+void my_skb_align(struct sk_buff *skb, int n)
+{
+	u32 x=(u32)skb->data;	/* We only want the low bits .. */
+	u32 v;
+	
+	v=(x+n-1)&~(n-1);	/* Where we want to be */
+	
+	skb_reserve(skb, v-x);
+}
+
 
 /*
  * ================
@@ -2950,8 +2966,8 @@
 			 * align to 128 bytes for compatibility with
 			 * the old EISA boards.
 			 */
-			newskb->data = (char *)((unsigned long)
-						(newskb->data+127) & ~127);
+			 
+			my_skb_align(newskb,128);
 			bp->descr_block_virt->rcv_data[i+j].long_1 = virt_to_bus(newskb->data);
 			/*
 			 * p_rcv_buff_va is only used inside the
@@ -3062,10 +3078,10 @@
 					newskb = dev_alloc_skb(NEW_SKB_SIZE);
 					if (newskb){
 						rx_in_place = 1;
-
-						newskb->data = (char *)((unsigned long)(newskb->data+127) & ~127);
+						
+						my_skb_align(newskb, 128);
 						skb = (struct sk_buff *)bp->p_rcv_buff_va[entry];
-						skb->data += RCV_BUFF_K_PADDING;
+						skb_reserve(skb, RCV_BUFF_K_PADDING);
 						bp->p_rcv_buff_va[entry] = (char *)newskb;
 						bp->descr_block_virt->rcv_data[entry].long_1 = virt_to_bus(newskb->data);
 					} else
@@ -3088,9 +3104,9 @@
 
 						memcpy(skb->data, p_buff + RCV_BUFF_K_PADDING, pkt_len+3);
 					}
-
-					skb->data += 3;			/* adjust data field so that it points to FC byte */
-					skb->len = pkt_len;		/* pass up packet length, NOT including CRC */
+					
+					skb_reserve(skb,3);		/* adjust data field so that it points to FC byte */
+					skb_put(skb, pkt_len);		/* pass up packet length, NOT including CRC */
 					skb->dev = bp->dev;		/* pass up device pointer */
 
 					skb->protocol = fddi_type_trans(skb, bp->dev);
diff -u --recursive --new-file v2.2.1/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.2.1/linux/drivers/net/eepro100.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/net/eepro100.c	Sat Feb  6 12:46:21 1999
@@ -842,9 +842,6 @@
 
 	wait_for_cmd_done(ioaddr + SCBCmd);
 	outw(CU_DUMPSTATS, ioaddr + SCBCmd);
-	/* No need to wait for the command unit to accept here. */
-	if ((sp->phy[0] & 0x8000) == 0)
-		mdio_read(ioaddr, sp->phy[0] & 0x1f, 0);
 
 	/*
 	 * Request the IRQ last, after we have set up all data structures.
@@ -854,6 +851,10 @@
 					"Intel EtherExpress Pro 10/100 Ethernet", dev)) {
 		return -EAGAIN;
 	}
+
+	/* No need to wait for the command unit to accept here. */
+	if ((sp->phy[0] & 0x8000) == 0)
+		mdio_read(ioaddr, sp->phy[0] & 0x1f, 0);
 
 	MOD_INC_USE_COUNT;
 
diff -u --recursive --new-file v2.2.1/linux/drivers/net/hamradio/baycom_epp.c linux/drivers/net/hamradio/baycom_epp.c
--- v2.2.1/linux/drivers/net/hamradio/baycom_epp.c	Fri Nov 27 13:09:24 1998
+++ linux/drivers/net/hamradio/baycom_epp.c	Mon Feb  1 10:41:47 1999
@@ -1075,6 +1075,7 @@
 	if (!(pp->modes & (PARPORT_MODE_PCECPEPP|PARPORT_MODE_PCEPP))) {
                 printk(KERN_ERR "%s: parport at 0x%lx does not support any EPP mode\n",
 		       bc_drvname, pp->base);
+		parport_release(bc->pdev);
                 parport_unregister_device(bc->pdev);
                 return -EIO;		
 	}
diff -u --recursive --new-file v2.2.1/linux/drivers/net/hostess_sv11.c linux/drivers/net/hostess_sv11.c
--- v2.2.1/linux/drivers/net/hostess_sv11.c	Thu Nov 19 09:56:28 1998
+++ linux/drivers/net/hostess_sv11.c	Thu Feb 18 16:28:49 1999
@@ -416,10 +416,8 @@
 
 int init_module(void)
 {
-	printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.01.\n");
+	printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n");
 	printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");	
-	if(dma)
-		printk(KERN_WARNING "DMA mode probably wont work right now.\n");
 	if((sv11_unit=sv11_init(io,irq))==NULL)
 		return -ENODEV;
 	return 0;
diff -u --recursive --new-file v2.2.1/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v2.2.1/linux/drivers/net/ppp.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/net/ppp.c	Thu Feb 18 16:29:30 1999
@@ -2062,7 +2062,11 @@
 			       "ppp: error in VJ decompression\n");
 		return 0;
 	}
-	skb_put(skb, new_count + PPP_HDRLEN - skb->len);
+	new_count += PPP_HDRLEN;
+	if (new_count > skb->len)
+		skb_put(skb, new_count - skb->len);
+	else
+		skb_trim(skb, new_count);
 	return rcv_proto_ip(ppp, skb);
 }
 
diff -u --recursive --new-file v2.2.1/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- v2.2.1/linux/drivers/net/smc-ultra.c	Tue Dec 22 14:16:56 1998
+++ linux/drivers/net/smc-ultra.c	Sat Feb  6 12:46:21 1999
@@ -440,6 +440,8 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
 
+EXPORT_NO_SYMBOLS;
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 int
diff -u --recursive --new-file v2.2.1/linux/drivers/net/syncppp.c linux/drivers/net/syncppp.c
--- v2.2.1/linux/drivers/net/syncppp.c	Fri Nov 27 13:09:24 1998
+++ linux/drivers/net/syncppp.c	Thu Feb 18 16:29:30 1999
@@ -51,7 +51,7 @@
 #include <asm/byteorder.h>
 #include "syncppp.h"
 
-#define MAXALIVECNT     3               /* max. alive packets */
+#define MAXALIVECNT     6               /* max. alive packets */
 
 #define PPP_ALLSTATIONS 0xff            /* All-Stations broadcast address */
 #define PPP_UI          0x03            /* Unnumbered Information */
@@ -380,6 +380,7 @@
 			if_down (dev);
 			if (! (sp->pp_flags & PP_CISCO)) {
 				/* Shut down the PPP link. */
+				sp->lcp.magic = jiffies;
 				sp->lcp.state = LCP_STATE_CLOSED;
 				sp->ipcp.state = IPCP_STATE_CLOSED;
 				sppp_clear_timeout (sp);
@@ -841,6 +842,25 @@
 }
 
 EXPORT_SYMBOL(sppp_open);
+
+int sppp_reopen (struct device *dev)
+{
+	struct sppp *sp = &((struct ppp_device *)dev)->sppp;
+	sppp_close(dev);
+	dev->flags |= IFF_RUNNING;
+	if (!(sp->pp_flags & PP_CISCO))
+	{
+		sp->lcp.magic = jiffies;
+		++sp->pp_seq;
+		sp->lcp.state = LCP_STATE_CLOSED;
+		sp->ipcp.state = IPCP_STATE_CLOSED;
+		/* Give it a moment for the line to settle then go */
+		sppp_set_timeout (sp, 1);
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(sppp_reopen);
 
 int sppp_change_mtu(struct device *dev, int new_mtu)
 {
diff -u --recursive --new-file v2.2.1/linux/drivers/net/syncppp.h linux/drivers/net/syncppp.h
--- v2.2.1/linux/drivers/net/syncppp.h	Fri Oct 23 22:01:21 1998
+++ linux/drivers/net/syncppp.h	Sat Feb  6 12:46:21 1999
@@ -80,6 +80,7 @@
 int sppp_isempty (struct device *dev);
 void sppp_flush (struct device *dev);
 int sppp_open (struct device *dev);
+int sppp_reopen (struct device *dev);
 int sppp_close (struct device *dev);
 #endif
 
diff -u --recursive --new-file v2.2.1/linux/drivers/net/tlan.c linux/drivers/net/tlan.c
--- v2.2.1/linux/drivers/net/tlan.c	Fri Jan  8 22:36:08 1999
+++ linux/drivers/net/tlan.c	Sat Feb  6 12:46:21 1999
@@ -29,6 +29,8 @@
  *
  *	Tigran Aivazian <tigran@sco.com>:	TLan_PciProbe() now uses
  *						new PCI BIOS interface.
+ *	Alan Cox	<alan@redhat.com>:	Fixed the out of memory
+ *						handling.
  *
  ********************************************************************/
 
@@ -1250,28 +1252,36 @@
 			netif_rx( skb );
 		}
 	} else {
-		skb = (struct sk_buff *) head_list->buffer[9].address;
-		head_list->buffer[9].address = 0;
-		skb_trim( skb, head_list->frameSize );
-
+		struct sk_buff *new_skb;
+		
+		/*
+		 *	I changed the algorithm here. What we now do
+		 *	is allocate the new frame. If this fails we
+		 *	simply recycle the frame.
+		 */
+		
+		new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
+		if ( new_skb != NULL ) {
+			/* If this ever happened it would be a problem */
+			/* not any more - ac */
+			skb = (struct sk_buff *) head_list->buffer[9].address;
+			head_list->buffer[9].address = 0;
+			skb_trim( skb, head_list->frameSize );
 #if LINUX_KERNEL_VERSION > 0x20100
 			priv->stats->rx_bytes += head_list->frameSize;
 #endif
 
-		skb->protocol = eth_type_trans( skb, dev );
-		netif_rx( skb );
-
-		skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
-		if ( skb == NULL ) {
-			printk( "TLAN:  Couldn't allocate memory for received data.\n" );
-			/* If this ever happened it would be a problem */
-		} else {
-			skb->dev = dev;
-			skb_reserve( skb, 2 );
-			t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE );
+			skb->protocol = eth_type_trans( skb, dev );
+			netif_rx( skb );
+	
+			new_skb->dev = dev;
+			skb_reserve( new_skb, 2 );
+			t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE );
 			head_list->buffer[0].address = virt_to_bus( t );
-			head_list->buffer[9].address = (u32) skb;
+			head_list->buffer[9].address = (u32) new_skb;
 		}
+		else
+			printk(KERN_WARNING "TLAN:  Couldn't allocate memory for received data.\n" );
 	}
 
 	head_list->forward = 0;
diff -u --recursive --new-file v2.2.1/linux/drivers/net/z85230.c linux/drivers/net/z85230.c
--- v2.2.1/linux/drivers/net/z85230.c	Fri Jan  8 22:36:08 1999
+++ linux/drivers/net/z85230.c	Sat Feb  6 12:46:21 1999
@@ -349,6 +349,7 @@
 	if(status&TxEOM)
 	{
 /*		printk("%s: Tx underrun.\n", chan->dev->name); */
+		chan->stats.tx_fifo_errors++;
 		write_zsctrl(chan, ERR_RES);
 		z8530_tx_done(chan);
 	}
@@ -359,6 +360,8 @@
 		{
 			printk(KERN_INFO "%s: DCD raised\n", chan->dev->name);
 			write_zsreg(chan, R3, chan->regs[3]|RxENABLE);
+			if(chan->netdevice)
+				sppp_reopen(chan->netdevice);
 		}
 		else
 		{
@@ -450,6 +453,8 @@
 		{
 			printk(KERN_INFO "%s: DCD raised\n", chan->dev->name);
 			write_zsreg(chan, R3, chan->regs[3]|RxENABLE);
+			if(chan->netdevice)
+				sppp_reopen(chan->netdevice);
 		}
 		else
 		{
@@ -1107,6 +1112,14 @@
 		{
 			flags=claim_dma_lock();
 			disable_dma(c->txdma);
+			/*
+			 *	Check if we crapped out.
+			 */
+			if(get_dma_residue(c->txdma))
+			{
+				c->stats.tx_dropped++;
+				c->stats.tx_fifo_errors++;
+			}
 			release_dma_lock(flags);
 		}
 		c->txcount=0;
@@ -1133,6 +1146,7 @@
 			set_dma_count(c->txdma, c->txcount);
 			enable_dma(c->txdma);
 			release_dma_lock(flags);
+			write_zsctrl(c, RES_EOM_L);
 			write_zsreg(c, R5, c->regs[R5]|TxENAB);
 		}
 		else
@@ -1173,6 +1187,8 @@
 	c->tx_skb=NULL;
 	z8530_tx_begin(c);
 	spin_unlock_irqrestore(&z8530_buffer_lock, flags);
+	c->stats.tx_packets++;
+	c->stats.tx_bytes+=skb->len;
 	dev_kfree_skb(skb);
 }
 
@@ -1255,11 +1271,16 @@
 		 
 		skb=dev_alloc_skb(ct);
 		if(skb==NULL)
-			printk("%s: Memory squeeze.\n", c->netdevice->name);
+		{
+			c->stats.rx_dropped++;
+			printk(KERN_WARNING "%s: Memory squeeze.\n", c->netdevice->name);
+		}
 		else
 		{
 			skb_put(skb, ct);
 			memcpy(skb->data, rxb, ct);
+			c->stats.rx_packets++;
+			c->stats.rx_bytes+=ct;
 		}
 		c->dma_ready=1;
 	}
@@ -1305,6 +1326,9 @@
 		{
 			skb_put(c->skb2,c->mtu);
 		}
+		c->stats.rx_packets++;
+		c->stats.rx_bytes+=ct;
+		
 	}
 	/*
 	 *	If we received a frame we must now process it.
@@ -1315,7 +1339,10 @@
 		c->rx_function(c,skb);
 	}
 	else
-		printk("Lost a frame\n");
+	{
+		c->stats.rx_dropped++;
+		printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name);
+	}
 }
 
 /*
diff -u --recursive --new-file v2.2.1/linux/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c
--- v2.2.1/linux/drivers/scsi/atp870u.c	Tue Dec 22 14:16:56 1998
+++ linux/drivers/scsi/atp870u.c	Mon Feb  8 09:44:08 1999
@@ -1720,8 +1720,8 @@
     h=0;
     while ( devid[h] != 0 )
     {
-      pci_find_device(0x1191,devid[h],pdev);
-      if (pdev == NULL); {
+      pdev = pci_find_device(0x1191,devid[h],pdev);
+      if (pdev == NULL) {
 	  h++;
 	  index=0;
 	  continue;
diff -u --recursive --new-file v2.2.1/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- v2.2.1/linux/drivers/scsi/ide-scsi.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/scsi/ide-scsi.c	Mon Feb 15 16:36:54 1999
@@ -23,8 +23,9 @@
  * Ver 0.6   Jan 27 98   Allow disabling of SCSI command translation layer
  *                        for access through /dev/sg.
  *                       Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation.
- * Ver 0.7   Dev 04 98   Ignore commands where lun != 0 to avoid multiple
+ * Ver 0.7   Dec 04 98   Ignore commands where lun != 0 to avoid multiple
  *                        detection of devices with CONFIG_SCSI_MULTI_LUN
+ * Ver 0.8   Feb 05 99   Optical media need translation too. 
  */
 
 #define IDESCSI_VERSION "0.6"
@@ -178,7 +179,7 @@
 
 	if (!test_bit(PC_TRANSFORM, &pc->flags))
 		return;
-	if (drive->media == ide_cdrom) {
+	if (drive->media == ide_cdrom || drive->media == ide_optical) {
 		if (c[0] == READ_6 || c[0] == WRITE_6) {
 			c[8] = c[4];		c[5] = c[3];		c[4] = c[2];
 			c[3] = c[1] & 0x1f;	c[2] = 0;		c[1] &= 0xe0;
@@ -217,7 +218,7 @@
 
 	if (!test_bit(PC_TRANSFORM, &pc->flags))
 		return;
-	if (drive->media == ide_cdrom) {
+	if (drive->media == ide_cdrom || drive->media == ide_optical) {
 		if (pc->c[0] == MODE_SENSE_10 && sc[0] == MODE_SENSE) {
 			scsi_buf[0] = atapi_buf[1];		/* Mode data length */
 			scsi_buf[1] = atapi_buf[2];		/* Medium type */
@@ -730,9 +731,6 @@
 		printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->target);
 		goto abort;
 	}
-	if (cmd->lun != 0) {		/* Only respond to LUN 0. Drop others */
-		goto abort;
-	}
 	scsi = drive->driver_data;
 	pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC);
 	rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
@@ -794,7 +792,7 @@
 
 int idescsi_reset (Scsi_Cmnd *cmd, unsigned int resetflags)
 {
-	return SCSI_RESET_PUNT;
+	return SCSI_RESET_SUCCESS;
 }
 
 int idescsi_bios (Disk *disk, kdev_t dev, int *parm)
diff -u --recursive --new-file v2.2.1/linux/drivers/scsi/imm.c linux/drivers/scsi/imm.c
--- v2.2.1/linux/drivers/scsi/imm.c	Wed Jan 13 15:00:42 1999
+++ linux/drivers/scsi/imm.c	Sun Feb 14 23:17:31 1999
@@ -1204,19 +1204,16 @@
 	    status = imm_out(host_no, &cmd[l << 1], 2);
 
 	if (!status) {
-	    imm_disconnect(host_no);
-	    imm_connect(host_no, CONNECT_EPP_MAYBE);
-	    w_dtr(ppb, 0x40);
-	    w_ctr(ppb, 0x08);
-	    udelay(30);
-	    w_ctr(ppb, 0x0c);
-	    udelay(1000);
-	    imm_disconnect(host_no);
-	    udelay(1000);
-	    if (imm_hosts[host_no].mode == IMM_EPP_32) {
-		imm_hosts[host_no].mode = old_mode;
-		goto second_pass;
-	    }
+            imm_disconnect(host_no);
+            imm_connect(host_no, CONNECT_EPP_MAYBE);
+            imm_reset_pulse(IMM_BASE(host_no));
+            udelay(1000);
+            imm_disconnect(host_no);
+            udelay(1000);
+            if (imm_hosts[host_no].mode == IMM_EPP_32) {
+                imm_hosts[host_no].mode = old_mode;
+                goto second_pass;
+            }
 	    printk("imm: Unable to establish communication, aborting driver load.\n");
 	    return 1;
 	}
diff -u --recursive --new-file v2.2.1/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- v2.2.1/linux/drivers/scsi/ncr53c8xx.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/scsi/ncr53c8xx.c	Sun Feb 14 23:17:31 1999
@@ -9633,6 +9633,8 @@
 	base = pdev->base_address[1];
 	base_2 = pdev->base_address[2];
 	irq = pdev->irq;
+	if ((base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64)
+		base_2 = pdev->base_address[3];
 #else
 	(void) pcibios_read_config_dword(bus, device_fn,
 					PCI_BASE_ADDRESS_0, &io_port);	
diff -u --recursive --new-file v2.2.1/linux/drivers/scsi/ppa.h linux/drivers/scsi/ppa.h
--- v2.2.1/linux/drivers/scsi/ppa.h	Fri Jan  8 22:36:10 1999
+++ linux/drivers/scsi/ppa.h	Mon Feb 22 14:51:33 1999
@@ -10,7 +10,7 @@
 #ifndef _PPA_H
 #define _PPA_H
 
-#define   PPA_VERSION   "2.03 (for Linux 2.0.0)"
+#define   PPA_VERSION   "2.03 (for Linux 2.2.x)"
 
 /* 
  * this driver has been hacked by Matteo Frigo (athena@theory.lcs.mit.edu)
diff -u --recursive --new-file v2.2.1/linux/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c
--- v2.2.1/linux/drivers/scsi/qlogicfas.c	Tue Apr 14 14:29:23 1998
+++ linux/drivers/scsi/qlogicfas.c	Thu Feb 18 16:29:30 1999
@@ -5,8 +5,8 @@
    these silly disclaimers.
 
    Copyright 1994, Tom Zerucha.   
-   zerucha@shell.portal.com
-
+   tz@execpc.com
+   
    Additional Code, and much appreciated help by
    Michael A. Griffith
    grif@cs.ucr.edu
diff -u --recursive --new-file v2.2.1/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.2.1/linux/drivers/scsi/sd.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/scsi/sd.c	Sat Feb  6 12:46:21 1999
@@ -708,14 +708,14 @@
      */
     if (rscsi_disks[dev].sector_size == 1024)
 	if((block & 1) || (SCpnt->request.nr_sectors & 1)) {
-	    printk("sd.c:Bad block number requested");
+	    printk("sd.c:Bad block number/count requested");
 	    SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 	    goto repeat;
 	}
 
      if (rscsi_disks[dev].sector_size == 2048)
  	if((block & 3) || (SCpnt->request.nr_sectors & 3)) {
- 	    printk("sd.c:Bad block number requested");
+ 	    printk("sd.c:Bad block number/count requested");
  	    SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
  	    goto repeat;
  	}
diff -u --recursive --new-file v2.2.1/linux/drivers/sound/midi_synth.c linux/drivers/sound/midi_synth.c
--- v2.2.1/linux/drivers/sound/midi_synth.c	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/midi_synth.c	Mon Feb  1 14:04:42 1999
@@ -12,6 +12,7 @@
  */
 /*
  * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
+ * Andrew Veliath  : fixed running status in MIDI input state machine
  */
 #include <linux/config.h>
 
@@ -196,13 +197,19 @@
 				      inc->m_left = len_tab[(data >> 4) - 8];
 				      inc->m_buf[0] = inc->m_prev_status = data;
 			      }
-		  } else if (inc->m_prev_status & 0x80)		/* Ignore if no previous status (yet) */
-		    {		/* Data byte (use running status) */
-			    inc->m_state = MST_DATA;
+		    } else if (inc->m_prev_status & 0x80) {
+			    /* Data byte (use running status) */
 			    inc->m_ptr = 2;
-			    inc->m_left = len_tab[(data >> 4) - 8] - 1;
-			    inc->m_buf[0] = inc->m_prev_status;
 			    inc->m_buf[1] = data;
+			    inc->m_buf[0] = inc->m_prev_status;
+			    inc->m_left = len_tab[(inc->m_buf[0] >> 4) - 8] - 1;
+			    if (inc->m_left > 0)
+				    inc->m_state = MST_DATA; /* Not done yet */
+			    else {
+				    inc->m_state = MST_INIT;
+				    do_midi_msg(dev, inc->m_buf, inc->m_ptr);
+				    inc->m_ptr = 0;
+			    }
 		    }
 		  break;	/* MST_INIT */
 
diff -u --recursive --new-file v2.2.1/linux/drivers/sound/sb.h linux/drivers/sound/sb.h
--- v2.2.1/linux/drivers/sound/sb.h	Tue Jan 19 11:32:52 1999
+++ linux/drivers/sound/sb.h	Mon Feb  1 14:04:42 1999
@@ -48,12 +48,6 @@
 #define MDL_ES1868MIDI	14	/* MIDI port of ESS1868 */
 #define MDL_AEDSP	15	/* Audio Excel DSP 16 */
 
-#define SUBMDL_ES1788	0x10	/* Subtype ES1788 for specific handling */
-#define SUBMDL_ES1868	0x11	/* Subtype ES1868 for specific handling */
-#define SUBMDL_ES1869	0x12	/* Subtype ES1869 for specific handling */
-#define SUBMDL_ES1878	0x13	/* Subtype ES1878 for specific handling */
-#define SUBMDL_ES1887	0x14	/* Subtype ES1887 for specific handling */
-#define SUBMDL_ES1888	0x14	/* Subtype ES1888 for specific handling */
 #define SUBMDL_ALS007	42	/* ALS-007 differs from SB16 only in mixer */
 				/* register assignment */
 #define SUBMDL_ALS100	43	/* ALS-100 allows sampling rates of up */
diff -u --recursive --new-file v2.2.1/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.2.1/linux/drivers/sound/sb_card.c	Thu Jan 28 12:58:02 1999
+++ linux/drivers/sound/sb_card.c	Mon Feb  1 14:04:42 1999
@@ -113,7 +113,7 @@
 }
 
 int sb_be_quiet=0;
-int esstype = 0;	/* ESS chip type */
+extern int esstype;	/* ESS chip type */
 
 #ifdef MODULE
 
@@ -130,13 +130,13 @@
 int io = -1;
 int irq = -1;
 int dma = -1;
-int dma16 = -1;	/* Set this for modules that need it */
-int type = 0;	/* Can set this to a specific card type */
-int mad16 = 0;	/* Set mad16=1 to load this as support for mad16 */
-int trix = 0;	/* Set trix=1 to load this as support for trix */
-int pas2 = 0;	/* Set pas2=1 to load this as support for pas2 */
+int dma16 = -1;		/* Set this for modules that need it */
+int type = 0;		/* Can set this to a specific card type */
+int mad16 = 0;		/* Set mad16=1 to load this as support for mad16 */
+int trix = 0;		/* Set trix=1 to load this as support for trix */
+int pas2 = 0;		/* Set pas2=1 to load this as support for pas2 */
 int sm_games = 0;	/* Mixer - see sb_mixer.c */
-int acer = 0;	/* Do acer notebook init */
+int acer = 0;		/* Do acer notebook init */
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
diff -u --recursive --new-file v2.2.1/linux/drivers/sound/sb_ess.c linux/drivers/sound/sb_ess.c
--- v2.2.1/linux/drivers/sound/sb_ess.c	Mon Jan 25 17:44:34 1999
+++ linux/drivers/sound/sb_ess.c	Sat Feb  6 12:46:21 1999
@@ -1,9 +1,38 @@
+#undef FKS_LOGGING
+#undef FKS_TEST
+
 /*
- * Created: 9-Jan-1999
+ * tabs should be 4 spaces, in vi(m): set tabstop=4
  *
  * TODO: 	consistency speed calculations!!
+ *			cleanup!
  * ????:	Did I break MIDI support?
  *
+ * History:
+ *
+ * Rolf Fokkens	(Dec 20 1998):	ES188x recording level support on a per
+ *								input basis.
+ *				(Dec 24 1998):	Recognition of ES1788, ES1887, ES1888,
+ *								ES1868, ES1869 and ES1878. Could be used for
+ *								specific handling in the future. All except
+ *								ES1887 and ES1888 and ES688 are handled like
+ *								ES1688.
+ *				(Dec 27 1998):	RECLEV for all (?) ES1688+ chips. ES188x now
+ *								have the "Dec 20" support + RECLEV
+ *				(Jan  2 1999):	Preparation for Full Duplex. This means
+ *								Audio 2 is now used for playback when dma16
+ *								is specified. The next step would be to use
+ *								Audio 1 and Audio 2 at the same time.
+ *				(Jan  9 1999):	Put all ESS stuff into sb_ess.[ch], this
+ *								includes both the ESS stuff that has been in
+ *								sb_*[ch] before I touched it and the ESS support
+ *								I added later
+ *				(Jan 23 1999):	Full Duplex seems to work. I wrote a small
+ *								test proggy which works OK. Haven't found
+ *								any applications to test it though. So why did
+ *								I bother to create it anyway?? :) Just for
+ *								fun.
+ *
  * This files contains ESS chip specifics. It's based on the existing ESS
  * handling as it resided in sb_common.c, sb_mixer.c and sb_audio.c. This
  * file adds features like:
@@ -19,27 +48,13 @@
  *
  * ESS detection isn't full proof (yet). If it fails an additional module
  * parameter esstype can be specified to be one of the following:
- * 688, 1688, 1868, 1869, 1788, 1887, 1888
- *
- * History:
- *
- * Rolf Fokkens	(Dec 20 1998):	ES188x recording level support on a per
- *								input basis.
- *				(Dec 24 1998):	Recognition of ES1788, ES1887, ES1888,
- *								ES1868, ES1869 and ES1878. Could be used for
- *								specific handling in the future. All except
- *								ES1887 and ES1888 and ES688 are handled like
- *								ES1688.
- *				(Dec 27 1998):	RECLEV for all (?) ES1688+ chips. ES188x now
- *								have the "Dec 20" support + RECLEV
- *				(jan  2 1999):	Preparation for Full Duplex. This means
- *								Audio 2 is now used for playback when dma16
- *								is specified. The next step would be to use
- *								Audio 1 and Audio 2 at the same time.
+ * -1, 0, 688, 1688, 1868, 1869, 1788, 1887, 1888
+ * -1 means: mimic 2.0 behaviour, 
+ *  0 means: auto detect.
+ *   others: explicitly specify chip
+ * -1 is default, cause auto detect still doesn't work.
  */
 
-#undef FKS_LOGGING
-
 /*
  * About the documentation
  *
@@ -156,13 +171,25 @@
  * ES1946	yes		This is a PCI chip; not handled by this driver
  */
 
+#include <linux/delay.h>
+
 #include "sound_config.h"
 #include "sb_mixer.h"
 #include "sb.h"
 
 #include "sb_ess.h"
 
-extern int esstype; /* module parameter in sb_card.c */
+#define ESSTYPE_LIKE20	-1		/* Mimic 2.0 behaviour					*/
+#define ESSTYPE_DETECT	0		/* Mimic 2.0 behaviour					*/
+
+int esstype = ESSTYPE_LIKE20; /* module parameter in sb_card.c */
+
+#define SUBMDL_ES1788	0x10	/* Subtype ES1788 for specific handling */
+#define SUBMDL_ES1868	0x11	/* Subtype ES1868 for specific handling */
+#define SUBMDL_ES1869	0x12	/* Subtype ES1869 for specific handling */
+#define SUBMDL_ES1878	0x13	/* Subtype ES1878 for specific handling */
+#define SUBMDL_ES1887	0x14	/* Subtype ES1887 for specific handling */
+#define SUBMDL_ES1888	0x15	/* Subtype ES1888 for specific handling */
 
 #ifdef FKS_LOGGING
 static void ess_show_mixerregs (sb_devc *devc);
@@ -370,45 +397,6 @@
 	}
 }
 
-#if 0
-static void ess_speed(sb_devc * devc)
-{
-	int divider;
-	unsigned char bits = 0;
-	int speed = devc->speed;
-
-	if (speed < 4000)
-		speed = 4000;
-	else if (speed > 48000)
-		speed = 48000;
-
-	if (speed > 22000)
-	{
-		bits = 0x80;
-		divider = 256 - (795500 + speed / 2) / speed;
-	}
-	else
-	{
-		divider = 128 - (397700 + speed / 2) / speed;
-	}
-
-	bits |= (unsigned char) divider;
-
-	ess_write (devc, 0xa1, bits);
-
-	/*
-	* Set filter divider register
-	*/
-
-	speed = (speed * 9) / 20;	/* Set filter roll-off to 90% of speed/2 */
-	divider = 256 - 7160000 / (speed * 82);
-
-	ess_write (devc, 0xa2, divider);
-
-	return;
-}
-#endif
-
 static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
 {
 	sb_devc *devc = audio_devs[dev]->devc;
@@ -931,6 +919,29 @@
 	return ess_common_set_irq_hw (devc);
 }
 
+#ifdef FKS_TEST
+
+/*
+ * FKS_test:
+ *	for ES1887: 00, 18, non wr bits: 0001 1000
+ *	for ES1868: 00, b8, non wr bits: 1011 1000
+ *	for ES1888: 00, f8, non wr bits: 1111 1000
+ *	for ES1688: 00, f8, non wr bits: 1111 1000
+ *	+   ES968
+ */
+
+static void FKS_test (sb_devc * devc)
+{
+	int val1, val2;
+	val1 = ess_getmixer (devc, 0x64);
+	ess_setmixer (devc, 0x64, ~val1);
+	val2 = ess_getmixer (devc, 0x64) ^ ~val1;
+	ess_setmixer (devc, 0x64, val1);
+	val1 ^= ess_getmixer (devc, 0x64);
+printk (KERN_INFO "FKS: FKS_test %02x, %02x\n", (val1 & 0x0ff), (val2 & 0x0ff));
+};
+#endif
+
 static unsigned int ess_identify (sb_devc * devc)
 {
 	unsigned int val;
@@ -1025,42 +1036,55 @@
 
 	if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
 		char *chip = NULL;
+		int submodel = -1;
 
-		if (esstype) {
-			int submodel = -1;
-
-			switch (esstype) {
-			case 688:
-				submodel = 0x00;
-				break;
-			case 1688:
-				submodel = 0x08;
-				break;
-			case 1868:
-				submodel = SUBMDL_ES1868;
-				break;
-			case 1869:
-				submodel = SUBMDL_ES1869;
-				break;
-			case 1788:
-				submodel = SUBMDL_ES1788;
-				break;
-			case 1887:
-				submodel = SUBMDL_ES1887;
-				break;
-			case 1888:
-				submodel = SUBMDL_ES1888;
-				break;
-			};
-			if (submodel != -1) {
-				devc->submodel = submodel;
-				sprintf (modelname, "ES%d", esstype);
-				chip = modelname;
-			};
+		switch (esstype) {
+		case ESSTYPE_DETECT:
+		case ESSTYPE_LIKE20:
+			break;
+		case 688:
+			submodel = 0x00;
+			break;
+		case 1688:
+			submodel = 0x08;
+			break;
+		case 1868:
+			submodel = SUBMDL_ES1868;
+			break;
+		case 1869:
+			submodel = SUBMDL_ES1869;
+			break;
+		case 1788:
+			submodel = SUBMDL_ES1788;
+			break;
+		case 1887:
+			submodel = SUBMDL_ES1887;
+			break;
+		case 1888:
+			submodel = SUBMDL_ES1888;
+			break;
+		default:
+			printk (KERN_ERR "Invalid esstype=%d specified\n", esstype);
+			return 0;
+		};
+		if (submodel != -1) {
+			devc->submodel = submodel;
+			sprintf (modelname, "ES%d", esstype);
+			chip = modelname;
 		};
 		if (chip == NULL && (ess_minor & 0x0f) < 8) {
 			chip = "ES688";
 		};
+#ifdef FKS_TEST
+FKS_test (devc);
+#endif
+		/*
+		 * If Nothing detected yet, and we want 2.0 behaviour...
+		 * Then let's assume it's ES1688.
+		 */
+		if (chip == NULL && esstype == ESSTYPE_LIKE20) {
+			chip = "ES1688";
+		};
 
 		if (chip == NULL) {
 			int type;
@@ -1080,6 +1104,10 @@
 				chip = "ES1878";
 				devc->submodel = SUBMDL_ES1878;
 				break;
+			default:
+				if ((type & 0x00ff) != ((type >> 8) & 0x00ff)) {
+					printk ("ess_init: Unrecognized %04x\n", type);
+				}
 			};
 		};
 #if 0
diff -u --recursive --new-file v2.2.1/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- v2.2.1/linux/drivers/sound/sound_core.c	Tue Jan 19 11:32:52 1999
+++ linux/drivers/sound/sound_core.c	Sat Feb  6 12:46:21 1999
@@ -63,6 +63,10 @@
 	int n=low;
 
 	if (index < 0) {	/* first free */
+
+		while (*list && (*list)->unit_minor<n)
+			list=&((*list)->next);
+
 		while(n<top)
 		{
 			/* Found a hole ? */
@@ -73,7 +77,7 @@
 		}
 
 		if(n>=top)
-			return -ENOMEM;
+			return -ENOENT;
 	} else {
 		n = low+(index*16);
 		while (*list) {
@@ -141,13 +145,13 @@
 	int r;
 	struct sound_unit *s=(struct sound_unit *)kmalloc(sizeof(struct sound_unit), GFP_KERNEL);
 	if(s==NULL)
-		return -1;
+		return -ENOMEM;
 		
 	spin_lock(&sound_loader_lock);
 	r=__sound_insert_unit(s,list,fops,index,low,top);
 	spin_unlock(&sound_loader_lock);
 	
-	if(r==-1)
+	if(r<0)
 		kfree(s);
 	return r;
 }
diff -u --recursive --new-file v2.2.1/linux/drivers/sound/sys_timer.c linux/drivers/sound/sys_timer.c
--- v2.2.1/linux/drivers/sound/sys_timer.c	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/sys_timer.c	Mon Feb  1 14:04:42 1999
@@ -13,6 +13,7 @@
  */
 /*
  * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
+ * Andrew Veliath  : adapted tmr2ticks from level 1 sequencer (avoid overflow)
  */
 #include <linux/config.h>
 
@@ -39,11 +40,17 @@
 tmr2ticks(int tmr_value)
 {
 	/*
-	 *    Convert system timer ticks (HZ) to MIDI ticks
-	 *    (divide # of MIDI ticks/minute by # of system ticks/minute).
+	 *    Convert timer ticks to MIDI ticks
 	 */
 
-	return ((tmr_value * curr_tempo * curr_timebase) + (30 * 100)) / (60 * HZ);
+	unsigned long tmp;
+	unsigned long scale;
+
+	/* tmr_value (ticks per sec) *
+	   1000000 (usecs per sec) / HZ (ticks per sec) -=> usecs */
+	tmp = tmr_value * (1000000 / HZ);
+	scale = (60 * 1000000) / (curr_tempo * curr_timebase);	/* usecs per MIDI tick */
+	return (tmp + scale / 2) / scale;
 }
 
 static void
diff -u --recursive --new-file v2.2.1/linux/fs/affs/inode.c linux/fs/affs/inode.c
--- v2.2.1/linux/fs/affs/inode.c	Tue Dec 22 14:16:57 1998
+++ linux/fs/affs/inode.c	Sat Feb  6 12:46:21 1999
@@ -293,7 +293,7 @@
 
 	sb = dir->i_sb;
 	inode->i_sb    = sb;
-	inode->i_flags = sb->s_flags;
+	inode->i_flags = 0;
 
 	if (!(block = affs_new_header((struct inode *)dir))) {
 		iput(inode);
diff -u --recursive --new-file v2.2.1/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.2.1/linux/fs/autofs/root.c	Wed Jan 13 15:00:43 1999
+++ linux/fs/autofs/root.c	Sun Feb 21 11:00:23 1999
@@ -209,7 +209,7 @@
 	NULL,			/* d_compare */
 };
 
-static int autofs_root_lookup(struct inode *dir, struct dentry * dentry)
+static int autofs_root_lookup(struct inode *dir, struct dentry *dentry)
 {
 	struct autofs_sb_info *sbi;
 	int oz_mode;
@@ -220,6 +220,9 @@
 	if (!S_ISDIR(dir->i_mode))
 		return -ENOTDIR;
 
+	if (dentry->d_name.len > NAME_MAX)
+		return -ENOENT;	/* File name too long to exist */
+
 	sbi = autofs_sbi(dir->i_sb);
 
 	oz_mode = autofs_oz_mode(sbi);
@@ -280,6 +283,9 @@
 	if ( !autofs_oz_mode(sbi) )
 		return -EPERM;
 
+	if ( dentry->d_name.len > NAME_MAX )
+		return -ENAMETOOLONG;
+
 	if ( autofs_hash_lookup(dh, &dentry->d_name) )
 		return -EEXIST;
 
@@ -400,6 +406,9 @@
 
 	if ( !autofs_oz_mode(sbi) )
 		return -EPERM;
+
+	if ( dentry->d_name.len > NAME_MAX )
+		return -ENAMETOOLONG;
 
 	ent = autofs_hash_lookup(dh, &dentry->d_name);
 	if ( ent )
diff -u --recursive --new-file v2.2.1/linux/fs/autofs/waitq.c linux/fs/autofs/waitq.c
--- v2.2.1/linux/fs/autofs/waitq.c	Wed Jan 13 15:00:43 1999
+++ linux/fs/autofs/waitq.c	Sun Feb 21 10:59:14 1999
@@ -99,13 +99,17 @@
 		autofs_catatonic_mode(sbi);
 }
 
-int autofs_wait(struct autofs_sb_info *sbi, struct qstr * name)
+int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name)
 {
 	struct autofs_wait_queue *wq;
 	int status;
 
 	/* In catatonic mode, we don't wait for nobody */
 	if ( sbi->catatonic )
+		return -ENOENT;
+	
+	/* We shouldn't be able to get here, but just in case */
+	if ( name->len > NAME_MAX )
 		return -ENOENT;
 
 	for ( wq = sbi->queues ; wq ; wq = wq->next ) {
diff -u --recursive --new-file v2.2.1/linux/fs/buffer.c linux/fs/buffer.c
--- v2.2.1/linux/fs/buffer.c	Tue Jan 19 11:32:52 1999
+++ linux/fs/buffer.c	Tue Feb 16 10:13:14 1999
@@ -74,6 +74,7 @@
 
 static int nr_buffers = 0;
 static int nr_buffers_type[NR_LIST] = {0,};
+static int size_buffers_type[NR_LIST] = {0,};
 static int nr_buffer_heads = 0;
 static int nr_unused_buffer_heads = 0;
 
@@ -99,7 +100,8 @@
 				each time we call refill */
 		int nref_dirt; /* Dirty buffer threshold for activating bdflush
 				  when trying to refill buffers. */
-		int dummy1;    /* unused */
+		int pct_dirt;    /* Max %age of mem for dirty buffers before
+				    activating bdflush */
 		int age_buffer;  /* Time for normal buffer to age before 
 				    we flush it */
 		int age_super;  /* Time for superblock to age before we 
@@ -383,7 +385,9 @@
 		goto out_putf;
 
 	/* this needs further work, at the moment it is identical to fsync() */
+	down(&inode->i_sem);
 	err = file->f_op->fsync(file, dentry);
+	up(&inode->i_sem);
 
 out_putf:
 	fput(file);
@@ -478,6 +482,7 @@
 		return;
 	}
 	nr_buffers_type[bh->b_list]--;
+	size_buffers_type[bh->b_list] -= bh->b_size;
 	remove_from_hash_queue(bh);
 	remove_from_lru_list(bh);
 }
@@ -551,6 +556,7 @@
 		(*bhp)->b_prev_free = bh;
 
 		nr_buffers_type[bh->b_list]++;
+		size_buffers_type[bh->b_list] += bh->b_size;
 
 		/* Put the buffer in new hash-queue if it has a device. */
 		bh->b_next = NULL;
@@ -802,13 +808,19 @@
 		file_buffer(buf, dispose);
 		if(dispose == BUF_DIRTY) {
 			int too_many = (nr_buffers * bdf_prm.b_un.nfract/100);
+			int too_large = (num_physpages * bdf_prm.b_un.pct_dirt/100);
 
 			/* This buffer is dirty, maybe we need to start flushing.
 			 * If too high a percentage of the buffers are dirty...
 			 */
-			if (nr_buffers_type[BUF_DIRTY] > too_many)
-				wakeup_bdflush(0);
-
+			if (nr_buffers_type[BUF_DIRTY] > too_many ||
+			    size_buffers_type[BUF_DIRTY]/PAGE_SIZE > too_large) {
+				if (nr_buffers_type[BUF_LOCKED] > 3 * bdf_prm.b_un.ndirty)
+					wakeup_bdflush(1);
+				else
+					wakeup_bdflush(0);
+			}
+			
 			/* If this is a loop device, and
 			 * more than half of the buffers are dirty...
 			 * (Prevents no-free-buffers deadlock with loop device.)
@@ -1604,7 +1616,7 @@
 #ifdef DEBUG
 	for(nlist = 0; nlist < NR_LIST; nlist++)
 #else
-	for(nlist = BUF_DIRTY; nlist <= BUF_DIRTY; nlist++)
+	for(nlist = BUF_LOCKED; nlist <= BUF_DIRTY; nlist++)
 #endif
 	{
 		ndirty = 0;
@@ -1623,8 +1635,13 @@
 				 }
 				 
 				 /* Clean buffer on dirty list?  Refile it */
-				 if (nlist == BUF_DIRTY && !buffer_dirty(bh) && !buffer_locked(bh))
-				  {
+				 if (nlist == BUF_DIRTY && !buffer_dirty(bh) && !buffer_locked(bh)) {
+					 refile_buffer(bh);
+					 continue;
+				 }
+				  
+				  /* Unlocked buffer on locked list?  Refile it */
+				  if (nlist == BUF_LOCKED && !buffer_locked(bh)) {
 					  refile_buffer(bh);
 					  continue;
 				  }
@@ -1752,7 +1769,7 @@
 #ifdef DEBUG
 		for(nlist = 0; nlist < NR_LIST; nlist++)
 #else
-		for(nlist = BUF_DIRTY; nlist <= BUF_DIRTY; nlist++)
+		for(nlist = BUF_LOCKED; nlist <= BUF_DIRTY; nlist++)
 #endif
 		 {
 			 ndirty = 0;
@@ -1771,11 +1788,16 @@
 					  }
 					  
 					  /* Clean buffer on dirty list?  Refile it */
-					  if (nlist == BUF_DIRTY && !buffer_dirty(bh) && !buffer_locked(bh))
-					   {
-						   refile_buffer(bh);
-						   continue;
-					   }
+					  if (nlist == BUF_DIRTY && !buffer_dirty(bh)) {
+						  refile_buffer(bh);
+						  continue;
+					  }
+					  
+					  /* Unlocked buffer on locked list?  Refile it */
+					  if (nlist == BUF_LOCKED && !buffer_locked(bh)) {
+						  refile_buffer(bh);
+						  continue;
+					  }
 					  
 					  if (buffer_locked(bh) || !buffer_dirty(bh))
 						   continue;
diff -u --recursive --new-file v2.2.1/linux/fs/coda/sysctl.c linux/fs/coda/sysctl.c
--- v2.2.1/linux/fs/coda/sysctl.c	Tue Dec 22 14:16:57 1998
+++ linux/fs/coda/sysctl.c	Sat Feb  6 12:46:21 1999
@@ -24,6 +24,8 @@
 #include <asm/segment.h>
 #include <asm/uaccess.h>
 #include <linux/utsname.h>
+#define __NO_VERSION__
+#include <linux/module.h>
 
 #include <linux/coda.h>
 #include <linux/coda_linux.h>
@@ -491,6 +493,14 @@
                 coda_cache_inv_stats_get_info
         };
 
+static void coda_proc_modcount(struct inode *inode, int fill)
+{
+	if (fill)
+		MOD_INC_USE_COUNT;
+	else
+		MOD_DEC_USE_COUNT;
+}
+
 #endif
 
 
@@ -504,6 +514,7 @@
 
 #ifdef CONFIG_PROC_FS
 	proc_register(&proc_root_fs,&proc_fs_coda);
+	proc_fs_coda.fill_inode = &coda_proc_modcount;
 	proc_register(&proc_fs_coda,&proc_coda_vfs);
 	proc_register(&proc_fs_coda,&proc_coda_upcall);
 	proc_register(&proc_fs_coda,&proc_coda_permission);
diff -u --recursive --new-file v2.2.1/linux/fs/hfs/ChangeLog linux/fs/hfs/ChangeLog
--- v2.2.1/linux/fs/hfs/ChangeLog	Mon Dec 28 15:00:52 1998
+++ linux/fs/hfs/ChangeLog	Mon Feb 15 23:55:00 1999
@@ -1,3 +1,13 @@
+1999-01-30  a sun  <asun@hecate.darksunrising.blah>
+
+	* catalog.c (hfs_cat_move): fixed corruption problem with
+	renames.
+
+1999-01-27  a sun  <asun@hecate.darksunrising.blah>
+
+	* file_hdr.c (get/set_dates): got rid of broken afpd times. NOTE:
+	you must use netatalk-1.4b2+asun2.1.2 or newer for this.
+
 1998-12-20  a sun  <asun@hecate.darksunrising.blah>
 
 	* bdelete.c (del_root): assign bthLNode and bthFNode only if the
diff -u --recursive --new-file v2.2.1/linux/fs/hfs/catalog.c linux/fs/hfs/catalog.c
--- v2.2.1/linux/fs/hfs/catalog.c	Sun Nov  8 14:03:05 1998
+++ linux/fs/hfs/catalog.c	Mon Feb 15 23:55:00 1999
@@ -1348,7 +1348,7 @@
 		hfs_sleep_on(&mdb->rename_wait);
 	}
 	spin_lock(&entry_lock);
-	mdb->rename_lock = 1;
+	mdb->rename_lock = 1; /* XXX: should be atomic_inc */
 	spin_unlock(&entry_lock);
 
 	/* keep readers from getting confused by changing dir size */
@@ -1385,7 +1385,6 @@
 restart:
 	/* see if the destination exists, getting it if it does */
 	dest = hfs_cat_get(mdb, new_key);
-
 	if (!dest) {
 		/* destination doesn't exist, so create it */
 		struct hfs_cat_rec new_record;
@@ -1408,14 +1407,16 @@
 			goto bail3;
 		}
 
-		/* build the new record */
+		/* build the new record. make sure to zero out the
+                   record. */
+		memset(&new_record, 0, sizeof(new_record));
 		new_record.cdrType = entry->type;
 		__write_entry(entry, &new_record);
 
 		/* insert the new record */
 		error = hfs_binsert(mdb->cat_tree, HFS_BKEY(new_key),
 				    &new_record, is_dir ? 2 + sizeof(DIR_REC) :
-							  2 + sizeof(FIL_REC));
+				    2 + sizeof(FIL_REC));
 		if (error == -EEXIST) {
 			delete_entry(dest);
 			unlock_entry(dest);
@@ -1565,7 +1566,7 @@
 	}
 	end_write(new_dir);
 	spin_lock(&entry_lock);
-	mdb->rename_lock = 0;
+	mdb->rename_lock = 0; /* XXX: should use atomic_dec */
 	hfs_wake_up(&mdb->rename_wait);
 	spin_unlock(&entry_lock);
 
diff -u --recursive --new-file v2.2.1/linux/fs/hfs/file_hdr.c linux/fs/hfs/file_hdr.c
--- v2.2.1/linux/fs/hfs/file_hdr.c	Thu Nov 19 09:56:28 1998
+++ linux/fs/hfs/file_hdr.c	Mon Feb 15 23:55:00 1999
@@ -303,16 +303,9 @@
 static void get_dates(const struct hfs_cat_entry *entry,
 		      const struct inode *inode,  hfs_u32 dates[3])
 {
-	if (HFS_SB(inode->i_sb)->s_afpd) {
-		/* AFPD compatible: use un*x times */
-		dates[0] = htonl(hfs_m_to_utime(entry->create_date));
-		dates[1] = htonl(hfs_m_to_utime(entry->modify_date));
-		dates[2] = htonl(hfs_m_to_utime(entry->backup_date));
-	} else {
-		dates[0] = hfs_m_to_htime(entry->create_date);
-		dates[1] = hfs_m_to_htime(entry->modify_date);
-		dates[2] = hfs_m_to_htime(entry->backup_date);
-	}
+	dates[0] = hfs_m_to_htime(entry->create_date);
+	dates[1] = hfs_m_to_htime(entry->modify_date);
+	dates[2] = hfs_m_to_htime(entry->backup_date);
 }
 
 /*
@@ -322,43 +315,23 @@
 		      const hfs_u32 *dates)
 {
 	hfs_u32 tmp;
-	if (HFS_SB(inode->i_sb)->s_afpd) {
-		/* AFPD compatible: use un*x times */
-		tmp = hfs_u_to_mtime(ntohl(dates[0]));
-		if (entry->create_date != tmp) {
-			entry->create_date = tmp;
-			hfs_cat_mark_dirty(entry);
-		}
-		tmp = hfs_u_to_mtime(ntohl(dates[1]));
-		if (entry->modify_date != tmp) {
-			entry->modify_date = tmp;
-			inode->i_ctime = inode->i_atime = inode->i_mtime =
-				ntohl(dates[1]);
-			hfs_cat_mark_dirty(entry);
-		}
-		tmp = hfs_u_to_mtime(ntohl(dates[2]));
-		if (entry->backup_date != tmp) {
-			entry->backup_date = tmp;
-			hfs_cat_mark_dirty(entry);
-		}
-	} else {
-		tmp = hfs_h_to_mtime(dates[0]);
-		if (entry->create_date != tmp) {
-			entry->create_date = tmp;
-			hfs_cat_mark_dirty(entry);
-		}
-		tmp = hfs_h_to_mtime(dates[1]);
-		if (entry->modify_date != tmp) {
-			entry->modify_date = tmp;
-			inode->i_ctime = inode->i_atime = inode->i_mtime = 
-				hfs_h_to_utime(dates[1]);
-			hfs_cat_mark_dirty(entry);
-		}
-		tmp = hfs_h_to_mtime(dates[2]);
-		if (entry->backup_date != tmp) {
-			entry->backup_date = tmp;
-			hfs_cat_mark_dirty(entry);
-		}
+
+	tmp = hfs_h_to_mtime(dates[0]);
+	if (entry->create_date != tmp) {
+		entry->create_date = tmp;
+		hfs_cat_mark_dirty(entry);
+	}
+	tmp = hfs_h_to_mtime(dates[1]);
+	if (entry->modify_date != tmp) {
+		entry->modify_date = tmp;
+		inode->i_ctime = inode->i_atime = inode->i_mtime = 
+			hfs_h_to_utime(dates[1]);
+		hfs_cat_mark_dirty(entry);
+	}
+	tmp = hfs_h_to_mtime(dates[2]);
+	if (entry->backup_date != tmp) {
+		entry->backup_date = tmp;
+		hfs_cat_mark_dirty(entry);
 	}
 }
 
diff -u --recursive --new-file v2.2.1/linux/fs/inode.c linux/fs/inode.c
--- v2.2.1/linux/fs/inode.c	Mon Jan 25 17:44:34 1999
+++ linux/fs/inode.c	Mon Feb 22 11:47:42 1999
@@ -62,9 +62,8 @@
 struct {
 	int nr_inodes;
 	int nr_free_inodes;
-	int preshrink;		/* pre-shrink dcache? */
-	int dummy[4];
-} inodes_stat = {0, 0, 0,};
+	int dummy[5];
+} inodes_stat = {0, 0,};
 
 int max_inodes;
 
@@ -196,6 +195,19 @@
 }
 
 /*
+ * Called with the spinlock already held..
+ */
+static void sync_all_inodes(void)
+{
+	struct super_block * sb = sb_entry(super_blocks.next);
+	for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.next)) {
+		if (!sb->s_dev)
+			continue;
+		sync_list(&sb->s_dirty);
+	}
+}
+
+/*
  * Needed by knfsd
  */
 void write_inode_now(struct inode *inode)
@@ -232,13 +244,15 @@
 
 /*
  * Dispose-list gets a local list, so it doesn't need to
- * worry about list corruption.
+ * worry about list corruption. It releases the inode lock
+ * while clearing the inodes.
  */
 static void dispose_list(struct list_head * head)
 {
 	struct list_head *next;
 	int count = 0;
 
+	spin_unlock(&inode_lock);
 	next = head->next;
 	for (;;) {
 		struct list_head * tmp = next;
@@ -256,7 +270,6 @@
 	spin_lock(&inode_lock);
 	list_splice(head, &inode_unused);
 	inodes_stat.nr_free_inodes += count;
-	spin_unlock(&inode_lock);
 }
 
 /*
@@ -305,65 +318,53 @@
 	spin_lock(&inode_lock);
 	busy = invalidate_list(&inode_in_use, sb, &throw_away);
 	busy |= invalidate_list(&sb->s_dirty, sb, &throw_away);
-	spin_unlock(&inode_lock);
-
 	dispose_list(&throw_away);
+	spin_unlock(&inode_lock);
 
 	return busy;
 }
 
 /*
  * This is called with the inode lock held. It searches
- * the in-use for the specified number of freeable inodes.
- * Freeable inodes are moved to a temporary list and then
- * placed on the unused list by dispose_list.
+ * the in-use for freeable inodes, which are moved to a
+ * temporary list and then placed on the unused list by
+ * dispose_list. 
+ *
+ * We don't expect to have to call this very often.
  *
- * Note that we do not expect to have to search very hard:
- * the freeable inodes will be at the old end of the list.
- * 
- * N.B. The spinlock is released to call dispose_list.
+ * N.B. The spinlock is released during the call to
+ *      dispose_list.
  */
 #define CAN_UNUSE(inode) \
-	(((inode)->i_count == 0) && \
-	 (!(inode)->i_state))
+	(((inode)->i_count | (inode)->i_state) == 0)
+#define INODE(entry)	(list_entry(entry, struct inode, i_list))
 
-static int free_inodes(int goal)
+static int free_inodes(void)
 {
-	struct list_head *tmp, *head = &inode_in_use;
-	LIST_HEAD(freeable);
-	int found = 0, depth = goal << 1;
+	struct list_head list, *entry, *freeable = &list;
+	int found = 0;
 
-	while ((tmp = head->prev) != head && depth--) {
-		struct inode * inode = list_entry(tmp, struct inode, i_list);
+	INIT_LIST_HEAD(freeable);
+	entry = inode_in_use.next;
+	while (entry != &inode_in_use) {
+		struct list_head *tmp = entry;
+
+		entry = entry->next;
+		if (!CAN_UNUSE(INODE(tmp)))
+			continue;
 		list_del(tmp);
-		if (CAN_UNUSE(inode)) {
-			list_del(&inode->i_hash);
-			INIT_LIST_HEAD(&inode->i_hash);
-			list_add(tmp, &freeable);
-			if (++found < goal)
-				continue;
-			break;
-		}
-		list_add(tmp, head);
+		list_del(&INODE(tmp)->i_hash);
+		INIT_LIST_HEAD(&INODE(tmp)->i_hash);
+		list_add(tmp, freeable);
+		found = 1;
 	}
+
 	if (found) {
-		spin_unlock(&inode_lock);
-		dispose_list(&freeable);
-		spin_lock(&inode_lock);
+		dispose_list(freeable);
+		found = 1;	/* silly compiler */
 	}
-	return found;
-}
 
-static void shrink_dentry_inodes(int goal)
-{
-	int found;
-
-	spin_unlock(&inode_lock);
-	found = select_dcache(goal, 0);
-	if (found < goal)
-		found = goal;
-	prune_dcache(found);
-	spin_lock(&inode_lock);
+	return found;
 }
 
 /*
@@ -373,9 +374,23 @@
  */
 static void try_to_free_inodes(int goal)
 {
-	shrink_dentry_inodes(goal);
-	if (!free_inodes(goal))
-		shrink_dentry_inodes(goal);
+	/*
+	 * First stry to just get rid of unused inodes.
+	 *
+	 * If we can't reach our goal that way, we'll have
+	 * to try to shrink the dcache and sync existing
+	 * inodes..
+	 */
+	free_inodes();
+	goal -= inodes_stat.nr_free_inodes;
+	if (goal > 0) {
+		spin_unlock(&inode_lock);
+		select_dcache(goal, 0);
+		prune_dcache(goal);
+		spin_lock(&inode_lock);
+		sync_all_inodes();
+		free_inodes();
+	}
 }
 
 /*
@@ -385,7 +400,7 @@
 void free_inode_memory(int goal)
 {
 	spin_lock(&inode_lock);
-	free_inodes(goal);
+	free_inodes();
 	spin_unlock(&inode_lock);
 }
 
@@ -403,9 +418,9 @@
 	/*
 	 * Check whether to restock the unused list.
 	 */
-	if (inodes_stat.preshrink) {
+	if (inodes_stat.nr_inodes > max_inodes) {
 		struct list_head *tmp;
-		try_to_free_inodes(8);
+		try_to_free_inodes(inodes_stat.nr_inodes >> 2);
 		tmp = inode_unused.next;
 		if (tmp != &inode_unused) {
 			inodes_stat.nr_free_inodes--;
@@ -436,9 +451,6 @@
 		 */
 		inodes_stat.nr_inodes += INODES_PER_PAGE;
 		inodes_stat.nr_free_inodes += INODES_PER_PAGE - 1;
-		inodes_stat.preshrink = 0;
-		if (inodes_stat.nr_inodes > max_inodes)
-			inodes_stat.preshrink = 1;
 		return inode;
 	}
 
@@ -447,10 +459,9 @@
 	 * the dcache and then try again to free some inodes.
 	 */
 	prune_dcache(inodes_stat.nr_inodes >> 2);
-	inodes_stat.preshrink = 1;
 
 	spin_lock(&inode_lock);
-	free_inodes(inodes_stat.nr_inodes >> 2);
+	free_inodes();
 	{
 		struct list_head *tmp = inode_unused.next;
 		if (tmp != &inode_unused) {
diff -u --recursive --new-file v2.2.1/linux/fs/lockd/clntproc.c linux/fs/lockd/clntproc.c
--- v2.2.1/linux/fs/lockd/clntproc.c	Thu Dec 31 10:29:02 1998
+++ linux/fs/lockd/clntproc.c	Wed Feb 17 09:44:33 1999
@@ -30,6 +30,14 @@
  */
 static u32	nlm_cookie = 0x1234;
 
+static inline void nlmclnt_next_cookie(struct nlm_cookie *c)
+{
+	memcpy(c->data, &nlm_cookie, 4);
+	memset(c->data+4, 0, 4);
+	c->len=4;
+	nlm_cookie++;
+}
+
 /*
  * Initialize arguments for TEST/LOCK/UNLOCK/CANCEL calls
  */
@@ -40,7 +48,7 @@
 	struct nlm_lock	*lock = &argp->lock;
 
 	memset(argp, 0, sizeof(*argp));
-	argp->cookie  = nlm_cookie++;
+	nlmclnt_next_cookie(&argp->cookie);
 	argp->state   = nsm_local_state;
 	lock->fh      = *NFS_FH(fl->fl_file->f_dentry);
 	lock->caller  = system_utsname.nodename;
@@ -57,7 +65,7 @@
 int
 nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
 {
-	call->a_args.cookie  = nlm_cookie++;
+	nlmclnt_next_cookie(&call->a_args.cookie);
 	call->a_args.lock    = *lock;
 	call->a_args.lock.caller = system_utsname.nodename;
 
@@ -230,9 +238,24 @@
 		/* Perform the RPC call. If an error occurs, try again */
 		if ((status = rpc_call(clnt, proc, argp, resp, 0)) < 0) {
 			dprintk("lockd: rpc_call returned error %d\n", -status);
-			if (status == -ERESTARTSYS)
-				return status;
-			nlm_rebind_host(host);
+			switch (status) {
+			case -EPROTONOSUPPORT:
+				status = -EINVAL;
+				break;
+			case -ECONNREFUSED:
+			case -ETIMEDOUT:
+			case -ENOTCONN:
+				status = -EAGAIN;
+				break;
+			case -ERESTARTSYS:
+				return signalled () ? -EINTR : status;
+			default:
+				break;
+			}
+			if (req->a_args.block)
+				nlm_rebind_host(host);
+			else
+				break;
 		} else
 		if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) {
 			dprintk("lockd: server in grace period\n");
@@ -248,9 +271,18 @@
 
 		/* Back off a little and try again */
 		interruptible_sleep_on_timeout(&host->h_gracewait, 15*HZ);
-	} while (!signalled());
 
-	return -ERESTARTSYS;
+		/* When the lock requested by F_SETLKW isn't available,
+		   we will wait until the request can be satisfied. If
+		   a signal is received during wait, we should return
+		   -EINTR. */
+		if (signalled ()) {
+			status = -EINTR;
+			break;
+		}
+	} while (1);
+
+	return status;
 }
 
 /*
diff -u --recursive --new-file v2.2.1/linux/fs/lockd/svc.c linux/fs/lockd/svc.c
--- v2.2.1/linux/fs/lockd/svc.c	Thu Dec 31 10:29:02 1998
+++ linux/fs/lockd/svc.c	Sat Feb  6 12:46:21 1999
@@ -64,6 +64,7 @@
 {
 	struct svc_serv	*serv = rqstp->rq_server;
 	int		err = 0;
+	unsigned long grace_period_expire;
 
 	/* Lock module and set up kernel thread */
 	MOD_INC_USE_COUNT;
@@ -111,7 +112,7 @@
 	}
 #endif
 
-	nlmsvc_grace_period += jiffies;
+	grace_period_expire = nlmsvc_grace_period + jiffies;
 	nlmsvc_timeout = nlm_timeout * HZ;
 
 	/*
diff -u --recursive --new-file v2.2.1/linux/fs/lockd/svclock.c linux/fs/lockd/svclock.c
--- v2.2.1/linux/fs/lockd/svclock.c	Thu Nov 12 16:21:22 1998
+++ linux/fs/lockd/svclock.c	Wed Feb 17 09:44:33 1999
@@ -111,16 +111,25 @@
 	return NULL;
 }
 
+static inline int nlm_cookie_match(struct nlm_cookie *a, struct nlm_cookie *b)
+{
+	if(a->len != b->len)
+		return 0;
+	if(memcmp(a->data,b->data,a->len))
+		return 0;
+	return 1;
+}
+
 /*
  * Find a block with a given NLM cookie.
  */
 static inline struct nlm_block *
-nlmsvc_find_block(u32 cookie)
+nlmsvc_find_block(struct nlm_cookie *cookie)
 {
 	struct nlm_block *block;
 
 	for (block = nlm_blocked; block; block = block->b_next) {
-		if (block->b_call.a_args.cookie == cookie)
+		if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie))
 			break;
 	}
 
@@ -139,7 +148,7 @@
  */
 static inline struct nlm_block *
 nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
-				struct nlm_lock *lock, u32 cookie)
+				struct nlm_lock *lock, struct nlm_cookie *cookie)
 {
 	struct nlm_block	*block;
 	struct nlm_host		*host;
@@ -160,7 +169,7 @@
 	lock->fl.fl_notify = nlmsvc_notify_blocked;
 	if (!nlmclnt_setgrantargs(&block->b_call, lock))
 		goto failed_free;
-	block->b_call.a_args.cookie = cookie;	/* see above */
+	block->b_call.a_args.cookie = *cookie;	/* see above */
 
 	dprintk("lockd: created block %p...\n", block);
 
@@ -267,7 +276,7 @@
  */
 u32
 nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
-			struct nlm_lock *lock, int wait, u32 cookie)
+			struct nlm_lock *lock, int wait, struct nlm_cookie *cookie)
 {
 	struct file_lock	*conflock;
 	struct nlm_block	*block;
@@ -529,8 +538,8 @@
 	unsigned long		timeout;
 
 	dprintk("lockd: GRANT_MSG RPC callback\n");
-	if (!(block = nlmsvc_find_block(call->a_args.cookie))) {
-		dprintk("lockd: no block for cookie %x\n", call->a_args.cookie);
+	if (!(block = nlmsvc_find_block(&call->a_args.cookie))) {
+		dprintk("lockd: no block for cookie %x\n", *(u32 *)(call->a_args.cookie.data));
 		return;
 	}
 
@@ -560,7 +569,7 @@
  * block.
  */
 void
-nlmsvc_grant_reply(u32 cookie, u32 status)
+nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
 {
 	struct nlm_block	*block;
 	struct nlm_file		*file;
diff -u --recursive --new-file v2.2.1/linux/fs/lockd/svcproc.c linux/fs/lockd/svcproc.c
--- v2.2.1/linux/fs/lockd/svcproc.c	Thu Dec 31 10:29:02 1998
+++ linux/fs/lockd/svcproc.c	Wed Feb 17 09:44:33 1999
@@ -151,7 +151,7 @@
 
 	/* Now try to lock the file */
 	resp->status = nlmsvc_lock(rqstp, file, &argp->lock,
-					argp->block, argp->cookie);
+					argp->block, &argp->cookie);
 
 	dprintk("lockd: LOCK          status %ld\n", ntohl(resp->status));
 	nlm_release_host(host);
diff -u --recursive --new-file v2.2.1/linux/fs/lockd/xdr.c linux/fs/lockd/xdr.c
--- v2.2.1/linux/fs/lockd/xdr.c	Tue Mar 10 10:03:34 1998
+++ linux/fs/lockd/xdr.c	Sat Feb  6 12:46:21 1999
@@ -53,28 +53,38 @@
 /*
  * XDR functions for basic NLM types
  */
-static inline u32 *
-nlm_decode_cookie(u32 *p, u32 *c)
+static inline u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c)
 {
 	unsigned int	len;
 
-	if ((len = ntohl(*p++)) == 4) {
-		*c = ntohl(*p++);
-	} else if (len == 0) {		/* hockeypux brain damage */
-		*c = 0;
-	} else {
+	len = ntohl(*p++);
+	
+	if(len==0)
+	{
+		c->len=4;
+		memset(c->data, 0, 4);	/* hockeypux brain damage */
+	}
+	else if(len<=8)
+	{
+		c->len=len;
+		memcpy(c->data, p, len);
+		p+=(len+3)>>2;
+	}
+	else 
+	{
 		printk(KERN_NOTICE
-			"lockd: bad cookie size %d (should be 4)\n", len);
+			"lockd: bad cookie size %d (only cookies under 8 bytes are supported.)\n", len);
 		return NULL;
 	}
 	return p;
 }
 
 static inline u32 *
-nlm_encode_cookie(u32 *p, u32 c)
+nlm_encode_cookie(u32 *p, struct nlm_cookie *c)
 {
-	*p++ = htonl(sizeof(c));
-	*p++ = htonl(c);
+	*p++ = htonl(c->len);
+	memcpy(p, c->data, c->len);
+	p+=(c->len+3)>>2;
 	return p;
 }
 
@@ -168,7 +178,7 @@
 static u32 *
 nlm_encode_testres(u32 *p, struct nlm_res *resp)
 {
-	if (!(p = nlm_encode_cookie(p, resp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &resp->cookie)))
 		return 0;
 	*p++ = resp->status;
 
@@ -308,7 +318,7 @@
 int
 nlmsvc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 {
-	if (!(p = nlm_encode_cookie(p, resp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &resp->cookie)))
 		return 0;
 	*p++ = resp->status;
 	*p++ = xdr_zero;		/* sequence argument */
@@ -318,7 +328,7 @@
 int
 nlmsvc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 {
-	if (!(p = nlm_encode_cookie(p, resp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &resp->cookie)))
 		return 0;
 	*p++ = resp->status;
 	return xdr_ressize_check(rqstp, p);
@@ -388,7 +398,7 @@
 {
 	struct nlm_lock	*lock = &argp->lock;
 
-	if (!(p = nlm_encode_cookie(p, argp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &argp->cookie)))
 		return -EIO;
 	*p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
 	if (!(p = nlm_encode_lock(p, lock)))
@@ -429,7 +439,7 @@
 {
 	struct nlm_lock	*lock = &argp->lock;
 
-	if (!(p = nlm_encode_cookie(p, argp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &argp->cookie)))
 		return -EIO;
 	*p++ = argp->block? xdr_one : xdr_zero;
 	*p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
@@ -446,7 +456,7 @@
 {
 	struct nlm_lock	*lock = &argp->lock;
 
-	if (!(p = nlm_encode_cookie(p, argp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &argp->cookie)))
 		return -EIO;
 	*p++ = argp->block? xdr_one : xdr_zero;
 	*p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
@@ -461,7 +471,7 @@
 {
 	struct nlm_lock	*lock = &argp->lock;
 
-	if (!(p = nlm_encode_cookie(p, argp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &argp->cookie)))
 		return -EIO;
 	if (!(p = nlm_encode_lock(p, lock)))
 		return -EIO;
@@ -472,7 +482,7 @@
 static int
 nlmclt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
 {
-	if (!(p = nlm_encode_cookie(p, resp->cookie)))
+	if (!(p = nlm_encode_cookie(p, &resp->cookie)))
 		return -EIO;
 	*p++ = resp->status;
 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
@@ -501,7 +511,7 @@
  * Buffer requirements for NLM
  */
 #define NLM_void_sz		0
-#define NLM_cookie_sz		2
+#define NLM_cookie_sz		3	/* 1 len , 2 data */
 #define NLM_caller_sz		1+QUADLEN(sizeof(system_utsname.nodename))
 #define NLM_netobj_sz		1+QUADLEN(XDR_MAX_NETOBJ)
 /* #define NLM_owner_sz		1+QUADLEN(NLM_MAXOWNER) */
diff -u --recursive --new-file v2.2.1/linux/fs/nfsd/nfsproc.c linux/fs/nfsd/nfsproc.c
--- v2.2.1/linux/fs/nfsd/nfsproc.c	Sun Jul 26 11:57:18 1998
+++ linux/fs/nfsd/nfsproc.c	Fri Jan 29 11:09:56 1999
@@ -515,7 +515,7 @@
   PROC(symlink,	 symlinkargs,	void,		none,		RC_REPLSTAT),
   PROC(mkdir,	 createargs,	diropres,	fhandle,	RC_REPLBUFF),
   PROC(rmdir,	 diropargs,	void,		none,		RC_REPLSTAT),
-  PROC(readdir,	 readdirargs,	readdirres,	none,		RC_REPLSTAT),
+  PROC(readdir,	 readdirargs,	readdirres,	none,		RC_REPLBUFF),
   PROC(statfs,	 fhandle,	statfsres,	none,		RC_NOCACHE),
 };
 
diff -u --recursive --new-file v2.2.1/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- v2.2.1/linux/fs/nfsd/vfs.c	Thu Jan 28 12:58:02 1999
+++ linux/fs/nfsd/vfs.c	Mon Feb 15 16:34:59 1999
@@ -734,7 +734,7 @@
 	 * directories via NFS.
 	 */
 	err = 0;
-	if ((iap->ia_valid &= (ATTR_UID|ATTR_GID|ATTR_MODE)) != 0)
+	if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0)
 		err = nfsd_setattr(rqstp, resfhp, iap);
 out:
 	return err;
diff -u --recursive --new-file v2.2.1/linux/fs/open.c linux/fs/open.c
--- v2.2.1/linux/fs/open.c	Thu Dec 31 10:29:02 1998
+++ linux/fs/open.c	Sun Feb 21 11:37:55 1999
@@ -22,10 +22,11 @@
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
 		struct inode * inode = dentry->d_inode;
+		struct super_block * sb = inode->i_sb;
 
-		error = -ENOSYS;
-		if (inode->i_sb->s_op->statfs)
-			error = inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
+		error = -ENODEV;
+		if (sb && sb->s_op && sb->s_op->statfs)
+			error = sb->s_op->statfs(sb, buf, sizeof(struct statfs));
 
 		dput(dentry);
 	}
@@ -52,10 +53,8 @@
 	if (!(inode = dentry->d_inode))
 		goto out_putf;
 	error = -ENODEV;
-	if (!(sb = inode->i_sb))
-		goto out_putf;
-	error = -ENOSYS;
-	if (sb->s_op->statfs)
+	sb = inode->i_sb;
+	if (sb && sb->s_op && sb->s_op->statfs)
 		error = sb->s_op->statfs(sb, buf, sizeof(struct statfs));
 out_putf:
 	fput(file);
diff -u --recursive --new-file v2.2.1/linux/fs/smbfs/file.c linux/fs/smbfs/file.c
--- v2.2.1/linux/fs/smbfs/file.c	Thu Nov 12 16:21:23 1998
+++ linux/fs/smbfs/file.c	Wed Feb 17 15:59:32 1999
@@ -144,7 +144,7 @@
 
 		result = smb_proc_write(dentry, offset, wsize, buffer);
 		if (result < 0)
-			goto io_error;
+			break;
 		/* N.B. what if result < wsize?? */
 #ifdef SMBFS_PARANOIA
 if (result < wsize)
@@ -162,15 +162,7 @@
 			inode->i_size = offset;
 		inode->u.smbfs_i.cache_valid |= SMB_F_LOCALWRITE;
 	} while (count);
-
-out:
-	smb_unlock_page(page);
 	return written ? written : result;
-
-io_error:
-	/* Must mark the page invalid after I/O error */
-	clear_bit(PG_uptodate, &page->flags);
-	goto out;
 }
 
 /*
@@ -190,6 +182,7 @@
 	set_bit(PG_locked, &page->flags);
 	atomic_inc(&page->count);
 	result = smb_writepage_sync(dentry, page, 0, PAGE_SIZE);
+	smb_unlock_page(page);
 	free_page(page_address(page));
 	return result;
 }
diff -u --recursive --new-file v2.2.1/linux/include/asm-i386/irq.h linux/include/asm-i386/irq.h
--- v2.2.1/linux/include/asm-i386/irq.h	Tue Jul 21 00:15:32 1998
+++ linux/include/asm-i386/irq.h	Tue Feb 16 14:20:05 1999
@@ -13,11 +13,15 @@
 #define TIMER_IRQ 0
 
 /*
- * 16 XT IRQ's, 8 potential APIC interrupt sources.
- * Right now the APIC is only used for SMP, but this
- * may change.
+ * 16 8259A IRQ's, 240 potential APIC interrupt sources.
+ * Right now the APIC is mostly only used for SMP.
+ * 256 vectors is an architectural limit. (we can have
+ * more than 256 devices theoretically, but they will
+ * have to use shared interrupts)
+ * Since vectors 0x00-0x1f are used/reserved for the CPU,
+ * the usable vector space is 0x20-0xff (224 vectors)
  */
-#define NR_IRQS 64
+#define NR_IRQS 224
 
 static __inline__ int irq_cannonicalize(int irq)
 {
diff -u --recursive --new-file v2.2.1/linux/include/asm-i386/semaphore-helper.h linux/include/asm-i386/semaphore-helper.h
--- v2.2.1/linux/include/asm-i386/semaphore-helper.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-i386/semaphore-helper.h	Wed Feb 17 09:34:13 1999
@@ -0,0 +1,94 @@
+#ifndef _I386_SEMAPHORE_HELPER_H
+#define _I386_SEMAPHORE_HELPER_H
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ * (C) Copyright 1999 Andrea Arcangeli
+ */
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ *
+ * This is trivially done with load_locked/store_cond,
+ * but on the x86 we need an external synchronizer.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (atomic_read(&sem->count) <= 0)
+		sem->waking++;
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking > 0) {
+		sem->waking--;
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking > 0) {
+		sem->waking--;
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ *	1	failed to lock
+ *	0	got the lock
+ *
+ * We must undo the sem->count down_trylock() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking <= 0)
+		atomic_inc(&sem->count);
+	else {
+		sem->waking--;
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif
diff -u --recursive --new-file v2.2.1/linux/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h
--- v2.2.1/linux/include/asm-i386/semaphore.h	Tue Jan 19 11:32:53 1999
+++ linux/include/asm-i386/semaphore.h	Mon Feb 22 14:50:23 1999
@@ -12,6 +12,11 @@
  *                     the original code and to make semaphore waits
  *                     interruptible so that processes waiting on
  *                     semaphores can be killed.
+ * Modified 1999-02-14 by Andrea Arcangeli, split the sched.c helper
+ *		       functions in asm/sempahore-helper.h while fixing a
+ *		       potential and subtle race discovered by Ulrich Schmid
+ *		       in down_interruptible(). Since I started to play here I
+ *		       also implemented the `trylock' semaphore operation.
  *
  * If you would like to see an analysis of this implementation, please
  * ftp to gcom.com and download the file
@@ -23,56 +28,23 @@
 #include <asm/atomic.h>
 #include <asm/spinlock.h>
 
-/*
- * Semaphores are recursive: we allow the holder process
- * to recursively do down() operations on a semaphore that
- * the process already owns. In order to do that, we need
- * to keep a semaphore-local copy of the owner and the
- * "depth of ownership".
- *
- * NOTE! Nasty memory ordering rules:
- *  - "owner" and "owner_count" may only be modified once you hold the
- *    lock. 
- *  - "owner_count" must be written _after_ modifying owner, and
- *    must be read _before_ reading owner. There must be appropriate
- *    write and read barriers to enforce this.
- *
- * On an x86, writes are always ordered, so the only enformcement
- * necessary is to make sure that the owner_depth is written after
- * the owner value in program order.
- *
- * For read ordering guarantees, the semaphore wake_lock spinlock
- * is already giving us ordering guarantees.
- *
- * Other (saner) architectures would use "wmb()" and "rmb()" to
- * do this in a more obvious manner.
- */
 struct semaphore {
 	atomic_t count;
-	unsigned long owner, owner_depth;
 	int waking;
 	struct wait_queue * wait;
 };
 
-/*
- * Because we want the non-contention case to be
- * fast, we save the stack pointer into the "owner"
- * field, and to get the true task pointer we have
- * to do the bit masking. That moves the masking
- * operation into the slow path.
- */
-#define semaphore_owner(sem) \
-	((struct task_struct *)((2*PAGE_MASK) & (sem)->owner))
-
-#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, 0, 0, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, 1, 0, NULL })
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL })
 
 asmlinkage void __down_failed(void /* special register calling convention */);
 asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
 asmlinkage void __up_wakeup(void /* special register calling convention */);
 
 asmlinkage void __down(struct semaphore * sem);
 asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
 asmlinkage void __up(struct semaphore * sem);
 
 extern spinlock_t semaphore_wake_lock;
@@ -80,75 +52,6 @@
 #define sema_init(sem, val)	atomic_set(&((sem)->count), (val))
 
 /*
- * These two _must_ execute atomically wrt each other.
- *
- * This is trivially done with load_locked/store_cond,
- * but on the x86 we need an external synchronizer.
- */
-static inline void wake_one_more(struct semaphore * sem)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&semaphore_wake_lock, flags);
-	sem->waking++;
-	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
-}
-
-/*
- * NOTE NOTE NOTE!
- *
- * We read owner-count _before_ getting the semaphore. This
- * is important, because the semaphore also acts as a memory
- * ordering point between reading owner_depth and reading
- * the owner.
- *
- * Why is this necessary? The "owner_depth" essentially protects
- * us from using stale owner information - in the case that this
- * process was the previous owner but somebody else is racing to
- * aquire the semaphore, the only way we can see ourselves as an
- * owner is with "owner_depth" of zero (so that we know to avoid
- * the stale value).
- *
- * In the non-race case (where we really _are_ the owner), there
- * is not going to be any question about what owner_depth is.
- *
- * In the race case, the race winner will not even get here, because
- * it will have successfully gotten the semaphore with the locked
- * decrement operation.
- *
- * Basically, we have two values, and we cannot guarantee that either
- * is really up-to-date until we have aquired the semaphore. But we
- * _can_ depend on a ordering between the two values, so we can use
- * one of them to determine whether we can trust the other:
- *
- * Cases:
- *  - owner_depth == zero: ignore the semaphore owner, because it
- *    cannot possibly be us. Somebody else may be in the process
- *    of modifying it and the zero may be "stale", but it sure isn't
- *    going to say that "we" are the owner anyway, so who cares?
- *  - owner_depth is non-zero. That means that even if somebody
- *    else wrote the non-zero count value, the write ordering requriement
- *    means that they will have written themselves as the owner, so
- *    if we now see ourselves as an owner we can trust it to be true.
- */
-static inline int waking_non_zero(struct semaphore *sem, struct task_struct *tsk)
-{
-	unsigned long flags;
-	unsigned long owner_depth = sem->owner_depth;
-	int ret = 0;
-
-	spin_lock_irqsave(&semaphore_wake_lock, flags);
-	if (sem->waking > 0 || (owner_depth && semaphore_owner(sem) == tsk)) {
-		sem->owner = (unsigned long) tsk;
-		sem->owner_depth++;	/* Don't use the possibly stale value */
-		sem->waking--;
-		ret = 1;
-	}
-	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
-	return ret;
-}
-
-/*
  * This is ugly, but we want the default case to fall through.
  * "down_failed" is a special asm handler that calls the C
  * routine that actually waits. See arch/i386/lib/semaphore.S
@@ -161,9 +64,7 @@
 		"lock ; "
 #endif
 		"decl 0(%0)\n\t"
-		"js 2f\n\t"
-		"movl %%esp,4(%0)\n"
-		"movl $1,8(%0)\n\t"
+		"js 2f\n"
 		"1:\n"
 		".section .text.lock,\"ax\"\n"
 		"2:\tpushl $1b\n\t"
@@ -185,8 +86,6 @@
 #endif
 		"decl 0(%1)\n\t"
 		"js 2f\n\t"
-		"movl %%esp,4(%1)\n\t"
-		"movl $1,8(%1)\n\t"
 		"xorl %0,%0\n"
 		"1:\n"
 		".section .text.lock,\"ax\"\n"
@@ -199,6 +98,28 @@
 	return result;
 }
 
+extern inline int down_trylock(struct semaphore * sem)
+{
+	int result;
+
+	__asm__ __volatile__(
+		"# atomic interruptible down operation\n\t"
+#ifdef __SMP__
+		"lock ; "
+#endif
+		"decl 0(%1)\n\t"
+		"js 2f\n\t"
+		"xorl %0,%0\n"
+		"1:\n"
+		".section .text.lock,\"ax\"\n"
+		"2:\tpushl $1b\n\t"
+		"jmp __down_failed_trylock\n"
+		".previous"
+		:"=a" (result)
+		:"c" (sem)
+		:"memory");
+	return result;
+}
 
 /*
  * Note! This is subtle. We jump to wake people up only if
@@ -210,7 +131,6 @@
 {
 	__asm__ __volatile__(
 		"# atomic up operation\n\t"
-		"decl 8(%0)\n\t"
 #ifdef __SMP__
 		"lock ; "
 #endif
diff -u --recursive --new-file v2.2.1/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.2.1/linux/include/linux/fs.h	Wed Jan 20 23:14:06 1999
+++ linux/include/linux/fs.h	Mon Feb 22 14:50:24 1999
@@ -150,6 +150,7 @@
 #define BLKFRAGET  _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
 #define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
 #define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
+#define BLKSSZGET  _IO(0x12,104)/* get block device sector size (reserved for) */
 
 #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
 #define FIBMAP	   _IO(0x00,1)	/* bmap access */
diff -u --recursive --new-file v2.2.1/linux/include/linux/lockd/lockd.h linux/include/linux/lockd/lockd.h
--- v2.2.1/linux/include/linux/lockd/lockd.h	Fri Jul 31 17:10:16 1998
+++ linux/include/linux/lockd/lockd.h	Mon Feb 22 14:50:56 1999
@@ -145,7 +145,7 @@
  * Server-side lock handling
  */
 u32		  nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
-					struct nlm_lock *, int, u32);
+					struct nlm_lock *, int, struct nlm_cookie *);
 u32		  nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
 u32		  nlmsvc_testlock(struct nlm_file *, struct nlm_lock *,
 					struct nlm_lock *);
diff -u --recursive --new-file v2.2.1/linux/include/linux/lockd/xdr.h linux/include/linux/lockd/xdr.h
--- v2.2.1/linux/include/linux/lockd/xdr.h	Fri Jul 31 17:10:16 1998
+++ linux/include/linux/lockd/xdr.h	Mon Feb 22 14:50:53 1999
@@ -25,10 +25,21 @@
 };
 
 /*
+ *	NLM cookies. Technically they can be 1K, Nobody uses over 8 bytes
+ *	however.
+ */
+ 
+struct nlm_cookie
+{
+	unsigned char data[8];
+	unsigned int len;
+};
+
+/*
  * Generic lockd arguments for all but sm_notify
  */
 struct nlm_args {
-	u32			cookie;
+	struct nlm_cookie	cookie;
 	struct nlm_lock		lock;
 	u32			block;
 	u32			reclaim;
@@ -42,7 +53,7 @@
  * Generic lockd result
  */
 struct nlm_res {
-	u32			cookie;
+	struct nlm_cookie	cookie;
 	u32			status;
 	struct nlm_lock		lock;
 };
diff -u --recursive --new-file v2.2.1/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.2.1/linux/include/linux/sched.h	Tue Jan 19 11:32:53 1999
+++ linux/include/linux/sched.h	Mon Feb 22 14:50:25 1999
@@ -174,6 +174,8 @@
 	unsigned long rss, total_vm, locked_vm;
 	unsigned long def_flags;
 	unsigned long cpu_vm_mask;
+	unsigned long swap_cnt;	/* number of pages to swap on next pass */
+	unsigned long swap_address;
 	/*
 	 * This is an architecture-specific pointer: the portable
 	 * part of Linux does not know about any segments.
@@ -191,7 +193,7 @@
 		0, 0, 0, 				\
 		0, 0, 0, 0,				\
 		0, 0, 0,				\
-		0, 0, NULL }
+		0, 0, 0, 0, NULL }
 
 struct signal_struct {
 	atomic_t		count;
@@ -276,8 +278,6 @@
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
 	int swappable:1;
-	unsigned long swap_address;
-	unsigned long swap_cnt;		/* number of pages to swap on next pass */
 /* process credentials */
 	uid_t uid,euid,suid,fsuid;
 	gid_t gid,egid,sgid,fsgid;
@@ -361,7 +361,7 @@
 /* utime */	{0,0,0,0},0, \
 /* per CPU times */ {0, }, {0, }, \
 /* flt */	0,0,0,0,0,0, \
-/* swp */	0,0,0, \
+/* swp */	0, \
 /* process credentials */					\
 /* uid etc */	0,0,0,0,0,0,0,0,				\
 /* suppl grps*/ 0, {0,},					\
diff -u --recursive --new-file v2.2.1/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h
--- v2.2.1/linux/include/linux/smb_fs.h	Thu Aug 27 19:56:30 1998
+++ linux/include/linux/smb_fs.h	Mon Feb 22 14:51:55 1999
@@ -14,7 +14,7 @@
 /*
  * ioctl commands
  */
-#define	SMB_IOC_GETMOUNTUID		_IOR('u', 1, uid_t)
+#define	SMB_IOC_GETMOUNTUID		_IOR('u', 1, __kernel_uid_t)
 #define SMB_IOC_NEWCONN                 _IOW('u', 2, struct smb_conn_opt)
 
 #ifdef __KERNEL__
diff -u --recursive --new-file v2.2.1/linux/include/linux/videodev.h linux/include/linux/videodev.h
--- v2.2.1/linux/include/linux/videodev.h	Mon Jan 25 17:44:34 1999
+++ linux/include/linux/videodev.h	Thu Feb 18 19:15:41 1999
@@ -273,6 +273,8 @@
 #define VID_HARDWARE_PLANB	16	/* PowerMac motherboard video-in */
 #define VID_HARDWARE_BROADWAY	17	/* Broadway project */
 #define VID_HARDWARE_GEMTEK	18
+#define VID_HARDWARE_TYPHOON	19
+#define VID_HARDWARE_VINO	20	/* Reserved for SGI Indy Vino */
 
 /*
  *	Initialiser list
diff -u --recursive --new-file v2.2.1/linux/include/net/sock.h linux/include/net/sock.h
--- v2.2.1/linux/include/net/sock.h	Wed Jan 20 23:14:06 1999
+++ linux/include/net/sock.h	Mon Feb 22 14:51:26 1999
@@ -453,8 +453,7 @@
 
 #ifdef CONFIG_FILTER
 	/* Socket Filtering Instructions */
-	int			filter;
-	struct sock_filter      *filter_data;
+	struct sk_filter      	*filter;
 #endif /* CONFIG_FILTER */
 
 	/* This is where all the private (optional) areas that don't
@@ -790,11 +789,11 @@
  * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller
  * than pkt_len we keep whole skb->data.
  */
-extern __inline__ int sk_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
+extern __inline__ int sk_filter(struct sk_buff *skb, struct sk_filter *filter)
 {
 	int pkt_len;
 
-        pkt_len = sk_run_filter(skb->data, skb->len, filter, flen);
+        pkt_len = sk_run_filter(skb, filter->insns, filter->len);
         if(!pkt_len)
                 return 1;	/* Toss Packet */
         else
@@ -802,6 +801,23 @@
 
 	return 0;
 }
+
+extern __inline__ void sk_filter_release(struct sock *sk, struct sk_filter *fp)
+{
+	unsigned int size = sk_filter_len(fp);
+
+	atomic_sub(size, &sk->omem_alloc);
+
+	if (atomic_dec_and_test(&fp->refcnt))
+		kfree_s(fp, size);
+}
+
+extern __inline__ void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
+{
+	atomic_inc(&fp->refcnt);
+	atomic_add(sk_filter_len(fp), &sk->omem_alloc);
+}
+
 #endif /* CONFIG_FILTER */
 
 /*
@@ -837,11 +853,8 @@
                 return -ENOMEM;
 
 #ifdef CONFIG_FILTER
-	if (sk->filter)
-	{
-		if (sk_filter(skb, sk->filter_data, sk->filter))
-			return -EPERM;	/* Toss packet */
-	}
+	if (sk->filter && sk_filter(skb, sk->filter))
+		return -EPERM;	/* Toss packet */
 #endif /* CONFIG_FILTER */
 
 	skb_set_owner_r(skb, sk);
diff -u --recursive --new-file v2.2.1/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.2.1/linux/include/net/tcp.h	Tue Jan 19 11:32:53 1999
+++ linux/include/net/tcp.h	Mon Feb 22 14:51:31 1999
@@ -912,7 +912,7 @@
  * can generate.
  */
 extern __inline__ void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
-					     int offer_wscale, int wscale, __u32 tstamp)
+					     int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent)
 {
 	/* We always get an MSS option.
 	 * The option bytes which will be seen in normal data
@@ -936,7 +936,7 @@
 			*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
 						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
 		*ptr++ = htonl(tstamp);		/* TSVAL */
-		*ptr++ = __constant_htonl(0);	/* TSECR */
+		*ptr++ = htonl(ts_recent);	/* TSECR */
 	} else if(sack)
 		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
 					  (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
diff -u --recursive --new-file v2.2.1/linux/init/main.c linux/init/main.c
--- v2.2.1/linux/init/main.c	Wed Jan 20 23:14:07 1999
+++ linux/init/main.c	Fri Feb  5 09:29:35 1999
@@ -64,6 +64,7 @@
 static int init(void *);
 extern int bdflush(void *);
 extern int kswapd(void *);
+extern int kpiod(void *);
 extern void kswapd_setup(void);
 
 extern void init_IRQ(void);
@@ -1271,6 +1272,7 @@
 	kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	/* Start the background pageout daemon. */
 	kswapd_setup();
+	kernel_thread(kpiod, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 
 #if CONFIG_AP1000
diff -u --recursive --new-file v2.2.1/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.2.1/linux/kernel/ksyms.c	Wed Jan 20 23:14:07 1999
+++ linux/kernel/ksyms.c	Thu Feb 18 10:44:10 1999
@@ -37,6 +37,7 @@
 #include <linux/file.h>
 #include <linux/console.h>
 #include <linux/poll.h>
+#include <linux/mm.h>
 
 #if defined(CONFIG_PROC_FS)
 #include <linux/proc_fs.h>
@@ -60,7 +61,7 @@
 extern void free_dma(unsigned int dmanr);
 extern spinlock_t dma_spin_lock;
 
-#ifdef MODVERSIONS
+#ifdef CONFIG_MODVERSIONS
 const struct module_symbol __export_Using_Versions
 __attribute__((section("__ksymtab"))) = {
 	1 /* Version version */, "Using_Versions"
@@ -105,6 +106,8 @@
 EXPORT_SYMBOL(high_memory);
 EXPORT_SYMBOL(update_vm_cache);
 EXPORT_SYMBOL(vmtruncate);
+EXPORT_SYMBOL(find_vma);
+EXPORT_SYMBOL(get_unmapped_area);
 
 /* filesystem internal functions */
 EXPORT_SYMBOL(in_group_p);
@@ -319,6 +322,8 @@
 EXPORT_SYMBOL(sprintf);
 EXPORT_SYMBOL(vsprintf);
 EXPORT_SYMBOL(kdevname);
+EXPORT_SYMBOL(bdevname);
+EXPORT_SYMBOL(cdevname);
 EXPORT_SYMBOL(simple_strtoul);
 EXPORT_SYMBOL(system_utsname);	/* UTS data */
 EXPORT_SYMBOL(uts_sem);		/* UTS semaphore */
@@ -367,6 +372,7 @@
 EXPORT_SYMBOL(event);
 EXPORT_SYMBOL(__down);
 EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__down_trylock);
 EXPORT_SYMBOL(__up);
 EXPORT_SYMBOL(brw_page);
 
diff -u --recursive --new-file v2.2.1/linux/kernel/sched.c linux/kernel/sched.c
--- v2.2.1/linux/kernel/sched.c	Wed Jan 20 23:14:07 1999
+++ linux/kernel/sched.c	Thu Feb 18 23:56:05 1999
@@ -36,6 +36,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
+#include <asm/semaphore-helper.h>
 
 #include <linux/timex.h>
 
@@ -463,8 +464,17 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&timerlist_lock, flags);
+	if (timer->prev)
+		goto bug;
 	internal_add_timer(timer);
+out:
 	spin_unlock_irqrestore(&timerlist_lock, flags);
+	return;
+
+bug:
+	printk("bug: kernel timer added twice at %p.\n",
+			__builtin_return_address(0));
+	goto out;
 }
 
 static inline int detach_timer(struct timer_list *timer)
@@ -639,6 +649,8 @@
 	struct task_struct * prev, * next;
 	int this_cpu;
 
+	run_task_queue(&tq_scheduler);
+
 	prev = current;
 	this_cpu = prev->processor;
 	/*
@@ -654,7 +666,6 @@
 	/* Do "administrative" work here while we don't hold any locks */
 	if (bh_active & bh_mask)
 		do_bottom_half();
-	run_task_queue(&tq_scheduler);
 
 	spin_lock(&scheduler_lock);
 	spin_lock_irq(&runqueue_lock);
@@ -680,8 +691,18 @@
 
 	sched_data->prevstate = prev->state;
 
+/* this is the scheduler proper: */
 	{
 		struct task_struct * p = init_task.next_run;
+		int c = -1000;
+
+		/* Default process to select.. */
+		next = idle_task;
+		if (prev->state == TASK_RUNNING) {
+			c = goodness(prev, prev, this_cpu);
+			next = prev;
+		}
+
 		/*
 		 * This is subtle.
 		 * Note how we can enable interrupts here, even
@@ -693,36 +714,27 @@
 		 * the scheduler lock
 		 */
 		spin_unlock_irq(&runqueue_lock);
-#ifdef __SMP__
-		prev->has_cpu = 0;
-#endif
-	
 /*
  * Note! there may appear new tasks on the run-queue during this, as
  * interrupts are enabled. However, they will be put on front of the
  * list, so our list starting at "p" is essentially fixed.
  */
-/* this is the scheduler proper: */
-		{
-			int c = -1000;
-			next = idle_task;
-			while (p != &init_task) {
-				if (can_schedule(p)) {
-					int weight = goodness(p, prev, this_cpu);
-					if (weight > c)
-						c = weight, next = p;
-				}
-				p = p->next_run;
+		while (p != &init_task) {
+			if (can_schedule(p)) {
+				int weight = goodness(p, prev, this_cpu);
+				if (weight > c)
+					c = weight, next = p;
 			}
+			p = p->next_run;
+		}
 
-			/* Do we need to re-calculate counters? */
-			if (!c) {
-				struct task_struct *p;
-				read_lock(&tasklist_lock);
-				for_each_task(p)
-					p->counter = (p->counter >> 1) + p->priority;
-				read_unlock(&tasklist_lock);
-			}
+		/* Do we need to re-calculate counters? */
+		if (!c) {
+			struct task_struct *p;
+			read_lock(&tasklist_lock);
+			for_each_task(p)
+				p->counter = (p->counter >> 1) + p->priority;
+			read_unlock(&tasklist_lock);
 		}
 	}
 
@@ -751,10 +763,8 @@
 	 * thus we have to lock the previous process from getting
 	 * rescheduled during switch_to().
 	 */
-	prev->has_cpu = 1;
-
- 	next->has_cpu = 1;
  	next->processor = this_cpu;
+ 	next->has_cpu = 1;
 	spin_unlock(&scheduler_lock);
 #endif /* __SMP__ */
  	if (prev != next) {
@@ -863,30 +873,28 @@
 	struct task_struct *tsk = current;	\
 	struct wait_queue wait = { tsk, NULL };
 
-#define DOWN_HEAD(task_state)						 \
-									 \
-									 \
-	tsk->state = (task_state);					 \
-	add_wait_queue(&sem->wait, &wait);				 \
-									 \
-	/*								 \
-	 * Ok, we're set up.  sem->count is known to be less than zero	 \
-	 * so we must wait.						 \
-	 *								 \
-	 * We can let go the lock for purposes of waiting.		 \
-	 * We re-acquire it after awaking so as to protect		 \
-	 * all semaphore operations.					 \
-	 *								 \
-	 * If "up()" is called before we call waking_non_zero() then	 \
-	 * we will catch it right away.  If it is called later then	 \
-	 * we will have to go through a wakeup cycle to catch it.	 \
-	 *								 \
-	 * Multiple waiters contend for the semaphore lock to see	 \
-	 * who gets to gate through and who has to wait some more.	 \
-	 */								 \
-	for (;;) {							 \
-		if (waking_non_zero(sem, tsk))	/* are we waking up?  */ \
-			break;			/* yes, exit loop */
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	tsk->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
 
 #define DOWN_TAIL(task_state)			\
 		tsk->state = (task_state);	\
@@ -898,6 +906,8 @@
 {
 	DOWN_VAR
 	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
 	schedule();
 	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
 }
@@ -907,15 +917,23 @@
 	DOWN_VAR
 	int ret = 0;
 	DOWN_HEAD(TASK_INTERRUPTIBLE)
-	if (signal_pending(tsk))
+
+	ret = waking_non_zero_interruptible(sem, tsk);
+	if (ret)
 	{
-		ret = -EINTR;			/* interrupted */
-		atomic_inc(&sem->count);	/* give up on down operation */
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
 		break;
 	}
 	schedule();
 	DOWN_TAIL(TASK_INTERRUPTIBLE)
 	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
 }
 
 #define	SLEEP_ON_VAR				\
diff -u --recursive --new-file v2.2.1/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.2.1/linux/kernel/sysctl.c	Wed Jan 13 15:00:44 1999
+++ linux/kernel/sysctl.c	Sat Feb  6 12:22:24 1999
@@ -557,14 +557,19 @@
 				continue;
 			}
 			unregister_proc_table(table->child, de);
+
+			/* Don't unregister directories which still have entries.. */
+			if (de->subdir)
+				continue;
 		}
-		/* Don't unregister proc directories which still have
-		   entries... */
-		if (!((de->mode & S_IFDIR) && de->subdir)) {
-			proc_unregister(root, de->low_ino);
-			table->de = NULL;
-			kfree(de);
-		} 
+
+		/* Don't unregoster proc entries that are still being used.. */
+		if (de->count)
+			continue;
+
+		proc_unregister(root, de->low_ino);
+		table->de = NULL;
+		kfree(de);
 	}
 }
 
diff -u --recursive --new-file v2.2.1/linux/mm/filemap.c linux/mm/filemap.c
--- v2.2.1/linux/mm/filemap.c	Mon Jan 25 17:44:34 1999
+++ linux/mm/filemap.c	Mon Feb  8 15:25:49 1999
@@ -19,6 +19,7 @@
 #include <linux/blkdev.h>
 #include <linux/file.h>
 #include <linux/swapctl.h>
+#include <linux/slab.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -39,6 +40,26 @@
 
 #define release_page(page) __free_page((page))
 
+/* 
+ * Define a request structure for outstanding page write requests
+ * to the background page io daemon
+ */
+
+struct pio_request 
+{
+	struct pio_request *	next;
+	struct file *		file;
+	unsigned long		offset;
+	unsigned long		page;
+};
+static struct pio_request *pio_first = NULL, **pio_last = &pio_first;
+static kmem_cache_t *pio_request_cache;
+static struct wait_queue *pio_wait = NULL;
+
+static inline void 
+make_pio_request(struct file *, unsigned long, unsigned long);
+
+
 /*
  * 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
@@ -1079,8 +1100,9 @@
 }
 
 static int filemap_write_page(struct vm_area_struct * vma,
-	unsigned long offset,
-	unsigned long page)
+			      unsigned long offset,
+			      unsigned long page,
+			      int wait)
 {
 	int result;
 	struct file * file;
@@ -1098,6 +1120,17 @@
 	 * and file could be released ... increment the count to be safe.
 	 */
 	file->f_count++;
+
+	/* 
+	 * If this is a swapping operation rather than msync(), then
+	 * leave the actual IO, and the restoration of the file count,
+	 * to the kpiod thread.  Just queue the request for now.
+	 */
+	if (!wait) {
+		make_pio_request(file, offset, page);
+		return 0;
+	}
+	
 	down(&inode->i_sem);
 	result = do_write_page(inode, file, (const char *) page, offset);
 	up(&inode->i_sem);
@@ -1113,7 +1146,7 @@
  */
 int filemap_swapout(struct vm_area_struct * vma, struct page * page)
 {
-	return filemap_write_page(vma, page->offset, page_address(page));
+	return filemap_write_page(vma, page->offset, page_address(page), 0);
 }
 
 static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
@@ -1150,7 +1183,7 @@
 			return 0;
 		}
 	}
-	error = filemap_write_page(vma, address - vma->vm_start + vma->vm_offset, page);
+	error = filemap_write_page(vma, address - vma->vm_start + vma->vm_offset, page, 1);
 	free_page(page);
 	return error;
 }
@@ -1568,4 +1601,128 @@
 	clear_bit(PG_locked, &page->flags);
 	wake_up(&page->wait);
 	__free_page(page);
+}
+
+
+/* Add request for page IO to the queue */
+
+static inline void put_pio_request(struct pio_request *p)
+{
+	*pio_last = p;
+	p->next = NULL;
+	pio_last = &p->next;
+}
+
+/* Take the first page IO request off the queue */
+
+static inline struct pio_request * get_pio_request(void)
+{
+	struct pio_request * p = pio_first;
+	pio_first = p->next;
+	if (!pio_first)
+		pio_last = &pio_first;
+	return p;
+}
+
+/* Make a new page IO request and queue it to the kpiod thread */
+
+static inline void make_pio_request(struct file *file,
+				    unsigned long offset,
+				    unsigned long page)
+{
+	struct pio_request *p;
+
+	atomic_inc(&mem_map[MAP_NR(page)].count);
+
+	/* 
+	 * We need to allocate without causing any recursive IO in the
+	 * current thread's context.  We might currently be swapping out
+	 * as a result of an allocation made while holding a critical
+	 * filesystem lock.  To avoid deadlock, we *MUST* not reenter
+	 * the filesystem in this thread.
+	 *
+	 * We can wait for kswapd to free memory, or we can try to free
+	 * pages without actually performing further IO, without fear of
+	 * deadlock.  --sct
+	 */
+
+	while ((p = kmem_cache_alloc(pio_request_cache, GFP_BUFFER)) == NULL) {
+		if (try_to_free_pages(__GFP_WAIT))
+			continue;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(HZ/10);
+	}
+	
+	p->file   = file;
+	p->offset = offset;
+	p->page   = page;
+
+	put_pio_request(p);
+	wake_up(&pio_wait);
+}
+
+
+/*
+ * This is the only thread which is allowed to write out filemap pages
+ * while swapping.
+ * 
+ * To avoid deadlock, it is important that we never reenter this thread.
+ * Although recursive memory allocations within this thread may result
+ * in more page swapping, that swapping will always be done by queuing
+ * another IO request to the same thread: we will never actually start
+ * that IO request until we have finished with the current one, and so
+ * we will not deadlock.  
+ */
+
+int kpiod(void * unused)
+{
+	struct task_struct *tsk = current;
+	struct wait_queue wait = { tsk, };
+	struct inode * inode;
+	struct dentry * dentry;
+	struct pio_request * p;
+	
+	tsk->session = 1;
+	tsk->pgrp = 1;
+	strcpy(tsk->comm, "kpiod");
+	sigfillset(&tsk->blocked);
+	init_waitqueue(&pio_wait);
+	/*
+	 * Mark this task as a memory allocator - we don't want to get caught
+	 * up in the regular mm freeing frenzy if we have to allocate memory
+	 * in order to write stuff out.
+	 */
+	tsk->flags |= PF_MEMALLOC;
+
+	lock_kernel();
+	
+	pio_request_cache = kmem_cache_create("pio_request", 
+					      sizeof(struct pio_request),
+					      0, SLAB_HWCACHE_ALIGN, 
+					      NULL, NULL);
+	if (!pio_request_cache)
+		panic ("Could not create pio_request slab cache");
+
+	while (1) {
+		tsk->state = TASK_INTERRUPTIBLE;
+		add_wait_queue(&pio_wait, &wait);
+		if (!pio_first)
+			schedule();
+		remove_wait_queue(&pio_wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		while (pio_first) {
+			p = get_pio_request();
+			dentry = p->file->f_dentry;
+			inode = dentry->d_inode;
+			
+			down(&inode->i_sem);
+			do_write_page(inode, p->file,
+				      (const char *) p->page, p->offset);
+			up(&inode->i_sem);
+			fput(p->file);
+			free_page(p->page);
+			kmem_cache_free(pio_request_cache, p);
+		}
+	}
 }
diff -u --recursive --new-file v2.2.1/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.2.1/linux/mm/vmscan.c	Mon Jan 25 17:44:34 1999
+++ linux/mm/vmscan.c	Fri Feb  5 09:29:36 1999
@@ -202,7 +202,7 @@
 
 	do {
 		int result;
-		tsk->swap_address = address + PAGE_SIZE;
+		tsk->mm->swap_address = address + PAGE_SIZE;
 		result = try_to_swap_out(tsk, vma, address, pte, gfp_mask);
 		if (result)
 			return result;
@@ -274,7 +274,7 @@
 	/*
 	 * Go through process' page directory.
 	 */
-	address = p->swap_address;
+	address = p->mm->swap_address;
 
 	/*
 	 * Find the proper vm-area
@@ -296,8 +296,8 @@
 	}
 
 	/* We didn't find anything for the process */
-	p->swap_cnt = 0;
-	p->swap_address = 0;
+	p->mm->swap_cnt = 0;
+	p->mm->swap_address = 0;
 	return 0;
 }
 
@@ -345,9 +345,9 @@
 				continue;
 			/* Refresh swap_cnt? */
 			if (assign)
-				p->swap_cnt = p->mm->rss;
-			if (p->swap_cnt > max_cnt) {
-				max_cnt = p->swap_cnt;
+				p->mm->swap_cnt = p->mm->rss;
+			if (p->mm->swap_cnt > max_cnt) {
+				max_cnt = p->mm->swap_cnt;
 				pbest = p;
 			}
 		}
diff -u --recursive --new-file v2.2.1/linux/net/Makefile linux/net/Makefile
--- v2.2.1/linux/net/Makefile	Tue Dec 22 14:16:59 1998
+++ linux/net/Makefile	Sat Feb  6 12:46:21 1999
@@ -127,6 +127,8 @@
 
 ifeq ($(CONFIG_IRDA),y)
 SUB_DIRS += irda
+# There might be some irda features that are compiled as modules
+MOD_SUB_DIRS += irda
 else
   ifeq ($(CONFIG_IRDA),m)
   MOD_SUB_DIRS += irda
diff -u --recursive --new-file v2.2.1/linux/net/core/filter.c linux/net/core/filter.c
--- v2.2.1/linux/net/core/filter.c	Mon Jan 12 15:28:25 1998
+++ linux/net/core/filter.c	Thu Feb 18 11:59:28 1999
@@ -11,6 +11,8 @@
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
+ *
+ * Andi Kleen - Fix a few bad bugs and races.
  */
 
 #include <linux/config.h>
@@ -36,6 +38,22 @@
 #include <asm/uaccess.h>
 #include <linux/filter.h>
 
+/* No hurry in this branch */
+
+static u8 *load_pointer(struct sk_buff *skb, int k)
+{
+	u8 *ptr = NULL;
+
+	if (k>=SKF_NET_OFF)
+		ptr = skb->nh.raw + k - SKF_NET_OFF;
+	else if (k>=SKF_LL_OFF)
+		ptr = skb->mac.raw + k - SKF_LL_OFF;
+
+	if (ptr<skb->head && ptr < skb->tail)
+		return ptr;
+	return NULL;
+}
+
 /*
  * Decode and apply filter instructions to the skb->data.
  * Return length to keep, 0 for none. skb is the data we are
@@ -43,15 +61,19 @@
  * len is the number of filter blocks in the array.
  */
  
-int sk_run_filter(unsigned char *data, int len, struct sock_filter *filter, int flen)
+int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
 {
+	unsigned char *data = skb->data;
+	/* len is UNSIGNED. Byte wide insns relies only on implicit
+	   type casts to prevent reading arbitrary memory locations.
+	 */
+	unsigned int len = skb->len;
 	struct sock_filter *fentry;	/* We walk down these */
 	u32 A = 0;	   		/* Accumulator */
 	u32 X = 0;   			/* Index Register */
 	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
 	int k;
 	int pc;
-	int *t;
 
 	/*
 	 * Process array of filter instructions.
@@ -60,53 +82,75 @@
 	for(pc = 0; pc < flen; pc++)
 	{
 		fentry = &filter[pc];
-		if(fentry->code & BPF_X)
-			t=&X;
-		else
-			t=&fentry->k;
 			
 		switch(fentry->code)
 		{
 			case BPF_ALU|BPF_ADD|BPF_X:
+				A += X;
+				continue;
+
 			case BPF_ALU|BPF_ADD|BPF_K:
-				A += *t;
+				A += fentry->k;
 				continue;
 
 			case BPF_ALU|BPF_SUB|BPF_X:
+				A -= X;
+				continue;
+
 			case BPF_ALU|BPF_SUB|BPF_K:
-				A -= *t;
+				A -= fentry->k;
 				continue;
 
 			case BPF_ALU|BPF_MUL|BPF_X:
+				A *= X;
+				continue;
+
 			case BPF_ALU|BPF_MUL|BPF_K:
-				A *= *t;
+				A *= X;
 				continue;
 
 			case BPF_ALU|BPF_DIV|BPF_X:
+				if(X == 0)
+					return (0);
+				A /= X;
+				continue;
+
 			case BPF_ALU|BPF_DIV|BPF_K:
-				if(*t == 0)
+				if(fentry->k == 0)
 					return (0);
-				A /= *t;
+				A /= fentry->k;
 				continue;
 
 			case BPF_ALU|BPF_AND|BPF_X:
+				A &= X;
+				continue;
+
 			case BPF_ALU|BPF_AND|BPF_K:
-				A &= *t;
+				A &= fentry->k;
 				continue;
 
 			case BPF_ALU|BPF_OR|BPF_X:
+				A |= X;
+				continue;
+
 			case BPF_ALU|BPF_OR|BPF_K:
-				A |= *t;
+				A |= fentry->k;
 				continue;
 
 			case BPF_ALU|BPF_LSH|BPF_X:
+				A <<= X;
+				continue;
+
 			case BPF_ALU|BPF_LSH|BPF_K:
-				A <<= *t;
+				A <<= fentry->k;
 				continue;
 
 			case BPF_ALU|BPF_RSH|BPF_X:
+				A >>= X;
+				continue;
+
 			case BPF_ALU|BPF_RSH|BPF_K:
-				A >>= *t;
+				A >>= fentry->k;
 				continue;
 
 			case BPF_ALU|BPF_NEG:
@@ -148,26 +192,62 @@
 			case BPF_JMP|BPF_JSET|BPF_X:
 				pc += (A & X) ? fentry->jt : fentry->jf;
 				continue;
+
 			case BPF_LD|BPF_W|BPF_ABS:
 				k = fentry->k;
-				if(k + sizeof(long) > len)
-					return (0);
-				A = ntohl(*(long*)&data[k]);
-				continue;
+load_w:
+				if(k+sizeof(u32) <= len) {
+					A = ntohl(*(u32*)&data[k]);
+					continue;
+				}
+				if (k<0) {
+					u8 *ptr;
+
+					if (k>=SKF_AD_OFF)
+						break;
+					if ((ptr = load_pointer(skb, k)) != NULL) {
+						A = ntohl(*(u32*)ptr);
+						continue;
+					}
+				}
+				return 0;
 
 			case BPF_LD|BPF_H|BPF_ABS:
 				k = fentry->k;
-				if(k + sizeof(short) > len)
-					return (0);
-				A = ntohs(*(short*)&data[k]);
-				continue;
+load_h:
+				if(k + sizeof(u16) <= len) {
+					A = ntohs(*(u16*)&data[k]);
+					continue;
+				}
+				if (k<0) {
+					u8 *ptr;
+
+					if (k>=SKF_AD_OFF)
+						break;
+					if ((ptr = load_pointer(skb, k)) != NULL) {
+						A = ntohs(*(u16*)ptr);
+						continue;
+					}
+				}
+				return 0;
 
 			case BPF_LD|BPF_B|BPF_ABS:
 				k = fentry->k;
-				if(k >= len)
-					return (0);
-				A = data[k];
-				continue;
+load_b:
+				if(k < len) {
+					A = data[k];
+					continue;
+				}
+				if (k<0) {
+					u8 *ptr;
+
+					if (k>=SKF_AD_OFF)
+						break;
+					if ((ptr = load_pointer(skb, k)) != NULL) {
+						A = *ptr;
+						continue;
+					}
+				}
 
 			case BPF_LD|BPF_W|BPF_LEN:
 				A = len;
@@ -177,35 +257,23 @@
 				X = len;
 				continue;
 
-                      case BPF_LD|BPF_W|BPF_IND:
+			case BPF_LD|BPF_W|BPF_IND:
 				k = X + fentry->k;
-				if(k + sizeof(u32) > len)
-					return (0);
-                                A = ntohl(*(u32 *)&data[k]);
-				continue;
+				goto load_w;
 
                        case BPF_LD|BPF_H|BPF_IND:
 				k = X + fentry->k;
-				if(k + sizeof(u16) > len)
-					return (0);
-				A = ntohs(*(u16*)&data[k]);
-				continue;
+				goto load_h;
 
                        case BPF_LD|BPF_B|BPF_IND:
 				k = X + fentry->k;
-				if(k >= len)
-					return (0);
-				A = data[k];
-				continue;
+				goto load_b;
 
 			case BPF_LDX|BPF_B|BPF_MSH:
-				/*
-				 *	Hack for BPF to handle TOS etc
-				 */
 				k = fentry->k;
 				if(k >= len)
 					return (0);
-				X = (data[fentry->k] & 0xf) << 2;
+				X = (data[k] & 0xf) << 2;
 				continue;
 
 			case BPF_LD|BPF_IMM:
@@ -216,7 +284,7 @@
 				X = fentry->k;
 				continue;
 
-                       case BPF_LD|BPF_MEM:
+			case BPF_LD|BPF_MEM:
 				A = mem[fentry->k];
 				continue;
 
@@ -246,15 +314,29 @@
 				mem[fentry->k] = X;
 				continue;
 
-
-
 			default:
 				/* Invalid instruction counts as RET */
 				return (0);
 		}
+
+		/* Handle ancillary data, which are impossible
+		   (or very difficult) to get parsing packet contents.
+		 */
+		switch (k-SKF_AD_OFF) {
+		case SKF_AD_PROTOCOL:
+			A = htons(skb->protocol);
+			continue;
+		case SKF_AD_PKTTYPE:
+			A = skb->pkt_type;
+			continue;
+		case SKF_AD_IFINDEX:
+			A = skb->dev->ifindex;
+			continue;
+		default:
+			return 0;
+		}
 	}
 
-	printk(KERN_ERR "Filter ruleset ran off the end.\n");
 	return (0);
 }
 
@@ -279,13 +361,17 @@
                  
                 ftest = &filter[pc];
 		if(BPF_CLASS(ftest->code) == BPF_JMP)
-		{	
+		{
 			/*
 			 *	But they mustn't jump off the end.
 			 */
 			if(BPF_OP(ftest->code) == BPF_JA)
 			{
-				if(pc + ftest->k + 1>= (unsigned)flen)
+				/* Note, the large ftest->k might cause
+				   loops. Compare this with conditional
+				   jumps below, where offsets are limited. --ANK (981016)
+				 */
+				if (ftest->k >= (unsigned)(flen-pc-1))
 					return (-EINVAL);
 			}
                         else
@@ -302,17 +388,18 @@
                  *	Check that memory operations use valid addresses.
                  */
                  
-                if(ftest->k <0 || ftest->k >= BPF_MEMWORDS)
+                if (ftest->k >= BPF_MEMWORDS)
                 {
                 	/*
                 	 *	But it might not be a memory operation...
                 	 */
-                	 
-                	if (BPF_CLASS(ftest->code) == BPF_ST)
+			switch (ftest->code) {
+			case BPF_ST:	
+			case BPF_STX:	
+			case BPF_LD|BPF_MEM:	
+			case BPF_LDX|BPF_MEM:	
                 		return -EINVAL;
-			if((BPF_CLASS(ftest->code) == BPF_LD) && 
-				(BPF_MODE(ftest->code) == BPF_MEM))
-	                        	return (-EINVAL);
+			}
 		}
         }
 
@@ -332,34 +419,35 @@
 
 int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
 {
-	struct sock_filter *fp, *old_filter; 
-	int fsize = sizeof(struct sock_filter) * fprog->len;
+	struct sk_filter *fp; 
+	unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
 	int err;
 
 	/* Make sure new filter is there and in the right amounts. */
-        if(fprog->filter == NULL || fprog->len == 0 || fsize > BPF_MAXINSNS)
+        if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS)
                 return (-EINVAL);
 
-	if((err = sk_chk_filter(fprog->filter, fprog->len))==0)
-	{
-		/* If existing filter, remove it first */
-		if(sk->filter)
-		{
-			old_filter = sk->filter_data;
-			kfree_s(old_filter, (sizeof(old_filter) * sk->filter));
-			sk->filter_data = NULL;
-		}
-
-		fp = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
-		if(fp == NULL)
-			return (-ENOMEM);
+	fp = (struct sk_filter *)sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
+	if(fp == NULL)
+		return (-ENOMEM);
+
+	if (copy_from_user(fp->insns, fprog->filter, fsize)) {
+		sock_kfree_s(sk, fp, fsize+sizeof(*fp)); 
+		return -EFAULT;
+	}
 
-		memset(fp,0,sizeof(*fp));
-		memcpy(fp, fprog->filter, fsize);	/* Copy instructions */
+	atomic_set(&fp->refcnt, 1);
+	fp->len = fprog->len;
 
-		sk->filter = fprog->len;	/* Number of filter blocks */
-		sk->filter_data = fp;		/* Filter instructions */
+	if ((err = sk_chk_filter(fp->insns, fp->len))==0) {
+		struct sk_filter *old_fp = sk->filter;
+		sk->filter = fp;
+		wmb();
+		fp = old_fp;
 	}
+
+	if (fp)
+		sk_filter_release(sk, fp);
 
 	return (err);
 }
diff -u --recursive --new-file v2.2.1/linux/net/core/skbuff.c linux/net/core/skbuff.c
--- v2.2.1/linux/net/core/skbuff.c	Thu Sep 17 17:53:39 1998
+++ linux/net/core/skbuff.c	Sat Feb  6 12:46:21 1999
@@ -304,6 +304,9 @@
 	n->stamp=skb->stamp;
 	n->destructor = NULL;
 	n->security=skb->security;
+#ifdef CONFIG_IP_FIREWALL
+        n->fwmark = skb->fwmark;
+#endif
 	return n;
 }
 
@@ -350,6 +353,9 @@
 	n->stamp=skb->stamp;
 	n->destructor = NULL;
 	n->security=skb->security;
+#ifdef CONFIG_IP_FIREWALL
+        n->fwmark = skb->fwmark;
+#endif
 
 	return n;
 }
diff -u --recursive --new-file v2.2.1/linux/net/core/sock.c linux/net/core/sock.c
--- v2.2.1/linux/net/core/sock.c	Sun Nov  8 14:03:13 1998
+++ linux/net/core/sock.c	Thu Feb 18 11:59:28 1999
@@ -155,10 +155,6 @@
 	int err;
 	struct linger ling;
 	int ret = 0;
-
-#ifdef CONFIG_FILTER
-	struct sock_fprog fprog;
-#endif
 	
 	/*
 	 *	Options without arguments
@@ -256,12 +252,13 @@
 
 		case SO_PRIORITY:
 			if (val >= 0 && val <= 7) 
+			{
+				if(val==7 && !capable(CAP_NET_ADMIN))
+					return -EPERM;
 				sk->priority = val;
-			else
-				return(-EINVAL);
+			}			
 			break;
 
-
 		case SO_LINGER:
 			if(optlen<sizeof(ling))
 				return -EINVAL;	/* 1003.1g */
@@ -310,10 +307,12 @@
 				if (optlen > IFNAMSIZ) 
 					optlen = IFNAMSIZ; 
 				if (copy_from_user(devname, optval, optlen))
-				    return -EFAULT;
-				    
+					return -EFAULT;
+
 				/* Remove any cached route for this socket. */
+				lock_sock(sk);
 				dst_release(xchg(&sk->dst_cache, NULL));
+				release_sock(sk);
 
 				if (devname[0] == '\0') {
 					sk->bound_dev_if = 0;
@@ -331,30 +330,32 @@
 
 #ifdef CONFIG_FILTER
 		case SO_ATTACH_FILTER:
-			if(optlen < sizeof(struct sock_fprog))
-				return -EINVAL;
+			ret = -EINVAL;
+			if (optlen == sizeof(struct sock_fprog)) {
+				struct sock_fprog fprog;
 
-			if(copy_from_user(&fprog, optval, sizeof(fprog)))
-			{
 				ret = -EFAULT;
-				break;
-			}
+				if (copy_from_user(&fprog, optval, sizeof(fprog)))
+					break;
 
-			ret = sk_attach_filter(&fprog, sk);
+				ret = sk_attach_filter(&fprog, sk);
+			}
 			break;
 
 		case SO_DETACH_FILTER:
-                        if(sk->filter)
-			{
-				fprog.filter = sk->filter_data;
-				kfree_s(fprog.filter, (sizeof(fprog.filter) * sk->filter));
-				sk->filter_data = NULL;
-				sk->filter = 0;
+                        if(sk->filter) {
+				struct sk_filter *filter;
+
+				filter = sk->filter;
+
+				sk->filter = NULL;
+				wmb();
+				
+				if (filter)
+					sk_filter_release(sk, filter);
 				return 0;
 			}
-			else
-				return -EINVAL;
-			break;
+			return -ENOENT;
 #endif
 		/* We implement the SO_SNDLOWAT etc to
 		   not be settable (1003.1g 5.3) */
@@ -503,6 +504,16 @@
 {
 	if (sk->destruct)
 		sk->destruct(sk);
+
+#ifdef CONFIG_FILTER
+	if (sk->filter) {
+		sk_filter_release(sk, sk->filter);
+		sk->filter = NULL;
+	}
+#endif
+
+	if (atomic_read(&sk->omem_alloc))
+		printk(KERN_DEBUG "sk_free: optmem leakage (%d bytes) detected.\n", atomic_read(&sk->omem_alloc));
 
 	kmem_cache_free(sk_cachep, sk);
 }
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.2.1/linux/net/ipv4/af_inet.c	Thu Jan  7 15:11:41 1999
+++ linux/net/ipv4/af_inet.c	Mon Feb 22 09:05:55 1999
@@ -5,7 +5,7 @@
  *
  *		PF_INET protocol family socket handler.
  *
- * Version:	$Id: af_inet.c,v 1.82 1999/01/04 20:36:44 davem Exp $
+ * Version:	$Id: af_inet.c,v 1.83 1999/02/22 13:54:18 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -828,6 +828,8 @@
 	sk->shutdown |= how;
 	if (sk->prot->shutdown)
 		sk->prot->shutdown(sk, how);
+	/* Wake up anyone sleeping in poll. */
+	sk->state_change(sk);
 	return(0);
 }
 
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
--- v2.2.1/linux/net/ipv4/fib_semantics.c	Mon Jan 25 17:44:34 1999
+++ linux/net/ipv4/fib_semantics.c	Mon Feb  8 09:26:29 1999
@@ -5,7 +5,7 @@
  *
  *		IPv4 Forwarding Information Base: semantics.
  *
- * Version:	$Id: fib_semantics.c,v 1.11 1998/10/03 09:37:12 davem Exp $
+ * Version:	$Id: fib_semantics.c,v 1.12 1999/01/26 05:33:44 davem Exp $
  *
  * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  *
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- v2.2.1/linux/net/ipv4/icmp.c	Thu Jan  7 15:11:41 1999
+++ linux/net/ipv4/icmp.c	Thu Feb 18 19:15:41 1999
@@ -402,6 +402,10 @@
 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
 		return 1;
 
+	/* No rate limit on loopback */
+	if (dst->dev && (dst->dev->flags&IFF_LOOPBACK))
+ 		return 1;
+
 	return xrlim_allow(dst, *(icmp_pointers[type].timeout));
 }
 
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/ip_masq_mfw.c linux/net/ipv4/ip_masq_mfw.c
--- v2.2.1/linux/net/ipv4/ip_masq_mfw.c	Mon Jan 25 17:44:34 1999
+++ linux/net/ipv4/ip_masq_mfw.c	Mon Feb  8 09:26:29 1999
@@ -3,7 +3,7 @@
  *
  *	Does (reverse-masq) forwarding based on skb->fwmark value
  *
- *	$Id: ip_masq_mfw.c,v 1.2 1998/12/12 02:40:42 davem Exp $
+ *	$Id: ip_masq_mfw.c,v 1.3 1999/01/26 05:33:47 davem Exp $
  *
  * Author:	Juan Jose Ciarlante   <jjciarla@raiz.uncu.edu.ar>
  *		  based on Steven Clarke's portfw
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- v2.2.1/linux/net/ipv4/ip_output.c	Wed Jan 20 23:14:07 1999
+++ linux/net/ipv4/ip_output.c	Mon Feb  8 09:26:29 1999
@@ -5,7 +5,7 @@
  *
  *		The Internet Protocol (IP) output module.
  *
- * Version:	$Id: ip_output.c,v 1.64 1999/01/04 20:05:33 davem Exp $
+ * Version:	$Id: ip_output.c,v 1.65 1999/01/21 13:37:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/proc.c linux/net/ipv4/proc.c
--- v2.2.1/linux/net/ipv4/proc.c	Sun Nov  8 14:03:14 1998
+++ linux/net/ipv4/proc.c	Mon Feb  8 09:26:29 1999
@@ -7,7 +7,7 @@
  *		PROC file system.  It is mainly used for debugging and
  *		statistics.
  *
- * Version:	$Id: proc.c,v 1.33 1998/10/21 05:44:35 davem Exp $
+ * Version:	$Id: proc.c,v 1.34 1999/02/08 11:20:34 davem Exp $
  *
  * Authors:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *		Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
@@ -184,6 +184,8 @@
 
 			for (req = sp->tp_pinfo.af_tcp.syn_wait_queue; req;
 			     i++, req = req->dl_next) {
+				if (req->sk)
+					continue;
 				pos += 128;
 				if (pos < offset) 
 					continue;
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.2.1/linux/net/ipv4/tcp.c	Tue Jan 19 11:32:53 1999
+++ linux/net/ipv4/tcp.c	Mon Feb 22 09:05:55 1999
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp.c,v 1.134 1999/01/09 08:50:09 davem Exp $
+ * Version:	$Id: tcp.c,v 1.135 1999/02/22 13:54:21 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1393,9 +1393,6 @@
 	if ((1 << sk->state) &
 	    (TCPF_ESTABLISHED|TCPF_SYN_SENT|TCPF_SYN_RECV|TCPF_CLOSE_WAIT)) {
 		lock_sock(sk);
-
-		/* Flag that the sender has shutdown. */
-		sk->shutdown |= SEND_SHUTDOWN;
 
 		/* Clear out any half completed packets.  FIN if needed. */
 		if (tcp_close_state(sk,0))
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.2.1/linux/net/ipv4/tcp_input.c	Mon Jan 25 17:44:34 1999
+++ linux/net/ipv4/tcp_input.c	Mon Feb 22 09:05:55 1999
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_input.c,v 1.153 1999/01/20 07:20:03 davem Exp $
+ * Version:	$Id: tcp_input.c,v 1.156 1999/02/22 13:54:13 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -130,11 +130,15 @@
 {
 	tp->delayed_acks++; 
 
-	/* Tiny-grams with PSH set make us ACK quickly.
-	 * Note: This also clears the "quick ack mode" bit.
+	/* Tiny-grams with PSH set artifically deflate our
+	 * ato measurement, but with a lower bound.
 	 */
-	if(th->psh && (skb->len < (tp->mss_cache >> 1)))
-		tp->ato = HZ/50;
+	if(th->psh && (skb->len < (tp->mss_cache >> 1))) {
+		/* Preserve the quickack state. */
+		if((tp->ato & 0x7fffffff) > HZ/50)
+			tp->ato = ((tp->ato & 0x80000000) |
+				   (HZ/50));
+	}
 } 
 
 /* Called to compute a smoothed rtt estimate. The data fed to this
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.2.1/linux/net/ipv4/tcp_ipv4.c	Thu Jan  7 15:11:42 1999
+++ linux/net/ipv4/tcp_ipv4.c	Thu Feb 18 11:59:28 1999
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_ipv4.c,v 1.164 1999/01/04 20:36:55 davem Exp $
+ * Version:	$Id: tcp_ipv4.c,v 1.165 1999/02/08 11:19:56 davem Exp $
  *
  *		IPv4 specific functions
  *
@@ -751,7 +751,6 @@
 	if (sk->ip_pmtudisc != IP_PMTUDISC_DONT && sk->dst_cache) {
 		if (tp->pmtu_cookie > sk->dst_cache->pmtu &&
 		    !atomic_read(&sk->sock_readers)) {
-			lock_sock(sk); 
 			tcp_sync_mss(sk, sk->dst_cache->pmtu);
 
 			/* Resend the TCP packet because it's  
@@ -760,7 +759,6 @@
 			 * discovery.
 			 */
 			tcp_simple_retransmit(sk);
-			release_sock(sk);
 		} /* else let the usual retransmit timer handle it */
 	}
 }
@@ -1325,6 +1323,10 @@
 		newsk->pair = NULL;
 		skb_queue_head_init(&newsk->back_log);
 		skb_queue_head_init(&newsk->error_queue);
+#ifdef CONFIG_FILTER
+		if (newsk->filter)
+			sk_filter_charge(newsk, newsk->filter);
+#endif
 
 		/* Now setup tcp_opt */
 		newtp = &(newsk->tp_pinfo.af_tcp);
@@ -1555,20 +1557,12 @@
 
 int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
+
 #ifdef CONFIG_FILTER
-	if (sk->filter)
-	{
-		if (sk_filter(skb, sk->filter_data, sk->filter))
-			goto discard;
-	}
+	if (sk->filter && sk_filter(skb, sk->filter))
+		goto discard;
 #endif /* CONFIG_FILTER */
 
-	/*
-	 *	socket locking is here for SMP purposes as backlog rcv
-	 *	is currently called with bh processing disabled.
-	 */
-	lock_sock(sk); 
-
 	/* 
 	 * This doesn't check if the socket has enough room for the packet.
 	 * Either process the packet _without_ queueing it and then free it,
@@ -1579,7 +1573,6 @@
 	if (sk->state == TCP_ESTABLISHED) { /* Fast path */
 		if (tcp_rcv_established(sk, skb, skb->h.th, skb->len))
 			goto reset;
-		release_sock(sk);
 		return 0; 
 	} 
 
@@ -1590,14 +1583,21 @@
 		nsk = tcp_v4_hnd_req(sk, skb);
 		if (!nsk) 
 			goto discard;
-		lock_sock(nsk);
-		release_sock(sk);
+
+		/*
+		 * Queue it on the new socket if the new socket is active,
+		 * otherwise we just shortcircuit this and continue with
+		 * the new socket..
+		 */
+		if (atomic_read(&nsk->sock_readers)) {
+			__skb_queue_tail(&nsk->back_log, skb);
+			return 0;
+		}
 		sk = nsk;
 	}
 	
 	if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len))
 		goto reset;
-	release_sock(sk); 
 	return 0;
 
 reset:
@@ -1609,7 +1609,6 @@
 	 * might be destroyed here. This current version compiles correctly,
 	 * but you have been warned.
 	 */
-	release_sock(sk);  
 	return 0;
 }
 
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.2.1/linux/net/ipv4/tcp_output.c	Wed Jan 20 23:14:07 1999
+++ linux/net/ipv4/tcp_output.c	Mon Feb 22 09:05:55 1999
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_output.c,v 1.101 1999/01/20 07:20:14 davem Exp $
+ * Version:	$Id: tcp_output.c,v 1.102 1999/02/22 13:54:26 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -30,6 +30,7 @@
  *		David S. Miller	:	Charge memory using the right skb
  *					during syn/ack processing.
  *		David S. Miller :	Output engine completely rewritten.
+ *		Andrea Arcangeli:	SYNACK carry ts_recent in tsecr.
  *
  */
 
@@ -135,7 +136,8 @@
 					      (sysctl_flags & SYSCTL_FLAG_SACK),
 					      (sysctl_flags & SYSCTL_FLAG_WSCALE),
 					      tp->rcv_wscale,
-					      TCP_SKB_CB(skb)->when);
+					      TCP_SKB_CB(skb)->when,
+		      			      tp->ts_recent);
 		} else {
 			tcp_build_and_update_options((__u32 *)(th + 1),
 						     tp, TCP_SKB_CB(skb)->when);
@@ -862,7 +864,8 @@
 	TCP_SKB_CB(skb)->when = jiffies;
 	tcp_syn_build_options((__u32 *)(th + 1), req->mss, req->tstamp_ok,
 			      req->sack_ok, req->wscale_ok, req->rcv_wscale,
-			      TCP_SKB_CB(skb)->when);
+			      TCP_SKB_CB(skb)->when,
+			      req->ts_recent);
 
 	skb->csum = 0;
 	th->doff = (tcp_header_size >> 2);
diff -u --recursive --new-file v2.2.1/linux/net/ipv4/timer.c linux/net/ipv4/timer.c
--- v2.2.1/linux/net/ipv4/timer.c	Sun Nov  8 14:03:15 1998
+++ linux/net/ipv4/timer.c	Mon Feb 22 09:05:55 1999
@@ -5,7 +5,7 @@
  *
  *		TIMER - implementation of software timers for IP.
  *
- * Version:	$Id: timer.c,v 1.14 1998/11/07 11:55:43 davem Exp $
+ * Version:	$Id: timer.c,v 1.15 1999/02/22 13:54:29 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -75,8 +75,7 @@
 	/* Only process if socket is not in use. */
 	if (atomic_read(&sk->sock_readers)) {
 		/* Try again later. */ 
-		sk->timer.expires = jiffies+HZ/20;
-		add_timer(&sk->timer);
+		mod_timer(&sk->timer, jiffies+HZ/20);
 		return;
 	}
 
diff -u --recursive --new-file v2.2.1/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.2.1/linux/net/ipv6/tcp_ipv6.c	Sun Nov  8 14:03:15 1998
+++ linux/net/ipv6/tcp_ipv6.c	Mon Feb  8 09:26:30 1999
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: tcp_ipv6.c,v 1.94 1998/11/07 11:50:33 davem Exp $
+ *	$Id: tcp_ipv6.c,v 1.95 1999/02/08 11:20:03 davem Exp $
  *
  *	Based on: 
  *	linux/net/ipv4/tcp.c
@@ -641,10 +641,8 @@
 			sk->err_soft = -dst->error;
 		} else if (tp->pmtu_cookie > dst->pmtu
 			   && !atomic_read(&sk->sock_readers)) {
-			lock_sock(sk); 
 			tcp_sync_mss(sk, dst->pmtu);
 			tcp_simple_retransmit(sk);
-			release_sock(sk);
 		} /* else let the usual retransmit timer handle it */
 		dst_release(dst);
 		return;
@@ -1210,11 +1208,6 @@
 
   	ipv6_statistics.Ip6InDelivers++;
 
-	/* XXX We need to think more about socket locking
-	 * XXX wrt. backlog queues, __release_sock(), etc.  -DaveM
-	 */
-	lock_sock(sk); 
-
 	/* 
 	 * This doesn't check if the socket has enough room for the packet.
 	 * Either process the packet _without_ queueing it and then free it,
@@ -1255,8 +1248,16 @@
 		nsk = tcp_v6_hnd_req(sk, skb);
 		if (!nsk)
 			goto discard;
-		lock_sock(nsk);
-		release_sock(sk);
+
+		/*
+		 * Queue it on the new socket if the new socket is active,
+		 * otherwise we just shortcircuit this and continue with
+		 * the new socket..
+		 */
+		if (atomic_read(&nsk->sock_readers)) {
+			__skb_queue_tail(&nsk->back_log, skb);
+			return 0;
+		}
 		sk = nsk;
 	}
 
@@ -1264,7 +1265,6 @@
 		goto reset;
 	if (users)
 		goto ipv6_pktoptions;
-	release_sock(sk);
 	return 0;
 
 reset:
@@ -1273,7 +1273,6 @@
 	if (users)
 		kfree_skb(skb);
 	kfree_skb(skb);
-	release_sock(sk);  
 	return 0;
 
 ipv6_pktoptions:
@@ -1303,7 +1302,6 @@
 
 	if (skb)
 		kfree_skb(skb);
-	release_sock(sk);
 	return 0;
 }
 
diff -u --recursive --new-file v2.2.1/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v2.2.1/linux/net/ipx/af_ipx.c	Tue Jan 19 11:32:53 1999
+++ linux/net/ipx/af_ipx.c	Thu Feb 18 19:15:41 1999
@@ -766,11 +766,10 @@
 
 		i = 0;
 
-		/* Dump packet if too many hops or already seen this net */
-		if(ipx->ipx_tctrl < 8)
-			for( ; i < ipx->ipx_tctrl; i++)
-				if(*l++ == intrfc->if_netnum)
-					break;
+		/* Dump packet if already seen this net */
+		for( ; i < ipx->ipx_tctrl; i++)
+			if(*l++ == intrfc->if_netnum)
+				break;
 
 		if(i == ipx->ipx_tctrl) 
 		{ 
@@ -779,6 +778,10 @@
 			/* xmit on all other interfaces... */
 			for(ifcs = ipx_interfaces; ifcs != NULL; ifcs = ifcs->if_next) 
 			{
+				/* Except unconfigured interfaces */
+				if(ifcs->if_netnum == 0)
+					continue;
+					
 				/* That aren't in the list */
 				l = (__u32 *) c;
 				for(i = 0; i <= ipx->ipx_tctrl; i++)
@@ -2074,18 +2077,16 @@
 	
 	/* Too small? */
 	if(ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr))
-	{
-		kfree_skb(skb);
-		return (0);
-	}
-	
+		goto drop;
+		
+	/* Not ours */	
+        if (skb->pkt_type == PACKET_OTHERHOST)
+        	goto drop;
+                        
 	if(ipx->ipx_checksum != IPX_NO_CHECKSUM) 
 	{
 		if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize)) != ipx->ipx_checksum)
-		{
-			kfree_skb(skb);
-			return (0);
-		}
+			goto drop;
 	}
 
 	/* Determine what local ipx endpoint this is */
@@ -2099,13 +2100,14 @@
 		}
 
 		if(intrfc == NULL)	/* Not one of ours */
-		{
-			kfree_skb(skb);
-			return (0);
-		}
+			goto drop;
 	}
 
 	return (ipxitf_rcv(intrfc, skb));
+	
+drop:
+	kfree_skb(skb);
+	return (0);
 }
 
 static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
@@ -2133,8 +2135,11 @@
 			uaddr.sipx_port = 0;
 			uaddr.sipx_network = 0L;
 #ifdef CONFIG_IPX_INTERN
-			memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc
-				->if_node, IPX_NODE_LEN);
+			if(sk->protinfo.af_ipx.intrfc)
+				memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc
+						->if_node,IPX_NODE_LEN);
+			else
+				return -ENETDOWN;               /* Someone zonked the iface */
 #endif
 			ret = ipx_bind(sock, (struct sockaddr *)&uaddr,
 					sizeof(struct sockaddr_ipx));
diff -u --recursive --new-file v2.2.1/linux/net/netsyms.c linux/net/netsyms.c
--- v2.2.1/linux/net/netsyms.c	Fri Jan  8 22:36:27 1999
+++ linux/net/netsyms.c	Mon Feb  1 14:04:39 1999
@@ -382,6 +382,9 @@
 EXPORT_SYMBOL(ipv4_config);
 EXPORT_SYMBOL(dev_open);
 
+/* Used by other modules */
+EXPORT_SYMBOL(in_ntoa);
+
 EXPORT_SYMBOL(ip_rcv);
 EXPORT_SYMBOL(arp_rcv);
 EXPORT_SYMBOL(arp_tbl);
diff -u --recursive --new-file v2.2.1/linux/net/sunrpc/svcsock.c linux/net/sunrpc/svcsock.c
--- v2.2.1/linux/net/sunrpc/svcsock.c	Sun Nov  8 14:03:16 1998
+++ linux/net/sunrpc/svcsock.c	Sat Feb  6 12:46:22 1999
@@ -24,6 +24,7 @@
 #include <linux/fcntl.h>
 #include <linux/net.h>
 #include <linux/in.h>
+#include <linux/inet.h>
 #include <linux/udp.h>
 #include <linux/version.h>
 #include <linux/unistd.h>
@@ -546,14 +547,14 @@
 	 * we just punt connects from unprivileged ports. */
 	if (ntohs(sin.sin_port) >= 1024) {
 		printk(KERN_WARNING
-			"%s: connect from unprivileged port: %08lx:%d",
+			"%s: connect from unprivileged port: %s:%d",
 			serv->sv_name, 
-			ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+			in_ntoa(sin.sin_addr.s_addr), ntohs(sin.sin_port));
 		goto failed;
 	}
 
-	dprintk("%s: connect from %08lx:%04x\n", serv->sv_name,
-			ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+	dprintk("%s: connect from %s:%04x\n", serv->sv_name,
+			in_ntoa(sin.sin_addr.s_addr), ntohs(sin.sin_port));
 
 	if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0)))
 		goto failed;
diff -u --recursive --new-file v2.2.1/linux/scripts/Configure linux/scripts/Configure
--- v2.2.1/linux/scripts/Configure	Fri Nov 27 13:09:31 1998
+++ linux/scripts/Configure	Mon Feb  1 12:03:20 1999
@@ -1,4 +1,3 @@
-
 #! /bin/sh
 #
 # This script is used to configure the Linux kernel.
@@ -8,18 +7,8 @@
 # something better'' because the old configure script wasn't flexible
 # enough.
 #
-# Please send comments / questions / bug fixes to raymondc@microsoft.com.
-#
-#              ***** IMPORTANT COMPATIBILITY NOTE ****
-# If configuration changes are made which might adversely effect 
-# Menuconfig or xconfig, please notify the respective maintainers so that 
-# those utilities can be updated in parallel.
-#
-# Menuconfig:  <mec@shout.net>
-# xconfig:     <apenwarr@foxnet.net>  <eric@aib.com>
-#              ****************************************
-#
-# Each line in the config file is a command.
+# Raymond Chen was the original author of Configure.
+# Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
 #
 # 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13
 # with an empty IFS.
@@ -56,6 +45,9 @@
 #
 # 102598 Michael Chastain (mec@shout.net) - put temporary files in
 # current directory, not in /tmp.
+#
+# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
+# - Improve the exit message (Jeff Ronne).
 
 #
 # Make sure we're really running bash.
@@ -528,10 +520,13 @@
 mv .tmpconfig.h include/linux/autoconf.h
 
 echo
-echo "The Linux kernel should now be configured for your setup."
-echo "Check the top-level Makefile for additional configuration,"
-echo "and do a 'make dep ; make clean' if you want to be sure all"
-echo "the files are correctly re-made"
+echo "*** End of Linux kernel configuration."
+echo "*** Check the top-level Makefile for additional configuration."
+if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then
+    echo "*** Next, you must run 'make dep'."
+else
+    echo "*** Next, you may run 'make zImage', 'make zdisk', or 'make zlilo'."
+fi
 echo
 
 exit 0
diff -u --recursive --new-file v2.2.1/linux/scripts/Menuconfig linux/scripts/Menuconfig
--- v2.2.1/linux/scripts/Menuconfig	Wed Jan 13 15:00:45 1999
+++ linux/scripts/Menuconfig	Mon Feb  1 12:03:20 1999
@@ -65,6 +65,9 @@
 # 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
 # Blow away lxdialog.scrltmp on entry to activate_menu.  This protects
 # against people who use commands like ' ' to select menus.
+#
+# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
+# - Improve the exit message (Jeff Ronne).
 
 
 #
@@ -1290,9 +1293,19 @@
 then
 	save_configuration
 	echo
-	echo The linux kernel is now configured for your setup.
+	echo
+	echo "*** End of Linux kernel configuration."
+	echo "*** Check the top-level Makefile for additional configuration."
+	if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then
+	    echo "*** Next, you must run 'make dep'."
+	else
+	    echo "*** Next, you may run 'make zImage', 'make zdisk', or 'make zlilo.'"
+	fi
+	echo
 else
+	echo
     	echo 
 	echo Your kernel configuration changes were NOT saved.
+	echo
 fi
 exit 0
diff -u --recursive --new-file v2.2.1/linux/scripts/header.tk linux/scripts/header.tk
--- v2.2.1/linux/scripts/header.tk	Tue Jan 19 11:32:53 1999
+++ linux/scripts/header.tk	Mon Feb  1 12:03:20 1999
@@ -4,12 +4,17 @@
 # CHANGES
 # =======
 #
-# 8 January 1998, Michael Elizabeth Chastain, <mec@shout.net>
-# Remove unused do_cmd function (part of the 2.0 sound support).
-# Arrange buttons in three columns for better screen fitting.
-# Add CONSTANT_Y, CONSTANT_M, CONSTANT_N for commands like:
-#   dep_tristate 'foo' CONFIG_FOO m
+# 8 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
+# - Remove unused do_cmd function (part of the 2.0 sound support).
+# - Arrange buttons in three columns for better screen fitting.
+# - Add CONSTANT_Y, CONSTANT_M, CONSTANT_N for commands like:
+#     dep_tristate 'foo' CONFIG_FOO m
 #
+# 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
+# - Shut vfix the hell up.
+#
+# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
+# - Improve the exit message (Jeff Ronne).
 
 #
 # This is a handy replacement for ".widget cget" that requires neither tk4
@@ -27,7 +32,6 @@
 proc vfix { var } {
 	global $var
 	if [ catch {eval concat $$var} ] {
-		puts stdout "WARNING - broken Config.in!  $var was not declared!"
 		set $var 0
 	}
 }
@@ -428,8 +432,15 @@
 proc wrapup {w }  {
 	catch {destroy $w}
 	toplevel $w -class Dialog
-	message $w.m -width 400 -aspect 300 -text \
-		"The Linux kernel should now be configured for your setup. Check the top-level Makefile for additional configuration, and do a 'make dep ; make clean' if you want to be sure all the files are correctly re-made."  -relief raised 
+
+	global CONFIG_MODVERSIONS; vfix CONFIG_MODVERSIONS
+	if { ([file exists .hdepend] != 1) || ($CONFIG_MODVERSIONS == 1) } then {
+	    message $w.m -width 400 -aspect 300 -relief raised -text \
+		"End of Linux kernel configuration.  Check the top-level Makefile for additional configuration.  Next, you must run 'make dep'."
+	} else {
+	    message $w.m -width 400 -aspect 300 -relief raised -text \
+		"End of Linux kernel configuration.  Check the top-level Makefile for additional configuration.  Next, you may 'make bzImage', 'make bzdisk', or 'make bzlilo.'"
+	}
 	label $w.bm -bitmap info
 	pack $w.bm $w.m -pady 10 -side top -padx 10
 	wm title $w "Kernel build instructions" 
diff -u --recursive --new-file v2.2.1/linux/scripts/lxdialog/checklist.c linux/scripts/lxdialog/checklist.c
--- v2.2.1/linux/scripts/lxdialog/checklist.c	Tue Mar 10 10:03:37 1998
+++ linux/scripts/lxdialog/checklist.c	Mon Feb  1 12:03:20 1999
@@ -157,6 +157,14 @@
     wattrset (dialog, dialog_attr);
     waddch (dialog, ACS_RTEE);
 
+    if (title != NULL && strlen(title) >= width-2 ) {
+	/* truncate long title -- mec */
+	char * title2 = malloc(width-2+1);
+	memcpy( title2, title, width-2 );
+	title2[width-2] = '\0';
+	title = title2;
+    }
+
     if (title != NULL) {
 	wattrset (dialog, title_attr);
 	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
diff -u --recursive --new-file v2.2.1/linux/scripts/lxdialog/inputbox.c linux/scripts/lxdialog/inputbox.c
--- v2.2.1/linux/scripts/lxdialog/inputbox.c	Sun Mar 24 10:02:36 1996
+++ linux/scripts/lxdialog/inputbox.c	Mon Feb  1 12:03:20 1999
@@ -69,6 +69,14 @@
     wattrset (dialog, dialog_attr);
     waddch (dialog, ACS_RTEE);
 
+    if (title != NULL && strlen(title) >= width-2 ) {
+	/* truncate long title -- mec */
+	char * title2 = malloc(width-2+1);
+	memcpy( title2, title, width-2 );
+	title2[width-2] = '\0';
+	title = title2;
+    }
+
     if (title != NULL) {
 	wattrset (dialog, title_attr);
 	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
diff -u --recursive --new-file v2.2.1/linux/scripts/lxdialog/menubox.c linux/scripts/lxdialog/menubox.c
--- v2.2.1/linux/scripts/lxdialog/menubox.c	Wed Jan 13 15:00:45 1999
+++ linux/scripts/lxdialog/menubox.c	Mon Feb  1 12:03:20 1999
@@ -189,6 +189,14 @@
     wbkgdset (dialog, dialog_attr & A_COLOR);
     waddch (dialog, ACS_RTEE);
 
+    if (title != NULL && strlen(title) >= width-2 ) {
+	/* truncate long title -- mec */
+	char * title2 = malloc(width-2+1);
+	memcpy( title2, title, width-2 );
+	title2[width-2] = '\0';
+	title = title2;
+    }
+
     if (title != NULL) {
 	wattrset (dialog, title_attr);
 	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
diff -u --recursive --new-file v2.2.1/linux/scripts/lxdialog/msgbox.c linux/scripts/lxdialog/msgbox.c
--- v2.2.1/linux/scripts/lxdialog/msgbox.c	Tue Feb  6 23:47:28 1996
+++ linux/scripts/lxdialog/msgbox.c	Mon Feb  1 12:03:20 1999
@@ -43,6 +43,14 @@
 
     draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
 
+    if (title != NULL && strlen(title) >= width-2 ) {
+	/* truncate long title -- mec */
+	char * title2 = malloc(width-2+1);
+	memcpy( title2, title, width-2 );
+	title2[width-2] = '\0';
+	title = title2;
+    }
+
     if (title != NULL) {
 	wattrset (dialog, title_attr);
 	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
diff -u --recursive --new-file v2.2.1/linux/scripts/lxdialog/textbox.c linux/scripts/lxdialog/textbox.c
--- v2.2.1/linux/scripts/lxdialog/textbox.c	Thu Nov 12 16:21:25 1998
+++ linux/scripts/lxdialog/textbox.c	Mon Feb  1 12:03:20 1999
@@ -106,6 +106,14 @@
     wbkgdset (dialog, dialog_attr & A_COLOR);
     waddch (dialog, ACS_RTEE);
 
+    if (title != NULL && strlen(title) >= width-2 ) {
+	/* truncate long title -- mec */
+	char * title2 = malloc(width-2+1);
+	memcpy( title2, title, width-2 );
+	title2[width-2] = '\0';
+	title = title2;
+    }
+
     if (title != NULL) {
 	wattrset (dialog, title_attr);
 	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
diff -u --recursive --new-file v2.2.1/linux/scripts/lxdialog/yesno.c linux/scripts/lxdialog/yesno.c
--- v2.2.1/linux/scripts/lxdialog/yesno.c	Sat Mar  2 23:22:25 1996
+++ linux/scripts/lxdialog/yesno.c	Mon Feb  1 12:03:20 1999
@@ -63,6 +63,14 @@
     wattrset (dialog, dialog_attr);
     waddch (dialog, ACS_RTEE);
 
+    if (title != NULL && strlen(title) >= width-2 ) {
+	/* truncate long title -- mec */
+	char * title2 = malloc(width-2+1);
+	memcpy( title2, title, width-2 );
+	title2[width-2] = '\0';
+	title = title2;
+    }
+
     if (title != NULL) {
 	wattrset (dialog, title_attr);
 	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
diff -u --recursive --new-file v2.2.1/linux/scripts/tkgen.c linux/scripts/tkgen.c
--- v2.2.1/linux/scripts/tkgen.c	Wed Jan 20 23:14:07 1999
+++ linux/scripts/tkgen.c	Mon Feb  1 12:03:19 1999
@@ -89,6 +89,9 @@
  *   drives/net/Config.in and other places.
  * - Fix menu line wraparound at 128 menus (some fool used a 'char' for
  *   a counter).
+ *
+ * 23 January 1999, Michael Elizabeth Chastain <mec@shout.net>
+ * - Remove bug-compatible code.
  */
 
 #include <stdio.h>
@@ -749,11 +752,9 @@
 	    break;
 
 	case token_endmenu:
-#if ! defined(BUG_COMPATIBLE)
 	    /* flatten menus with proper scoping */
 	    if ( --menu_depth < 0 )
 		{ fprintf( stderr, "unmatched endmenu\n" ); exit( 1 ); }
-#endif
 	    break;
 
 	case token_bool:
diff -u --recursive --new-file v2.2.1/linux/scripts/tkparse.c linux/scripts/tkparse.c
--- v2.2.1/linux/scripts/tkparse.c	Wed Jan 20 23:14:07 1999
+++ linux/scripts/tkparse.c	Mon Feb  1 12:03:19 1999
@@ -26,6 +26,9 @@
  *   every architecture and comparing it character-for-character against
  *   the output of the old tkparse.
  *
+ * 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
+ * - Remove bug-compatible code.
+ *
  * TO DO:
  * - xconfig is at the end of its life cycle.  Contact <mec@shout.net> if
  *   you are interested in working on the replacement.
@@ -434,25 +437,14 @@
 
     case token_define_bool:
 	pnt = get_string( pnt, &cfg->optionname );
-#if ! defined(BUG_COMPATIBLE)
 	while ( *pnt == ' ' || *pnt == '\t' )
 	    pnt++;
-#endif
 	if      ( *pnt == 'n' || *pnt == 'N' ) cfg->value = "0";
 	else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = "1";
 	else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = "2";
 	else
 	{
-#if ! defined(BUG_COMPATIBLE)
 	    syntax_error( "unknown define_bool value" );
-#else
-	    /*
-	     * This ought to give the same output as printf'ing
-	     * through the null pointer ... I don't want to be
-	     * SIGSEGV compatible!
-	     */
-	    cfg->value = "(null)";
-#endif
 	}
 	break;
 
@@ -558,12 +550,7 @@
     if ( infile == NULL )
     {
 	sprintf( buffer, "unable to open %s", filename );
-#if defined(BUG_COMPATIBLE)
-	fprintf( stderr, "%s\n", buffer );
-	return;
-#else
 	syntax_error( buffer );
-#endif
     }
 
     /* push the new file name and line number */
diff -u --recursive --new-file v2.2.1/linux/scripts/tkparse.h linux/scripts/tkparse.h
--- v2.2.1/linux/scripts/tkparse.h	Wed Jan 20 23:14:07 1999
+++ linux/scripts/tkparse.h	Mon Feb  1 12:03:19 1999
@@ -3,14 +3,6 @@
  */
 
 /*
- * Define this symbol to generate exactly the same output, byte for byte,
- * as the previous version of xconfig.  I need to do this to make sure I
- * I don't break anything in my moby edit. -- mec
- */
-
-#define BUG_COMPATIBLE
-
-/*
  * Token types (mostly statement types).
  */
 
diff -u --recursive --new-file v2.2.1/linux/scripts/ver_linux linux/scripts/ver_linux
--- v2.2.1/linux/scripts/ver_linux	Tue Jan 19 11:32:54 1999
+++ linux/scripts/ver_linux	Sat Feb  6 12:46:22 1999
@@ -4,6 +4,7 @@
 # /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
 # differ on your system.
 #
+PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH
 echo '-- Versions installed: (if some fields are empty or looks'
 echo '-- unusual then possibly you have very old versions)'
 uname -a
