diff -u --recursive --new-file v2.1.99/linux/Documentation/Changes linux/Documentation/Changes
--- v2.1.99/linux/Documentation/Changes	Sat May  2 14:19:50 1998
+++ linux/Documentation/Changes	Wed May  6 11:50:20 1998
@@ -33,7 +33,7 @@
    Also, don't forget http://www.linuxhq.com/ for all your Linux kernel
 needs.
 
-Last updated: April 27, 1998
+Last updated: May 5, 1998
 Current Author: Chris Ricker (kaboom@gatech.edu).
 
 Current Minimal Requirements
@@ -60,7 +60,7 @@
 - Bash                   1.14.7                  ; bash -version
 - Ncpfs                  2.1.1                   ; ncpmount -v
 - Pcmcia-cs              3.0.0
-- PPP                    2.3.3                   ; pppd -v
+- PPP                    2.3.5                   ; pppd -v
 
 Upgrade notes
 *************
@@ -127,6 +127,12 @@
 to find out the proper way to upgrade it.  No, the instruction to "rm
 `which encaps`" is not a joke.
 
+The last public release of the binutils 2.8.x series is 2.8.1.0.23. 
+Binutils 2.8.1.0.25 to 2.9.1.0.2 are all very buggy; do not use them. 
+Binutils 2.9.1 (note the absence of a suffix) is all right, and binutils
+2.9.1.0.3 (and presumably later revisions) will probably work, too. 
+Stick with 2.8.1.0.23 to be safe. 
+
 Gnu C
 =====
 
@@ -423,14 +429,14 @@
 Pcmcia-cs
 =========
 
-The 3.0.0 release:
-ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs-3.0.0.tar.gz
+The May 4, 1998 release:
+ftp://hyper.stanford.edu/pub/pcmcia/NEW/pcmcia-cs.04-May-98.tar.gz
 
 PPP
 ===
 
-The 2.3.3 release:
-ftp://cs.anu.edu.au/pub/software/ppp/ppp-2.3.3.tar.gz
+The 2.3.5 release:
+ftp://cs.anu.edu.au/pub/software/ppp/ppp-2.3.5.tar.gz
 
 Other Info
 ==========
diff -u --recursive --new-file v2.1.99/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.99/linux/Documentation/Configure.help	Sat May  2 14:19:50 1998
+++ linux/Documentation/Configure.help	Sun May  3 17:52:07 1998
@@ -4,7 +4,7 @@
 # corresponds to the kernel versions 2.1.x. Be aware that these are
 # development kernels and need not be completely stable.
 #
-# International versions of this file available on the WWW:
+# Translations of this file available on the WWW:
 #   - http://jf.gee.kyoto-u.ac.jp/JF/JF-ftp/euc/Configure.help.euc
 # is a Japanese translation, maintained by Tetsuyasu YAMADA
 # (tetsu@cauchy.nslab.ntt.jp). 
@@ -33,16 +33,14 @@
 #
 # Format of this file: description<nl>variable<nl>helptext<nl><nl>. If
 # the question being documented is of type "choice", we list only the
-# first occurring config variable. The help texts must not contain
-# empty lines. Order of the help texts does not matter, however, no
-# variable should be documented twice: if it is, only the first
-# occurrence will be used by Configure. It is not absolutely necessary
-# that the one-line descriptions of the variables used here are
-# exactly the same as the ones in the corresponding Config.in scripts.
-# The lines in a help text should be indented two positions. Lines
-# starting with `#' are ignored. To be nice to menuconfig, limit your
-# lines to 70 characters. Use emacs' kfill.el to edit and ispell.el to
-# spell check this file or you lose.
+# first occurring config variable. The help texts may contain empty
+# lines, but every non-empty line must be indented two positions.
+# Order of the help texts does not matter, however, no variable should
+# be documented twice: if it is, only the first occurrence will be
+# used by Configure. We try to keep the help texts of related variables
+# close together. Lines starting with `#' are ignored. To be nice to
+# menuconfig, limit your line length to 70 characters. Use emacs'
+# kfill.el to edit and ispell.el to spell check this file or you lose.
 #
 # If you add a help text to this file, please try to be as gentle as
 # possible. Don't use unexplained acronyms and generally write for the
@@ -51,12 +49,14 @@
 # for the first time. Tell them what to do if they're unsure. Technical 
 # information should go in a README in the Documentation directory.
 # Mention all the relevant READMEs and HOWTOs in the help text.
+# Repetitions are fine since the help texts are not meant to be read
+# in sequence.
 #
 # 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
-# Public License.
+# General Public License.
 
 Prompt for development and/or incomplete code/drivers
 CONFIG_EXPERIMENTAL
@@ -75,6 +75,7 @@
   (before submitting bug reports, please read the documents README,
   MAINTAINERS, Documentation/BUG-HUNTING, and
   Documentation/oops-tracing.txt in the kernel source).  
+
   Unless you intend to help test and develop a feature or driver that
   falls into this category, or you have a situation that requires
   using these features you should probably say N here, which will
@@ -88,32 +89,25 @@
   operations) if you don't have one. 486DX and Pentium processors have
   a math coprocessor built in, 486SX and 386 do not, unless you added
   a 487DX or 387, respectively.  (The messages during boot time can
-  give you some hints here ["man dmesg"]) Everyone needs either a
-  coprocessor or this emulation. If you say Y here even
-  though you have a coprocessor, the coprocessor will be used
-  nevertheless. (This behavior can be changed with the kernel command
-  line option "no387", which comes handy if your coprocessor is
-  broken. Try "man bootparam" or see the documentation of your boot
+  give you some hints here ["man dmesg"].) Everyone needs either a
+  coprocessor or this emulation. 
+
+  If you don't have a math coprocessor, you need to say Y here; if you
+  say Y here even though you have a coprocessor, the coprocessor will
+  be used nevertheless. (This behavior can be changed with the kernel
+  command line option "no387", which comes handy if your coprocessor
+  is broken. Try "man bootparam" or see the documentation of your boot
   loader (lilo or loadlin) about how to pass options to the kernel at
   boot time. The lilo procedure is also explained in the SCSI-HOWTO,
   available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.) This means that it is a good
-  idea to say Y here if you intend to use this kernel on different
-  machines. More information about the internals of Linux math
-  coprocessor emulation can be found in arch/i386/math-emu/README. If
-  you are not sure, say Y; apart from resulting in a 45kB bigger
-  kernel, it won't hurt.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) This means that it is a
+  good idea to say Y here if you intend to use this kernel on
+  different machines. More information about the internals of Linux
+  math coprocessor emulation can be found in
+  arch/i386/math-emu/README.
 
-Max physical memory
-CONFIG_MAX_MEMSIZE
-  Linux/x86 can use up to 3.8 gigabytes of physical memory. Default
-  is max 1 gigabyte physical memory (1024 MB), this is enough for
-  most systems.
-  A system with 2G physical memory should use a value of ~2400, a
-  system with 3.8G memory should use something like 3900. A bit of
-  experimentation with the limit wont hurt, the kernel needs a ~128M
-  window for vmalloc() plus PCI space uses up some memory too, thus
-  addresses above FD000000 should rather be kept free.
+  If you are not sure, say Y; apart from resulting in a 45kB bigger
+  kernel, it won't hurt.
 
 Normal floppy disk support
 CONFIG_BLK_DEV_FD
@@ -122,11 +116,12 @@
   Thinkpad users, is contained in drivers/block/README.fd. This file
   also contains the location of the Floppy driver FAQ as well as
   location of the fdutils package used to configure additional
-  parameters of the driver at run time. 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
-  floppy.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  parameters of the driver at run time. 
+
+  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 floppy.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 RAM disk support
 CONFIG_BLK_DEV_RAM
@@ -137,11 +132,15 @@
   store a copy of a minimal root file system off of a floppy into RAM
   during the initial install of Linux.  Note that the kernel command
   line option "ramdisk=XX" is now obsolete.  For details, read
-  Documentation/ramdisk.txt. 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 and read Documentation/modules.txt. The
-  module will be called rd.o. Most normal users won't need the RAM
-  disk functionality, and can thus say N here.
+  Documentation/ramdisk.txt. 
+
+  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 and read Documentation/modules.txt. The module will be called
+  rd.o. 
+
+  Most normal users won't need the RAM disk functionality, and can
+  thus say N here.
 
 Initial RAM disk (initrd) support
 CONFIG_BLK_DEV_INITRD
@@ -153,15 +152,16 @@
 
 Loop device support
 CONFIG_BLK_DEV_LOOP
-  Saying Y here will allow you to mount a file as a file system.  This
+  Saying Y here will allow you to mount a file as a file system. This
   is useful if you want to check an ISO9660 file system before burning
   the CD, or want to use floppy images without first writing them to
-  floppy.  This option also allows you to mount a filesystem with
-  encryption.  To use these features, you need a recent version of
+  floppy. This option also allows you to mount a filesystem with
+  encryption. To use these features, you need a recent version of
   mount (available via ftp (user: anonymous) from
-  ftp.win.tue.nl/pub/linux/util/).  Note that this loop device has
-  nothing to do with the loopback device used for network connections
-  from the machine to itself.  Most users will answer N here.
+  ftp://ftp.win.tue.nl/pub/linux/util/). Note that this loop device
+  has nothing to do with the loopback device used for network
+  connections from the machine to itself. Most users will answer N
+  here.
 
 Network Block Device support
 CONFIG_BLK_DEV_NBD
@@ -172,33 +172,44 @@
   client program this is hidden: it looks like a regular local file
   access to a special file such as /dev/nd0. It also allows you to run
   a block-device in userland (making server and client physically the
-  same computer, communicating using loopback). 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
-  nbd.o. Normal users say N here. Read Documentation/nbd.txt.
+  same computer, communicating using the loopback network device). 
+  Read Documentation/nbd.txt for details.
+
+  Note that this has nothing to do with the network file system NFS;
+  you can say N here even if you intend to use NFS.
+
+  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 nbd.o.
+
+  If unsure, say N.
 
 Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
 CONFIG_BLK_DEV_IDE
-  This will use the full-featured IDE driver to control up to four IDE
-  interfaces, each being able to serve a "master" and a "slave"
-  device, for a combination of up to eight IDE disk/cdrom/tape/floppy
-  drives. Useful information about large (>540MB) IDE disks, sound
-  card IDE ports, module support, and other topics, is contained in
+  If you say Y here, you will use the full-featured IDE driver to
+  control up to four IDE interfaces, each being able to serve a
+  "master" and a "slave" device, for a total of up to eight IDE
+  disk/cdrom/tape/floppy drives.
+
+  Useful information about large (>540MB) IDE disks, sound card IDE
+  ports, module support, and other topics, is contained in
   Documentation/ide.txt. For detailed information about hard drives,
   consult the Disk-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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 13kB of memory in the
-  kernel. To fine-tune IDE drive/interface parameters for improved
-  performance, look for the hdparm package at
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. To fine-tune IDE
+  drive/interface parameters for improved performance, look for the
+  hdparm package at
   sunsite.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 13kB of memory in the kernel.
+
 Old hard disk (MFM/RLL/IDE) driver
 CONFIG_BLK_DEV_HD_ONLY
-  There are two drivers for MFM/RLL/IDE disks. Most people use the
-  newer enhanced driver, but this old one is still around for two
+  There are two drivers for MFM/RLL/IDE hard disks. Most people use
+  the newer enhanced driver, but this old one is still around for two
   reasons. Some older systems have strange timing problems and seem to
   work only with the old driver (which itself does not work with some
   newer systems). The other reason is that the old driver is smaller,
@@ -208,68 +219,78 @@
   driver can save 13kB or so of kernel memory. If you are unsure, then
   just choose the Enhanced IDE/MFM/RLL driver instead of this one. For
   more detailed information, read the Disk-HOWTO, available via ftp
-  (user: anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 Use old disk-only driver on primary interface
 CONFIG_BLK_DEV_HD_IDE
-  There are two drivers for MFM/RLL/IDE disks.  Most people use just
-  the new enhanced driver by itself.  This option however installs the
-  old hard disk driver to control the primary IDE/disk interface in the
-  system, leaving the new enhanced IDE driver take care of only the
-  2nd/3rd/4th IDE interfaces. Doing this will prevent you from having
-  an IDE/ATAPI CDROM or tape drive connected to the primary IDE
+  There are two drivers for MFM/RLL/IDE disks. Most people use just
+  the new enhanced driver by itself. This option however installs the
+  old hard disk driver to control the primary IDE/disk interface in
+  the system, leaving the new enhanced IDE driver to take care of only
+  the 2nd/3rd/4th IDE interfaces. Doing this will prevent you from
+  having an IDE/ATAPI CDROM or tape drive connected to the primary IDE
   interface. Choosing this option may be useful for older systems
   which have MFM/RLL/ESDI controller+drives at the primary port
   address (0x1f0), along with IDE drives at the secondary/3rd/4th port
-  addresses.  Normally, just say N here; you will then use the new
+  addresses. Normally, just say N here; you will then use the new
   driver for all 4 interfaces.
 
 Include IDE/ATA-2 DISK support
 CONFIG_BLK_DEV_IDEDISK
   This will include enhanced support for MFM/RLL/IDE hard disks. If you
   have a MFM/RLL/IDE disk, and there is no special reason to use the
-  old hard disk driver instead, say Y.  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 ide-disk.o. Do
-  not compile this driver as a module if your root filesystem (the one
-  containing the directory /) is located on the IDE disk. If unsure,
-  say Y.
+  old hard disk driver instead, say Y.  
+
+  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 ide-disk.o. Do not compile this driver as a module if your
+  root filesystem (the one containing the directory /) is located on
+  the IDE disk. If unsure, say Y.
 
 Include IDE/ATAPI CDROM support
 CONFIG_BLK_DEV_IDECD
-  If you have a CDROM drive using the ATAPI protocol, say Y.  ATAPI is
+  If you have a CDROM drive using the ATAPI protocol, say Y. ATAPI is
   a new protocol used by IDE CDROM and TAPE drives, similar to the
-  SCSI protocol.  Most new CDROM drives use ATAPI, including the
+  SCSI protocol. Most new CDROM drives use ATAPI, including the
   NEC-260, Mitsumi FX400, Sony 55E, and just about all non-SCSI
-  double(2X), quad(4X), and six(6X) speed drives.  At boot time, the
-  CDROM drive will be identified along with other IDE devices, as
-  "hdb" or "hdc", or something similar (check the boot messages with
-  dmesg).  If this is your only CDROM drive, you can say N to all
-  other CDROM options, but be sure to say Y to "ISO9660 cdrom
-  filesystem support".  Read the CDROM-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO and the file
-  Documentation/cdrom/ide-cd.  Note that older versions of lilo (the
-  linux boot loader) cannot properly deal with IDE/ATAPI CDROMs, so
+  double(2X), quad(4X), and six(6X) speed drives.
+
+  If you say Y here, the CDROM drive will be identified at boot time
+  along with other IDE devices, as "hdb" or "hdc", or something
+  similar (check the boot messages with dmesg). If this is your only
+  CDROM drive, you can say N to all other CDROM options, but be sure
+  to say Y to "ISO9660 cdrom filesystem support".
+
+  Read the CDROM-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and the file
+  Documentation/cdrom/ide-cd. Note that older versions of lilo (the
+  Linux boot loader) cannot properly deal with IDE/ATAPI CDROMs, so
   install lilo-16 or higher, available from
-  sunsite.unc.edu:/pub/Linux/system/Linux-boot/lilo.  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 ide-cd.o.
+  ftp://sunsite.unc.edu/pub/Linux/system/Linux-boot/lilo.
+
+  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 ide-cd.o.
 
 Include IDE/ATAPI TAPE support
 CONFIG_BLK_DEV_IDETAPE
   If you have an IDE tape drive using the ATAPI protocol, say Y.
   ATAPI is a new protocol used by IDE tape and CDROM drives, similar
-  to the SCSI protocol.  At boot time, the tape drive will be
-  identified along with other IDE devices, as "hdb" or "hdc", or
-  something similar, and will be mapped to a character device such as
-  "ht0" (check the boot messages with dmesg).  Be sure to consult the
+  to the SCSI protocol.  
+
+  If you say Y here, the tape drive will be identified at boot time
+  along with other IDE devices, as "hdb" or "hdc", or something
+  similar, and will be mapped to a character device such as "ht0"
+  (check the boot messages with dmesg). Be sure to consult the
   drivers/block/ide-tape.c and Documentation/ide.txt files for usage
-  information.  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 ide-tape.o.
+  information.
+
+  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 ide-tape.o.
 
 Include IDE/ATAPI FLOPPY support
 CONFIG_BLK_DEV_IDEFLOPPY
@@ -277,13 +298,17 @@
   Y.  ATAPI is a new 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 through the SCSI
-  emulation). At boot time, the FLOPPY drive will be identified along
-  with other IDE devices, as "hdb" or "hdc", or something similar
-  (check the boot messages with dmesg). 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 ide-floppy.o.
+  driver; support for PD-CD/CDR drives is available if you say 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
+  the boot messages with dmesg).
+
+  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 ide-floppy.o.
 
 SCSI emulation support
 CONFIG_BLK_DEV_IDESCSI
@@ -305,10 +330,17 @@
   conditions.  Say Y here to include code which tries to automatically
   detect and correct the problems under Linux.  This option also
   enables access to the secondary IDE ports in some CMD640 based
-  systems.  This driver will work automatically in PCI based systems
-  (most new systems have PCI slots).  But if your system uses VESA
-  local bus (VLB) instead of PCI, you must also supply a kernel boot
-  parameter to enable the CMD640 bugfix/support: "ide0=cmd640_vlb".
+  systems.  
+
+  This driver will work automatically in PCI based systems (most new
+  systems have PCI slots). But if your system uses VESA local bus
+  (VLB) instead of PCI, you must also supply a kernel boot parameter
+  to enable the CMD640 bugfix/support: "ide0=cmd640_vlb". (Try "man
+  bootparam" or see the documentation of your boot loader about how to
+  pass options to the kernel. The lilo procedure is also explained in
+  the SCSI-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.)
+
   The CMD640 chip is also used on add-in cards by Acculogic, and on
   the "CSA-6400E PCI to IDE controller" that some people have. For
   details, read Documentation/ide.txt. If unsure, say Y.
@@ -348,16 +380,18 @@
   You can also use the "hdparm" utility to enable DMA for drives which
   were not enabled automatically.  You can get the latest version of
   the hdparm utility via anonymous FTP from
-  sunsite.unc.edu/pub/Linux/system/hardware/. Read the comments at the
-  beginning of drivers/block/idedma.c and the file
-  Documentation/ide.txt for more information.
+  ftp://sunsite.unc.edu/pub/Linux/system/hardware/. 
+
+  Read the comments at the beginning of drivers/block/idedma.c and the
+  file Documentation/ide.txt for more information. 
+
   It is safe to say Y to this question.
 
 Other IDE chipset support
 CONFIG_IDE_CHIPSETS
   Say Y here if you want to include enhanced support for various IDE
   interface chipsets used on motherboards and add-on cards.  This
-  enhanced support may be necessary for linux to be able to access the
+  enhanced support may be necessary for Linux to be able to access the
   3rd/4th drives in some systems.  It may also enable setting of
   higher speed I/O rates to improve system performance with these
   chipsets.  Most of these also require special kernel boot parameters
@@ -396,6 +430,12 @@
   "ide0=dc4030" kernel boot parameter.  See the Documentation/ide.txt
   and drivers/block/pdc4030.c files for more info.
 
+PS/2 ESDI hard disk support
+CONFIG_BLK_DEV_PS2
+  Say Y here if you have a PS/2 machine with a MCA bus and an ESDI
+  hard disk.
+
+Tekram TRM290 chipset support (EXPERIMENTAL)
 CONFIG_BLK_DEV_TRM290
   This driver adds support for bus master DMA transfers
   using the Tekram TRM290 PCI IDE chip.  Volunteers are
@@ -458,21 +498,24 @@
   your computer's parallel port. Most of them are actually IDE devices
   using a parallel port IDE adapter. This option enables the PARIDE
   subsystem which contains drivers for many of these external drives.
-  Read linux/Documentation/paride.txt for more information. If you
-  have said Y to the "Parallel-port support" configuration option, you
-  may share a single port between your printer and other parallel port
-  devices. Answer Y to build PARIDE support into your kernel, or M if
-  you would like to build it as a loadable module. If your parallel
-  port support is in a loadable module, you must build PARIDE as a
-  module. If you built PARIDE support into your kernel, you may still
-  build the individual protocol modules and high-level drivers as
-  loadable modules. To use the PARIDE support, you must say Y or M
-  here and also to at least one high-level driver (e.g. "Parallel port
-  IDE disks", "Parallel port ATAPI CD-ROMs", "Parallel port ATAPI
-  disks" etc.) and to at least one protocol driver (e.g. "ATEN EH-100
-  protocol", "MicroSolutions backpack protocol", "DataStor Commuter
-  protocol" etc.). If you build this support as a module, it will be
-  called paride.o.
+  Read linux/Documentation/paride.txt for more information.
+
+  If you have said Y to the "Parallel-port support" configuration
+  option, you may share a single port between your printer and other
+  parallel port devices. Answer Y to build PARIDE support into your
+  kernel, or M if you would like to build it as a loadable module. If
+  your parallel port support is in a loadable module, you must build
+  PARIDE as a module. If you built PARIDE support into your kernel,
+  you may still build the individual protocol modules and high-level
+  drivers as loadable modules. If you build this support as a module,
+  it will be called paride.o.
+
+  To use the PARIDE support, you must say Y or M here and also to at
+  least one high-level driver (e.g. "Parallel port IDE disks",
+  "Parallel port ATAPI CD-ROMs", "Parallel port ATAPI disks" etc.) and
+  to at least one protocol driver (e.g. "ATEN EH-100 protocol",
+  "MicroSolutions backpack protocol", "DataStor Commuter protocol"
+  etc.).
 
 Parallel port IDE disks
 CONFIG_PARIDE_PD 
@@ -626,12 +669,14 @@
 Multiple devices driver support
 CONFIG_BLK_DEV_MD
   This driver lets you combine several hard disk partitions into one
-  logical block device. Information about how and why to use it and
-  the necessary tools are available over ftp (user: anonymous) from
-  sweet-smoke.ufr-info-p7.ibp.fr/pub/Linux in the md package and the
-  md-FAQ. Please read drivers/block/README.md and the relevant section
-  of the Disk-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If unsure, say N.
+  logical block device. This can be used to combine several redundant
+  hard disks to a RAID1/4/5 device so as to provide protection against
+  hard disk failures. More information and the necessary tools are
+  available over ftp (user: anonymous) from
+  ftp://sweet-smoke.ufr-info-p7.ibp.fr/pub/Linux in the md package and
+  the md-FAQ. Please read drivers/block/README.md and the relevant
+  section of the Disk-HOWTO, available via ftp (user: anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If unsure, say N.
 
 Linear (append) mode
 CONFIG_MD_LINEAR
@@ -663,11 +708,14 @@
   an error free MD (multiple device) to the higher levels of the
   kernel. In a set with N drives, the available space is the capacity
   of a single drive, and the set protects against a failure of (N - 1)
-  drives.  raidtools, a set of user-space tools which create and
-  maintain RAID1/4/5 sets, is available at:
+  drives.  
+
+  Raidtools, a set of user-space tools which create and maintain
+  RAID1/4/5 sets, is available at:
   ftp://ftp.kernel.org/pub/linux/daemons/raid
   http://luthien.nuclecu.unam.mx/~miguel/raid
-  If you want to use such a RAID-1 set say Y. This code is also
+
+  If you want to use such a RAID-1 set, say Y. This code is also
   available as a module called raid1.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
@@ -682,10 +730,12 @@
   For a RAID-4 set, the parity blocks are present on a single drive,
   while a RAID-5 set distributes the parity across the drives in one
   of the available parity distribution methods.
-  raidtools, a set of user-space tools which create and maintain
+
+  Raidtools, a set of user-space tools which create and maintain
   RAID1/4/5 sets, is available at:
   ftp://ftp.kernel.org/pub/linux/daemons/raid
   http://luthien.nuclecu.unam.mx/~miguel/raid
+
   If you want to use such a RAID-5 set, say Y. This code is also
   available as a module called raid5.o ( = code which can be inserted
   in and removed from the running kernel whenever you want). If you
@@ -694,8 +744,8 @@
 
 Boot support (linear, striped)
 CONFIG_MD_BOOT
-  To boot with an initial linear or striped md device you have to 
-  select this. For lilo and loadlin options see Documentation/md.txt.
+  To boot with an initial linear or striped md device you have to say
+  Y here. For lilo and loadlin options see Documentation/md.txt.
 
 Support for Deskstation RPC44 
 CONFIG_DESKSTATION_RPC44
@@ -708,11 +758,11 @@
 
 Support for Mips Magnum 3000 
 CONFIG_MIPS_MAGNUM_3000
-  To compile a Linux kernel that runs on these, say Y here. For
-  details about Linux on the MIPS architecture, check out the
+  To compile a Linux kernel that runs on these machines, say Y here.
+  For details about Linux on the MIPS architecture, check out the
   Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse the
-  WWW, you need to have access to a machine on the Internet that has
-  a program like lynx or netscape).
+  WWW, you need to have access to a machine on the Internet that has a
+  program like lynx or netscape).
 
 Support for Mips Magnum 4000
 CONFIG_MIPS_MAGNUM_4000
@@ -773,52 +823,31 @@
   should consider updating your networking tools too because changes
   in the kernel and the tools often go hand in hand. The tools are
   contained in the package net-tools, the location and version number
-  of which is given in Documentation/Changes.
-
-Fast switching (read help!)
-CONFIG_NET_FASTROUTE
-  Enables direct NIC-to-NIC data transfers, which is fast.
-    *** This option is NOT COMPATIBLE with several important ***
-    *** networking options: especially CONFIG*FIREWALL.      ***
-  However, it will work with all options in CONFIG_IP_ADVANCED_ROUTER
-  section (except for CONFIG_IP_ROUTE_TOS). At the moment, few devices
-  support fast switching (tulip is one of them, modified 8390 can be
-  found at ftp://ftp.inr.ac.ru/ip-routing/fastroute-8390.tar.gz). If
-  unsure, say N.
-
-Forwarding between high speed interfaces
-CONFIG_NET_HW_FLOWCONTROL
-  This option enables NIC hardware throttling during periods of
-  extremal congestion. At the moment only a couple of device drivers
-  support it (really only one ---tulip, modified 8390 can be found at
-  ftp://ftp.inr.ac.ru/ip-routing/fastroute-8390.tar.gz).  Really, this
-  option is applicable to any machine attached to a fast enough
-  network, and even a 10Mb NIC is able to kill a not very slow box,
-  such as a 120MHz Pentium.
-  However, do not enable this option, if you did not experience
-  any serious problems.
+  of which are given in Documentation/Changes.
 
 Network aliasing
 CONFIG_NET_ALIAS
-  This will allow you to set multiple network addresses on the same
-  low-level network device driver. Typically used for services that
-  act differently based on the address they listen on (e.g.
-  "multihosting" or "virtual domains" or "virtual hosting services" on
-  the web server apache and the ftp server wuftpd -- read the
-  Virtual-Services-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO) or for connecting to
-  different logical networks through the same physical interface (most
-  commonly an Ethernet networking card). This is the generic part,
-  later when configuring network protocol options you will be asked
-  for protocol-specific aliasing support, and you will have to say Y
-  to at least one of them, most likely "IP: aliasing support". See
-  Documentation/networking/alias.txt for more info. If you need this
-  feature (for any protocol, like IP) say Y; if unsure, say N.
+  If you say Y here, you will be able to set multiple network
+  addresses on the same low-level network device driver. This is
+  typically used for services that act differently based on the
+  address they listen on (e.g. "multihosting" or "virtual domains" or
+  "virtual hosting services" on the web server apache and the ftp
+  server wuftpd -- read the Virtual-Services-HOWTO, available via ftp
+  (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO)
+  or for connecting to different logical networks through the same
+  physical interface (most commonly an Ethernet networking card). See
+  Documentation/networking/alias.txt for more info.
+
+  This is the generic part, later when configuring network protocol
+  options you will be asked for protocol-specific aliasing support,
+  and you will have to say Y to at least one of them, most likely to
+  "IP: aliasing support". If you need this feature (for any protocol,
+  like IP) say Y; if unsure, say N.
 
 Socket filtering
 CONFIG_FILTER
   The Linux Socket Filter is derived from the Berkeley Packet Filter.
-  If you say Y here, user-space programs can attach a filter onto any
+  If you say Y here, user-space programs can attach a filter to any
   socket and thereby tell the kernel that it should allow or disallow
   certain types of data to get through the socket. Linux Socket
   Filtering works on all socket types except TCP for now. See the text
@@ -829,22 +858,39 @@
 CONFIG_FIREWALL
   A firewall is a computer which protects a local network from the
   rest of the world: all traffic to and from computers on the local
-  net is inspected by the firewall first, and sometimes blocked. If
-  you want to configure your Linux box as a firewall for a local
-  network, say Y here. If your local network is TCP/IP based, you will
-  then also have to say Y to "IP: firewalling", below.  
-  You also need to say Y here and say Y to "IP firewalling" below in
-  order to be able to use IP masquerading (i.e. local computers can
-  chat with an outside host, but that outside host is made to think
-  that it is talking to the firewall box -- makes the local network
-  completely invisible and avoids the need to allocate valid IP host
-  addresses for the machines on the local net) and IP packet
-  accounting (keeping track of what is using all your network
-  bandwidth) and IP transparent proxying (makes the computers on the
-  local network think they're talking to a remote computer, while in
-  reality the traffic is redirected by your Linux firewall to a local
-  proxy server). Chances are that you should use this on every machine
-  being run as a router and not on any regular host. If unsure, say N.
+  net is inspected by the firewall first, and sometimes blocked or
+  modified. The type of firewall you'll get if you say Y here is
+  called a "packet filter": it can block network traffic based on
+  type, origin and destination. By contrast, "proxy-based" firewalls
+  are more secure but more intrusive and more bothersome to set up;
+  they inspect the network traffic much more closely, modify it and
+  have knowledge about the higher level protocols, which packet
+  filters lack. They also often require changes in the programs
+  running on the local clients. Proxy-based firewalls don't need
+  support by the kernel, but they are often combined with packet
+  filters, which only works if you say Y here.
+
+  If you want to configure your Linux box as a packet filter firewall
+  for a local network, say Y here. If your local network is TCP/IP
+  based, you will then also have to say Y to "IP: firewalling", below.
+
+  You also need to say Y here and to "IP firewalling" below in order
+  to be able to use IP masquerading (i.e. local computers can chat
+  with an outside host, but that outside host is made to think that it
+  is talking to the firewall box -- makes the local network completely
+  invisible to the outside world and avoids the need to allocate
+  globally valid IP host addresses for the machines on the local net)
+  and IP packet accounting (keeping track of what is using up all your
+  network bandwidth) and IP transparent proxying (makes the computers
+  on the local network think they're talking to a remote computer,
+  while in reality the traffic is redirected by your Linux firewall to
+  a local proxy server).
+  
+  Make sure to say N to "Fast switching" below if you intend to say Y
+  here.
+
+  Chances are that you should say Y here for every machine which is
+  run as a router and N for every regular host. If unsure, say N.
 
 SYN flood protection
 CONFIG_SYN_COOKIES
@@ -852,19 +898,24 @@
   This denial-of-service attack prevents legitimate remote users from
   being able to connect to your computer and requires very little work
   from the attacker, who can operate from anywhere on the Internet.
-  SYN cookies provide protection against this type of attack. With
-  this option turned on, the TCP/IP stack will use a cryptographic
-  challenge protocol known as SYN cookies to enable legitimate users
-  to continue to connect, even when your machine is under attack.
-  There is no need for the legitimate users to change their TCP/IP
-  software; SYN cookies work transparently to them.  For technical
-  information about SYN cookies, check out
+
+  SYN cookies provide protection against this type of attack. If you
+  say Y here, the TCP/IP stack will use a cryptographic challenge
+  protocol known as "SYN cookies" to enable legitimate users to
+  continue to connect, even when your machine is under attack. There
+  is no need for the legitimate users to change their TCP/IP software;
+  SYN cookies work transparently to them. For technical information
+  about SYN cookies, check out
   ftp://koobera.math.uic.edu/pub/docs/syncookies-archive.
-  If you say Y here, note that SYN cookies aren't enabled by default:
-  you need to add the command
+
+  If you say Y here, note that SYN cookies aren't enabled by default;
+  you can enable them by saying Y to "/proc filesystem support" and
+  "Sysctl support" below and executing the command
+
     echo 1 >/proc/sys/net/ipv4/tcp_syncookies 
-  to one of your startup scripts (e.g. /etc/rc.local or 
-  /etc/rc.d/rc.local) in addition.
+
+  at boot time after the proc filesystem has been mounted.
+  
   If unsure, say Y.
 
 Sun floppy controller support
@@ -879,7 +930,7 @@
   http://www.azstarnet.com/~axplinux/ (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 the Alpha-HOWTO, available via ftp (user:
-  anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO. For this
+  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. For this
   question, it suffices to give a unique prefix of the option you want
   to choose. The choices:
   ** Avanti: This is for Mustang (AS200), M3 (AS250), Avanti (AS400)
@@ -910,21 +961,24 @@
 CONFIG_ALPHA_SRM
   There are two different types of booting firmware on Alphas: SRM,
   which is command line driven, and ARC, which uses menus and arrow
-  keys. The usual way to load Linux on an Alpha machine is to use MILO
+  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
+  have access to a machine on the Internet that has a program like
+  lynx or netscape).
+
+  The usual way to load Linux on an Alpha machine is to use MILO
   (a bootloader that lets you pass command line parameters to the
-  kernel just like lilo does for the 386 architecture) which can be
+  kernel just like lilo does for the x86 architecture) which can be
   loaded either from ARC or can be installed directly as a permanent
   firmware replacement from floppy (which requires changing a certain
   jumper on the motherboard). If you want to do either of these, say N
   here. If MILO doesn't work on your system (true for Jensen
   motherboards), you can bypass it altogether and boot Linux directly
   from an SRM console; say Y here in order to do that. Note that you
-  won't be able to boot from an IDE disk using SRM. If unsure, say
-  N. Details about the Linux/Alpha booting process are contained in
-  the Linux/Alpha FAQ, accessible on the WWW from
-  http://www.azstarnet.com/~axplinux/ (To browse the WWW, you need to
-  have access to a machine on the Internet that has a program like
-  lynx or netscape).
+  won't be able to boot from an IDE disk using SRM. 
+
+  If unsure, say N.
 
 Non-standard serial port support
 CONFIG_SERIAL_NONSTANDARD
@@ -950,14 +1004,15 @@
 
 Support more than 4 serial ports
 CONFIG_SERIAL_MANY_PORTS
-  Enable this option if you have dumb serial boards other than the
-  four standard COM 1/2/3/4 ports. This may happen if you have an AST
+  Say Y here if you have dumb serial boards other than the four
+  standard COM 1/2/3/4 ports. This may happen if you have an AST
   FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
   via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini), or other custom serial
-  port hardware which acts similar to standard serial port hardware.
-  If you only use the standard COM 1/2/3/4 ports, you can say N here
-  to save some memory.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini), or other custom
+  serial port hardware which acts similar to standard serial port
+  hardware. If you only use the standard COM 1/2/3/4 ports, you can
+  say N here to save some memory. You can also say Y if you have an
+  "intelligent" multiport card such as Cyclades, Digiboards, etc.
 
 Support for sharing serial interrupts
 CONFIG_SERIAL_SHARE_IRQ
@@ -996,7 +1051,7 @@
   that implements the TGA interface (much like the VGA standard, but
   older TGA adapters are *not* VGA compatible).  On such systems, you
   should say Y here so that the TGA driver rather than the standard
-  VGA driver is used.
+  VGA driver is used. 
 
 PCI support
 CONFIG_PCI
@@ -1007,6 +1062,7 @@
   via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO,
   contains valuable information about which PCI hardware does work
   under Linux and which doesn't.
+
   If some of your PCI devices don't work and you get a warning during
   boot time ("man dmesg"), please follow the instructions at the top
   of include/linux/pci.h.
@@ -1016,9 +1072,10 @@
   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 this switch is enabled -- for such
-  motherboards, you should say N here and say Y to "PCI direct access
-  support" instead.
+  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.
 
@@ -1047,12 +1104,17 @@
 Backward-compatible /proc/pci
 CONFIG_PCI_OLD_PROC
   Older kernels supported a /proc/pci file containing brief textual
-  description of all PCI devices in the system. Several programs tried
-  to parse this file, so it became almost impossible to add new
+  descriptions of all PCI devices in the system. Several programs
+  tried to parse this file, so it became almost impossible to add new
   fields without breaking compatibility. So a new /proc interface to
-  PCI (/proc/bus/pci) has been implemented and the old one is supported
-  for compatibility reasons only (you can disable it here, gaining
-  some memory).  If unsure, say Y.
+  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.
 
 MCA support
 CONFIG_MCA
@@ -1064,19 +1126,21 @@
 
 System V IPC
 CONFIG_SYSVIPC
-  Inter Process Communication is a suite of library functions and system
-  calls which let processes (= running programs) synchronize and
-  exchange information. It is generally considered to be a good thing,
-  and some programs won't run unless you say Y here. In particular,
-  if you want to run the DOS emulator dosemu under Linux (read the
-  DOSEMU-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO), you'll need to say Y here. You
-  can find documentation about IPC in ipc.info, which is contained in
-  sunsite.unc.edu:/pub/Linux/docs/man/info.tar.gz (extract with "tar
-  xzvf filename"). These docs are in the info format which is used to
-  document GNU software and can be read from within emacs ("Ctrl-h i")
-  or with the program info ("man info"). Saying Y here enlarges
-  your kernel by about 7kB. Just say Y.
+  Inter Process Communication is a suite of library functions and
+  system calls which let processes (= running programs) synchronize
+  and exchange information. It is generally considered to be a good
+  thing, and some programs won't run unless you say Y here. In
+  particular, if you want to run the DOS emulator dosemu under Linux
+  (read the DOSEMU-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO), you'll need to say Y
+  here.
+  
+  You can find documentation about IPC with "info ipc" and also in
+  section 6.4 of the Linux Programmer's Guide, available via ftp
+  (user: anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide.
+
+  Saying Y here enlarges your kernel by about 7kB. Just say Y.
 
 BSD Process Accounting
 CONFIG_BSD_PROCESS_ACCT
@@ -1100,33 +1164,36 @@
   beneath the /proc/sys directory. They are explained in the files in
   Documentation/sysctl/. Note that enabling this option will enlarge
   the kernel by at least 8kB. As it is generally a good thing, you
-  probably want to say Y here unless building a kernel for
-  install/rescue disks or your system is very limited in memory.
+  should say Y here unless building a kernel for install/rescue disks
+  or your system is very limited in memory.
 
 Kernel support for ELF binaries
 CONFIG_BINFMT_ELF
   ELF (Executable and Linkable Format) is a format for libraries and
   executables used across different architectures and operating
-  systems. This option will enable your kernel to run ELF binaries and
+  systems. Saying Y here will enable your kernel to run ELF binaries and
   enlarge it by about 2kB. ELF support under Linux has now all but
   replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
   because it is portable (this does *not* mean that you will be able
   to run executables from different architectures or operating
   systems!) and makes building run-time libraries very easy. Many new
   executables are distributed solely in ELF format. You definitely
-  want to say Y here. Information about ELF is on the WWW at
+  want to say Y here. 
+
+  Information about ELF is on the WWW at
   http://www.sjc.ox.ac.uk/users/barlow/elf-howto.html (To browse the
   WWW, you need to have access to a machine on the Internet that has a
-  program like lynx or netscape).  If you find that after upgrading
+  program like lynx or netscape). If you find that after upgrading
   from Linux kernel 1.2 and saying Y here, you still can't run any ELF
   binaries (they just crash), then you'll have to install the newest
   ELF runtime libraries, including ld.so (check the file
-  Documentation/Changes for location and latest version). 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
-  binfmt_elf.o. Saying M or N here is dangerous because some crucial
-  programs on your system might be in ELF format.
+  Documentation/Changes for location and latest version).
+
+  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 binfmt_elf.o. Saying M or N here is dangerous because some
+  crucial programs on your system might be in ELF format.
 
 Kernel support for A.OUT binaries
 CONFIG_BINFMT_AOUT
@@ -1134,6 +1201,7 @@
   executables used in the earliest versions of UNIX. Linux used the
   a.out formats QMAGIC and ZMAGIC until they were replaced with the
   ELF format.
+
   As more and more programs are converted to ELF, the use for a.out
   will gradually diminish. If you disable this option it will reduce
   your kernel by one page. This is not much and by itself does not
@@ -1153,13 +1221,16 @@
   JAVA(tm) is an object oriented programming language developed by
   SUN; JAVA programs are compiled into "JAVA bytecode" binaries which
   can then be interpreted by run time systems on many different
-  operating systems.  These JAVA binaries are becoming a universal
-  executable format. If you want to execute JAVA binaries, read the
-  Java on Linux HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. You will then need to install
-  the run time system contained in the Java Developers Kit (JDK) as
-  described in the HOWTO. This is completely independent of the Linux
-  kernel and you do NOT need to say Y here for this to work.
+  architectures and operating systems. These JAVA binaries are
+  becoming a universal executable format.
+
+  If you want to execute JAVA binaries, read the Java on Linux HOWTO,
+  available via ftp (user: anonymous) at
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You will then need to
+  install the run time system contained in the Java Developers Kit
+  (JDK) as described in the HOWTO. This is completely independent of
+  the Linux kernel and you do NOT need to say Y here for this to work.
+
   Saying Y here allows you to execute a JAVA bytecode binary just like
   any other Linux program: by simply typing in its name. (You also
   need to have the JDK installed for this to work).  As more and more
@@ -1167,13 +1238,16 @@
   increase. You can even execute HTML files containing JAVA applets (=
   JAVA binaries) if those files start with the string
   "<!--applet-->". If you want to use this, say Y here and read
-  Documentation/java.txt. If you disable this option it will reduce
-  your kernel by about 4kB. This is not much and by itself does not
-  warrant removing support. However its removal is a good idea if you
-  do not have the JDK installed. You may answer M for module support
-  and later load the module when you install the JDK or find an
-  interesting Java program that you can't live without. The module
-  will be called binfmt_java.o. 
+  Documentation/java.txt. 
+
+  If you disable this option it will reduce your kernel by about 4kB.
+  This is not much and by itself does not warrant removing support.
+  However its removal is a good idea if you do not have the JDK
+  installed. You may answer M for module support and later load the
+  module when you install the JDK or find an interesting Java program
+  that you can't live without. The module will be called
+  binfmt_java.o.
+
   The complete functionality of this Java support is also provided by
   the more general option "Kernel support for MISC binaries",
   below. This option is therefore considered obsolete and you should
@@ -1193,31 +1267,36 @@
 CONFIG_BINFMT_MISC
   This enables the possibility to plug wrapper-driven binary formats
   into the kernel. You will like this especially when you use programs
-  that need an interpreter to run like Java, Python or
-  Emacs-Lisp. Once you have registered such a binary class with the
-  kernel, you can start such a program simply by typing in its name;
-  Linux will feed it to the correct interpreter. If you say Y here,
-  you won't need "Kernel support for JAVA binaries"
+  that need an interpreter to run like Java, Python or Emacs-Lisp.
+  Once you have registered such a binary class with the kernel, you
+  can start such a program simply by typing in its name; Linux will
+  feed it to the correct interpreter.
+
+  If you say Y here, you won't need "Kernel support for JAVA binaries"
   (CONFIG_BINFMT_JAVA) or "Kernel support for Linux/Intel ELF
   binaries" (CONFIG_BINFMT_EM86), as this is a more general solution.
+
   You can do other nice things, too. Read
   Documentation/binfmt_misc.txt to learn how to use this feature, and
   Documentation/java.txt for information about how to include Java
-  support. 
+  support.
+
   You must enable the "proc filesystem support" (CONFIG_PROC_FS) to
   use this part of the kernel.
+
   You may answer M for module support and later load the module when
-  you have use for it; the module is called binfmt_misc.o.  
-  If you don't know what to answer at this point, say Y.
+  you have use for it; the module is called binfmt_misc.o. If you
+  don't know what to answer at this point, say Y.
 
 Solaris binary emulation
 CONFIG_SOLARIS_EMUL
   This is experimental code which will enable you to run (many)
-  Solaris binaries on your Sparc Linux machine.  This code 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 solaris.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  Solaris binaries on your Sparc Linux machine.  
+
+  This code 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 solaris.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Processor family
 CONFIG_M386
@@ -1229,6 +1308,7 @@
   (=586) and Pentium Pro (=686). In rare cases, it can make sense to
   specify "Pentium" even if running on a 486: the kernel will be
   smaller but slower. 
+
   If you have a single processor machine, make sure that the line
   "SMP=1" at the top of the toplevel kernel Makefile is commented out;
   if you have a multi processor machine and want Linux to use all the
@@ -1239,10 +1319,14 @@
   need to have access to a machine on the Internet that has a program
   like lynx or netscape). People using multiprocessor machines should
   also say Y to "Enhanced Real Time Clock Support", below.
+
   If you want to compile a kernel that should work on both single
-  processor and multi processor machines, it is possible to set
-  SMP=1. The "Advance Power Management" code (see configuration option
-  below) will not work in that scenario, though.
+  processor and multi processor machines, it is possible to set SMP=1.
+  The "Advanced Power Management" code (see configuration option
+  below) will not work in that scenario, though. In addition, the
+  kernel will be slower on single processor machines, and other
+  problems may appear, so this is not recommended.
+
   If you don't know what to do, choose "386".
 
 Video mode selection support
@@ -1256,30 +1340,34 @@
   "man bootparam" or see the documentation of your boot loader about
   how to pass options to the kernel. The lilo procedure is also
   explained in the SCSI-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  Read Documentation/svga.txt
-  for more information about the Video mode selection support. If
-  unsure, say N.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Read
+  Documentation/svga.txt for more information about the Video mode
+  selection support. If unsure, say N.
 
 Parallel-port support
 CONFIG_PARPORT
-  If you want to use devices connected to your parallel port (the
-  connector at the computer with 25 holes), e.g. printer, Zip drive,
-  PLIP link (Parallel Line Internet Protocol is mainly used to create
-  a mini network by connecting the parallel ports of two local
+  If you want to use devices connected to your machine's parallel port
+  (the connector at the computer with 25 holes), e.g. printer, Zip
+  drive, PLIP link (Parallel Line Internet Protocol is mainly used to
+  create a mini network by connecting the parallel ports of two local
   machines) etc., then you need to say Y here; please read
-  Documentation/parport.txt and drivers/misc/BUGS-parport. For
-  extensive information about drivers for many devices attaching to
-  the parallel port see http://www.torque.net/linux-pp.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). It is possible
-  to share a single parallel port among several devices and it is safe
-  to compile all the corresponding drivers into the kernel. If you
-  want to compile parallel port support 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 parport.o. If you have more than one parallel port
-  and want to specify which port and IRQ to be used by this driver at
-  module load time, read Documentation/networking/net-modules.txt.
+  Documentation/parport.txt and drivers/misc/BUGS-parport.
+
+  For extensive information about drivers for many devices attaching
+  to the parallel port see http://www.torque.net/linux-pp.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).
+
+  It is possible to share a single parallel port among several devices
+  and it is safe to compile all the corresponding drivers into the
+  kernel. If you want to compile parallel port support 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 parport.o. If you have more than one
+  parallel port and want to specify which port and IRQ to be used by
+  this driver at module load time, read
+  Documentation/networking/net-modules.txt.
+
   If unsure, say Y.
 
 PC-style hardware 
@@ -1329,10 +1417,11 @@
   inserted in or removed from the running kernel, using the programs
   insmod and rmmod. This is described in the file
   Documentation/modules.txt, including the fact that you have to say
-  "make modules" in order to compile the modules. Modules can be
-  device drivers, file systems, binary executable formats, and so
-  on. If you think that you may want to make use of modules with this
-  kernel in the future, then say Y here. If unsure, say Y.
+  "make modules" in order to compile the modules that you chose during
+  kernel configuration. Modules can be device drivers, file systems,
+  binary executable formats, and so on. If you think that you may want
+  to make use of modules with this kernel in the future, then say Y
+  here. If unsure, say Y.
 
 Set version information on all symbols for modules
 CONFIG_MODVERSIONS
@@ -1354,7 +1443,7 @@
   be created as loadable modules, you also have the responsibility to
   load the corresponding modules (using the programs insmod or
   modprobe) before you can use them. If you say Y here however, the
-  kernel will be able to load modules for itself. When a part of the
+  kernel will be able to load modules for itself: when a part of the
   kernel needs a module, it runs modprobe with the appropriate
   arguments. (This is a replacement for kerneld.) Say Y here and read
   about configuring it in Documentation/kmod.txt.
@@ -1369,14 +1458,18 @@
   resolution (ARP) cache inside the kernel works well.  However,
   maintaining an internal ARP cache does not work well for very large
   switched networks, and will use a lot of kernel memory if TCP/IP
-  connections are made to many machines on the network.  By saying Y
-  here, the kernel's internal ARP cache will never grow to more than
-  256 entries (the oldest entries are expired in a LIFO manner) and
-  communication will be attempted with an external ARP daemon, arpd.
-  This code is still experimental.  If you do say Y here, you should
-  obtain a copy of arpd from http://www.loran.com/~layes/arpd/index.html, 
-  and you should say Y to "Kernel/User network link driver", below.
-  If unsure, say N.
+  connections are made to many machines on the network.  
+
+  If you say Y here, the kernel's internal ARP cache will never grow
+  to more than 256 entries (the oldest entries are expired in a LIFO
+  manner) and communication will be attempted with the user space ARP
+  daemon arpd. Arpd then answers the address resolution request either
+  from its own cache or by asking the net.
+
+  This code is still experimental. If you do say Y here, you should
+  obtain a copy of arpd from
+  http://www.loran.com/~layes/arpd/index.html, and you should also say
+  Y to "Kernel/User network link driver", below. If unsure, say N.
 
 TCP/IP networking
 CONFIG_INET
@@ -1390,6 +1483,13 @@
   program which gives you almost full Internet connectivity if you
   have a regular dial up shell account on some Internet connected Unix
   computer. Read http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html).
+  
+  If you say Y here and also to "/proc filesystem support" and "Sysctl
+  support" below, you can change various aspects of the behavior of
+  the TCP/IP code by writing to the (virtual) files in
+  /proc/sys/net/ipv4/*; the options are explained in the file
+  Documentation/Networking/ip-sysctl.txt.
+
   Short answer: say Y.
 
 IP: multicasting
@@ -1412,14 +1512,19 @@
   computer that forwards and redistributes network packets, say Y; you
   will then be presented with several options that allow more precise
   control about the routing process.
+
   The answer to this question won't directly affect the kernel: saying
   N will just cause this configure script to skip all the questions
   about advanced routing.
-  Note that your box can only act as a router if you say Y to "/proc
-  filesystem support" below and if you enable IP forwarding in your
-  kernel; you can do this from within a boot-time script like so:
-    echo "1" > /proc/sys/net/ipv4/ip_forwarding
-  after the /proc filesystem has been mounted.  
+
+  Note that your box can only act as a router if you enable IP
+  forwarding in your kernel; you can do that by saying Y to "/proc
+  filesystem support" and "Sysctl support" below and executing the line
+
+    echo "1" > /proc/sys/net/ipv4/ip_forward
+
+  at boot time after the /proc filesystem has been mounted.  
+
   If unsure, say N here.
 
 IP: policy routing
@@ -1470,50 +1575,62 @@
 IP: optimize as router not host
 CONFIG_IP_ROUTER
   Some Linux network drivers use a technique called copy and checksum
-  to optimize host performance. For a machine which acts a router most
-  of the time and is forwarding most packets to another host this is
-  however a loss. If you say Y here, copy and checksum will be
+  to optimize host performance. For a machine which acts as a router
+  most of the time and is forwarding most packets to another host this
+  is however a loss. If you say Y here, copy and checksum will be
   switched off. In the future, it may make other changes which
   optimize for router operation.
-  Note that your box can only act as a router if you say Y to "/proc
-  filesystem support" below and if you enable IP forwarding in your
-  kernel; you can do this from within a boot-time script like so:
-    echo "1" > /proc/sys/net/ipv4/ip_forwarding
-  after the /proc filesystem has been mounted.  If unsure, say N here.
+
+  Note that your box can only act as a router if you enable IP
+  forwarding in your kernel; you can do that by saying Y to "/proc
+  filesystem support" and "Sysctl support" below and executing the line
+
+    echo "1" > /proc/sys/net/ipv4/ip_forward
+
+  at boot time after the /proc filesystem has been mounted.  
+
+  If unsure, say N here.
 
 IP: firewalling
 CONFIG_IP_FIREWALL
-  If you want to configure your Linux box as a firewall for a local
-  TCP/IP based network, say Y here. This will enlarge your kernel by
-  about 2kB. You may need to read the FIREWALL-HOWTO, available via
-  ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Also, you will need the
-  ipfwadm tool (available via ftp (user: anonymous) from
-  ftp.xos.nl/pub/linux/ipfwadm/) to allow selective blocking of
-  Internet traffic based on type, origin and destination; this type of
-  firewall is called a "packet filter".  The other type of firewall,
-  "proxy-based" ones, is more secure but more intrusive and more
-  bothersome to set up; it inspects the network traffic much more
-  closely and has knowledge about the higher level protocols, which
-  packet filters lack. Proxy-based firewalls don't need support by the
-  kernel, but they are often combined with a packet filter, which only
-  works if you say Y here.
-  The firewalling code will only work if you say Y to "/proc
-  filesystem support" below and IP forwarding is enabled in your
-  kernel; do this from within a boot-time script like so:
-    echo "1" > /proc/sys/net/ipv4/ip_forwarding
-  after the /proc filesystem has been mounted.  
+  If you want to configure your Linux box as a packet filter firewall
+  for a local TCP/IP based network, say Y here. This will enlarge your
+  kernel by about 2kB. You may need to read the FIREWALL-HOWTO,
+  available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  Also, you will need the ipfwadm tool (available via ftp (user:
+  anonymous) from ftp://ftp.xos.nl/pub/linux/ipfwadm/) to allow selective
+  blocking of Internet traffic based on type, origin and destination;
+  this type of firewall is called a "packet filter". The other type of
+  firewall, "proxy-based" ones, is more secure but more intrusive and
+  more bothersome to set up; it inspects the network traffic much more
+  closely, modifies it and has knowledge about the higher level
+  protocols, which a packet filter lacks. Moreover, proxy-based
+  firewalls often require changes to the programs running on the local
+  clients. Proxy-based firewalls don't need support by the kernel, but
+  they are often combined with a packet filter, which only works if
+  you say Y here.
+
+  The firewalling code will only work if IP forwarding is enabled in
+  your kernel. You can do that by saying Y to "/proc filesystem
+  support" and "Sysctl support" below and executing the line
+
+    echo "1" > /proc/sys/net/ipv4/ip_forward
+
+  at boot time after the /proc filesystem has been mounted.  
+
   You need to say Y to "IP firewalling" in order to be able to use IP
   masquerading (masquerading means that local computers can chat with
   an outside host, but that outside host is made to think that it is
   talking to the firewall box -- makes the local network completely
-  invisible and avoids the need to allocate valid IP host addresses
-  for the machines on the local net) and IP packet accounting (keeping
-  track of what is using all your network bandwidth) and IP
-  transparent proxying (makes the computers on the local network think
-  they're talking to a remote computer, while in reality the traffic
-  is redirected by your Linux firewall to a local proxy server). If
-  unsure, say N.
+  invisible to the outside world and avoids the need to allocate
+  globally valid IP host addresses for the machines on the local net)
+  and IP packet accounting (keeping track of what is using all your
+  network bandwidth) and IP transparent proxying (makes the computers
+  on the local network think they're talking to a remote computer,
+  while in reality the traffic is redirected by your Linux firewall to
+  a local proxy server).
 
 IP: firewall packet netlink device
 CONFIG_IP_FIREWALL_NETLINK
@@ -1535,7 +1652,7 @@
   /proc/net/ip_acct", so you want to say Y to the /proc filesystem
   below, if you say Y here. To specify what exactly should be
   recorded, you need the tool ipfwadm (available via ftp (user:
-  anonymous) from ftp.xos.nl/pub/linux/ipfwadm/).
+  anonymous) from ftp://ftp.xos.nl/pub/linux/ipfwadm/).
 
 IP: kernel level autoconfiguration
 CONFIG_IP_PNP
@@ -1580,10 +1697,11 @@
   appear on a different network than it physically is, or to use
   mobile-IP facilities (allowing laptops to seamlessly move between
   networks without changing their IP addresses; check out
-  http://anchor.cs.binghamton.edu/~mobileip/LJ/index.html). Saying Y
-  to this option will produce two modules ( = code which can be
-  inserted in and removed from the running kernel whenever you want),
-  one encapsulator called tunnel.o and one decapsulator called
+  http://anchor.cs.binghamton.edu/~mobileip/LJ/index.html). 
+
+  Saying Y to this option will produce two modules ( = code which can
+  be inserted in and removed from the running kernel whenever you
+  want), one encapsulator called tunnel.o and one decapsulator called
   ipip.o. You can read details in drivers/net/README.tunnel. Most
   people won't need this and can say N.
 
@@ -1640,20 +1758,29 @@
   Linux box to the Internet using SLiRP [SLiRP is a SLIP/PPP emulator
   that works if you have a regular dial up shell account on some UNIX
   computer; get it via ftp (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/serial/].) The IP
-  masquerading code will only work if you say Y to "/proc filesystem
-  support" below and IP forwarding is enabled in your kernel; you can
-  do this from within a boot-time script like so: echo "1" >
-  /proc/sys/net/ipv4/ip_forwarding after the /proc filesystem has been
-  mounted. Details on how to set things up are contained in the IP
-  Masquerade mini-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. If you say Y here, then
-  the modules ip_masq_ftp.o (for ftp transfers through the firewall),
-  ip_masq_irc.o (for irc chats through the firewall), and
-  ip_masq_raudio.o (for realaudio downloads through the firewall) will
-  automatically be compiled. Modules are pieces of code which can be
-  inserted in and removed from the running kernel whenever you want;
-  read Documentation/modules.txt for details.
+  ftp://sunsite.unc.edu/pub/Linux/system/network/serial/ ].) 
+
+  The IP masquerading code will only work if IP forwarding is enabled
+  in your kernel; you can do this by saying Y to "/proc
+  filesystem support" and "Sysctl support" below and then executing a
+  line like
+
+    echo "1" > /proc/sys/net/ipv4/ip_forward
+
+  from a boot time script after the /proc filesystem has been mounted. 
+
+  Details on how to set things up are contained in the IP Masquerade
+  mini-HOWTO, available via ftp (user: anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini.
+
+  If you say Y here, you should also say Y to "IP: always defragment",
+  below. If you say Y here, then the modules ip_masq_ftp.o (for ftp
+  transfers through the firewall), ip_masq_irc.o (for irc chats
+  through the firewall), and ip_masq_raudio.o (for realaudio downloads
+  through the firewall) will automatically be compiled. Modules are
+  pieces of code which can be inserted in and removed from the running
+  kernel whenever you want; read Documentation/modules.txt for
+  details.
 
 IP: ICMP masquerading
 CONFIG_IP_MASQUERADE_ICMP
@@ -1662,22 +1789,24 @@
   connections).  This option adds additional support for masquerading
   ICMP packets, such as ping or the probes used by the Windows 95
   tracert program.
+
   If you want this, say Y. 
 
-IP: ipautofw masquerade support
-CONFIG_IP_MASQUERADE_IPAUTOFW (Experimental)
+IP: ipautofw masquerade support (Experimental)
+CONFIG_IP_MASQUERADE_IPAUTOFW
   ipautofw is a program by Richard Lynch allowing additional support
   for masquerading protocols which do not (as yet) have their own
-  additional protocol helpers.  Information and source for ipautofw is
-  available via ftp (user: anonymous) from
+  protocol helpers. Information and source for ipautofw is available
+  via ftp (user: anonymous) from
   ftp://ftp.netis.com/pub/members/rlynch/
+
   The ipautofw code is still under development and so is currently
-  marked EXPERIMENTAL.
-  If you want this, 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). The module will be called ip_masq_autofw.o. If
-  you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  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).
+  The module will be called ip_masq_autofw.o. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt.
 
 IP: ipportfw masquerade support
 CONFIG_IP_MASQUERADE_IPPORTFW
@@ -1688,32 +1817,34 @@
   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).
+
   The portfw code is still under development and so is currently
-  marked EXPERIMENTAL.
-  If you want this, 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). The module will be called ip_masq_portfw.o. If
-  you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  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).
+  The module will be called ip_masq_portfw.o. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt.
 
 IP: always defragment 
 CONFIG_IP_ALWAYS_DEFRAG
   This option means that all incoming fragments (= parts of IP packets
   that arose when some host between origin and destination decided
-  that the IP packets were too large and cut them in pieces) will be
+  that the IP packets were too large and cut them into pieces) will be
   reassembled (defragmented) before being processed, even if they are
-  about to be forwarded.  This option is highly recommended if you
-  have said Y to "IP: masquerading" because that facility requires
-  that second and further fragments can be related to TCP or UDP port
-  numbers, which are only stored in the first fragment.  When using
-  "IP: firewalling" support , you might also want to say Y here, to
-  have a more reliable firewall (otherwise second and further
-  fragments will always be accepted by the firewall).  When using "IP:
-  transparent proxying", this option is implicit, although it is safe
-  to say Y here. Do not say Y to this option except when running
-  either a firewall that is the sole link to your network or a
-  transparent proxy. Never ever say Y to this for a normal router or
-  host.
+  about to be forwarded.  
+
+  This option is highly recommended if you have said Y to "IP:
+  masquerading" because that facility requires that second and further
+  fragments can be related to TCP or UDP port numbers, which are only
+  stored in the first fragment. When using "IP: firewalling" support ,
+  you might also want to say Y here, to have a more reliable firewall
+  (otherwise second and further fragments will always be accepted by
+  the firewall). When using "IP: transparent proxying", this option is
+  implicit, although it is safe to say Y here. Do not say Y to this
+  option except when running either a firewall that is the sole link
+  to your network or a transparent proxy. Never ever say Y to this for
+  a normal router or host.
 
 IP: aliasing support
 CONFIG_IP_ALIAS
@@ -1727,13 +1858,17 @@
   WWW, you need to have access to a machine on the Internet that has a
   program like lynx or netscape) and also in the
   Virtual-Hosting-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Another scenario would be
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+
+  Another scenario would be
   that there are two logical networks living on your local Ethernet
-  and you want to access them both with the same Ethernet card. The
-  configuration of these alias addresses is done with a special name
-  syntax explained in Documentation/networking/alias.txt and in the
-  IP-Alias mini-HOWTO. If you want this, say Y. Most people don't need
-  it and say N.
+  and you want to access them both with the same Ethernet card. This
+  can be done if you say Y here.
+
+  The configuration of these alias addresses is done with a special
+  name syntax explained in Documentation/networking/alias.txt and in
+  the IP-Alias mini-HOWTO. If you want this, say Y. Most people don't
+  need it and say N.
 
 IP: multicast routing
 CONFIG_IP_MROUTE
@@ -1772,28 +1907,35 @@
   here.  Everyone else says N. People having problems with NCSA telnet
   should see the file linux/Documentation/networking/ncsa-telnet.
 
-Reverse ARP
+Reverse ARP server
 CONFIG_INET_RARP
-  Since you asked: if there are (usually diskless or portable)
-  machines on your local network that know their hardware Ethernet
-  addresses but don't know their IP addresses upon startup, they can
-  send out a Reverse Address Resolution Protocol (RARP) request to
-  find out their own IP addresses. Diskless Sun 3 machines use this
-  procedure at boot time. If you want your Linux box to be able to
-  *answer* such requests, say Y here; you'd have to run the program
-  rarp ("man rarp") on your box. If you actually want to use a
-  diskless Sun 3 machine as an Xterminal to Linux, say Y here and
-  fetch Linux-Xkernel from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/boot.net/.  Superior
-  solutions to the problem of booting and configuring machines over a
-  net connection are given by the protocol BOOTP and its successor
-  DHCP. See the DHCP FAQ
+  If there are (usually diskless or portable) machines on your local
+  network that know their hardware Ethernet addresses but don't know
+  their IP addresses upon startup, they can send out a Reverse Address
+  Resolution Protocol (RARP) request to find out their own IP
+  addresses. Diskless Sun 3 machines use this procedure at boot time,
+  and diskless Linux boxes can be configured to do it as well.
+  
+  If you want your Linux box to be able to *answer* such requests, say
+  Y here; you'll then have to run the program rarp ("man rarp") on
+  your box.
+
+  If you actually want to use a diskless Sun 3 machine as an Xterminal
+  to Linux, say Y here and fetch Linux-Xkernel from
+  ftp://sunsite.unc.edu/pub/Linux/system/network/boot.net/.
+
+  Superior solutions to the problem of booting and configuring
+  machines over a net connection are given by the protocol BOOTP and
+  its successor DHCP. See the DHCP FAQ
   http://web.syr.edu/~jmwobus/comfaqs/dhcp.faq.html 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).  If you want to compile
-  RARP support 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 rarp.o.
+  that has a program like lynx or netscape).
+
+  If you want to compile RARP support 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 rarp.o. 
+
   If you don't understand a word of the above, say N and rest in
   peace.
 
@@ -1805,20 +1947,6 @@
   links, between machines of your IP network, say N.  If in doubt, say
   N. The PATH mtu discovery facility will cover most cases anyway.
 
-Disable Path MTU Discovery (normally enabled)
-CONFIG_NO_PATH_MTU_DISCOVERY
-  MTU (maximal transfer unit) is the size of the chunks we send out
-  over the net. "Path MTU Discovery" means that, instead of always
-  sending very small chunks, we start out sending big ones and if we
-  then discover that some host along the way likes its chunks smaller,
-  we adjust to a smaller size. This is good, so most people say N
-  here, thereby not disabling it. However, some DOS software (versions
-  of DOS NCSA telnet and Trumpet Winsock in PPP mode) is broken and
-  won't be able to connect to your Linux machine correctly in all
-  cases (especially through a terminal server) unless you say Y
-  here. See Documentation/networking/ncsa-telnet for the location of
-  fixed NCSA telnet clients. If in doubt, say N.
-
 Path MTU Discovery (normally enabled)
 CONFIG_PATH_MTU_DISCOVERY
   MTU (maximal transfer unit) is the size of the chunks we send out
@@ -1826,10 +1954,14 @@
   sending very small chunks, we start out sending big ones and if we
   then discover that some host along the way likes its chunks smaller,
   we adjust to a smaller size. This is good, so most people say
-  Y here. However, some versions of DOS NCSA telnet (and other software)
-  are broken and can only connect to your Linux machine if you say N
-  here. See Documentation/networking/ncsa-telnet for the location
-  of fixed NCSA telnet clients. If in doubt, say Y.
+  Y here. 
+
+  However, some DOS software (versions of DOS NCSA telnet and Trumpet
+  Winsock in PPP mode) is broken and won't be able to connect to your
+  Linux machine correctly in all cases (especially through a terminal
+  server) unless you say N here. See
+  Documentation/networking/ncsa-telnet for the location of fixed NCSA
+  telnet clients. If in doubt, say Y.
 
 Disable NAGLE algorithm (normally enabled)
 CONFIG_TCP_NAGLE_OFF
@@ -1853,7 +1985,7 @@
   problems (and is rarely a useful feature), and hence it is recommended
   that you say Y here unless you really know what you're doing.
 
-IP: Allow large windows (not recommend if <16Mb of memory)
+IP: Allow large windows (not recommended if <16Mb of memory)
 CONFIG_SKB_LARGE
   On high speed, long distance networks the performance limit on 
   networking becomes the amount of data a machine can buffer until the
@@ -1869,14 +2001,16 @@
 Unix domain sockets
 CONFIG_UNIX
   This includes Unix domain sockets, the standard Unix mechanism for
-  establishing and accessing network connections.  Unless you are
-  working on an embedded system or something, you probably want to say
-  Y.  The socket support is also available as a module ( = code which
-  can be inserted in and removed from the running kernel whenever you
+  establishing and accessing network connections. Unless you are
+  working on an embedded system or something, you 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 are running kerneld, be sure
-  to add 'alias net-pf-1 unix' to your /etc/conf.module file.  If
+  to add 'alias net-pf-1 unix' to your /etc/conf.module file. If
   unsure, say Y.
 
 The IPv6 protocol
@@ -1890,62 +2024,84 @@
   browse the WWW, you need to have access to a machine on the Internet
   that has a program like lynx or netscape); for specific information
   about IPv6 under Linux read the HOWTO at http://www.terra.net/ipv6/
-  and the file net/ipv6/README in the kernel source. If you want to
-  use IPv6, please upgrade to the newest net-tools as given in
-  Documentation/Changes. The IPv6 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
-  ipv6.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt.  It's safe to say N for now.
+  and the file net/ipv6/README in the kernel source. 
+
+  If you want to use IPv6, please upgrade to the newest net-tools as
+  given in Documentation/Changes.
+
+  The IPv6 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 ipv6.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt. It's safe to
+  say N for now.
 
 IPv6: enable EUI-64 token format
 CONFIG_IPV6_EUI64
   6bone, the network of computers using the IPv6 protocol, is moving
   to a new aggregatable address format and a new link local address
-  assignment (EUI-64). Say Y, if your site has upgraded already, or
+  assignment (EUI-64). Say Y if your site has upgraded already, or
   has started to upgrade.
 
 IPv6: disable provider based addresses
 CONFIG_IPV6_NO_PB
-  Linux tries to operate correctly when your site is moved to EUI-64
+  Linux tries to operate correctly when your site has moved to EUI-64
   only partially. Unfortunately, the two address formats (old:
-  "provider based" and new: "aggregatable") are incompatible. Say Y,
-  if your site finished the upgrade to EUI-64, and/or you encountered
+  "provider based" and new: "aggregatable") are incompatible. Say Y if
+  your site finished the upgrade to EUI-64, and/or you encountered
   some problems caused by the presence of two link-local addresses on
   an interface.
 
+IPv6: routing messages via old netlink
+CONFIG_IPV6_NETLINK
+  You can say Y here to receive routing messages from the IPv6 code
+  through the old netlink interface. However, a better option is to
+  say Y to "Kernel/User network link driver" and to "Routing
+  messages" instead.
+  
 The IPX protocol
 CONFIG_IPX
   This is support for the Novell networking protocol, IPX, commonly
   used for local networks of Windows machines. You need it if you want
   to access Novell NetWare file or print servers using the Linux
   Novell client ncpfs (available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/system/filesystems/) or from within the
-  Linux DOS emulator dosemu (read the DOSEMU-HOWTO, available in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO). In order to do the former,
-  you'll also have to say Y to "NCP filesystem support", below. To
-  turn your Linux box into a fully featured NetWare file server and
+  ftp://sunsite.unc.edu/pub/Linux/system/filesystems/) or from within
+  the Linux DOS emulator dosemu (read the DOSEMU-HOWTO, available in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO). In order to do the
+  former, you'll also have to say Y to "NCP filesystem support",
+  below.
+
+  IPX is similar in scope to IP, while SPX, which runs on top of IPX,
+  is similar to TCP. There is also experimental support for SPX in
+  Linux (see "SPX networking", below).
+
+  To turn your Linux box into a fully featured NetWare file server and
   IPX router, say Y here and fetch either lwared from
-  sunsite.unc.edu:/pub/Linux/system/network/daemons/ or mars_nwe from
-  ftp.gwdg.de:/pub/linux/misc/ncpfs. For more information, read the
-  IPX-HOWTO in sunsite.unc.edu:/pub/Linux/docs/howto. The IPX driver
-  would enlarge your kernel by about 5 kB. 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 ipx.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.  Unless you want to integrate
+  ftp://sunsite.unc.edu/pub/Linux/system/network/daemons/ or mars_nwe from
+  ftp://ftp.gwdg.de/pub/linux/misc/ncpfs. For more information, read the
+  IPX-HOWTO in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  General information about how to connect Linux, Windows machines and
+  Macs is on the WWW at http://www.eats.com/linux_mac_win.html (to
+  browse the WWW, you need to have access to a machine on the Internet
+  that has a program like lynx or netscape). 
+
+  The IPX driver would enlarge your kernel by about 5 kB. 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 ipx.o. If you want to compile it as a module, say M here
+  and read Documentation/modules.txt. Unless you want to integrate
   your Linux box with a local Novell network, say N.
 
-Full internal IPX network
+IPX: Full internal IPX network
 CONFIG_IPX_INTERN
   Every IPX network has an address that identifies it. Sometimes it is
   useful to give an IPX "network" address to your Linux box as well
   (for example if your box is acting as a fileserver for different IPX
-  networks: it will then be accessible form everywhere using the same
+  networks: it will then be accessible from everywhere using the same
   address).  The way this is done is to create a virtual internal
   "network" inside your box and to assign an IPX address to this
   network. Say Y here if you want to do this; read the IPX-HOWTO at
   sunsite.unc.edu:/pub/Linux/docs/howto for details.  
+
   The full internal IPX network enables you to allocate sockets on
   different virtual nodes of the internal network. This is done by
   evaluating the field sipx_node of the socket address given to the
@@ -1957,58 +2113,72 @@
   'special' sockets to sockets listening on the primary network is
   disabled. This might break existing applications, especially RIP/SAP
   daemons. A RIP/SAP daemon that works well with the full internal net
-  can be found on ftp.gwdg.de:/pub/linux/misc/ncpfs.  If you don't
+  can be found on ftp://ftp.gwdg.de/pub/linux/misc/ncpfs.  If you don't
   know what you are doing, say N.
 
-IPX Type 20 Routing
-CONFIG_IPX_PPROP_ROUTING
-  IPX Type 20 packets are special broadcast messages designed to work
-  across routers.  If you are using an internal network, have multiple
-  interfaces that route IPX, or will want to route IPX connections over
-  ppp to internal networks, setting this will allow the type 20 packets
-  to be propagated to all connected networks.  These packets are used by
-  Novell NETBIOS and the NETBIOS name functions of SMB protocols that
-  work over IPX (e.g. the "Network Neighborhood" on another popular OS
-  cum GUI).  In brief, if your Linux box needs to route IPX packets,
-  this should be set to Y.
+IPX: SPX networking (EXPERIMENTAL)
+CONFIG_SPX
+  The Sequenced Packet eXchange protocol is a transport layer protocol
+  built on top of IPX. It is used in Novell NetWare systems for
+  client-server applications and is similar to TCP (which runs on top
+  of IP).
+
+  Note that Novell NetWare file sharing does not use SPX; it uses a
+  protocol called NCP, for which separate Linux support is available
+  ("NCP filesystem support" below for the client side, and the user
+  space programs lwared or mars_nwe for the server side).
+
+  Say Y here if you have use for SPX; read the IPX-HOWTO at
+  sunsite.unc.edu:/pub/Linux/docs/howto for details.
+
+  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 af_spx.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Appletalk DDP
 CONFIG_ATALK
   Appletalk is the way Apple computers speak to each other on a
-  network. If your linux box is connected to such a network and you
+  network. If your Linux box is connected to such a network and you
   want to join the conversation, say Y. You will need to use the
   netatalk package so that your Linux box can act as a print and file
   server for macs as well as access appletalk printers. Check out
-  http://artoo.hitchcock.org/~flowerpt/projects/linux-netatalk/ on the
-  WWW 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 serial links. Ethertalk and Localtalk are fully 
-  supported by Linux. The NET-2-HOWTO, available via ftp (user: anonymous)
-  in sunsite.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). The module is called appletalk.o. If you want to compile
-  it as a module, say M here and read Documentation/modules.txt. I
-  hear that the GNU boycott of Apple is over, so even politically
-  correct people are allowed to say Y here.
+  http://threepio.hitchcock.org/cgi-bin/faq/netatalk/faq.pl on the WWW
+  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
+  serial links. Ethertalk and Localtalk are fully supported by Linux.
+  The NET-2-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.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
+
+  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 is called appletalk.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt. I hear that
+  the GNU boycott of Apple is over, so even politically correct people
+  are allowed to say Y here.
 
 Appletalk-IP driver support
 CONFIG_IPDDP
   This allows IP networking for users who only have Appletalk
-  networking available.  This feature is experimental. With this
+  networking available. This feature is experimental. With this
   driver, you can either encapsulate IP inside Appletalk (e.g. if your
-  Linux box is stuck on an appletalk only network) or decapsulate
-  (e.g. if you want your Linux box to act as a Internet gateway for a
+  Linux box is stuck on an Appletalk only network) or decapsulate
+  (e.g. if you want your Linux box to act as an Internet gateway for a
   zoo of appletalk connected Macs). You decide which one of the two
   you want in the following two questions; you can say Y to only one
   of them. Please see Documentation/networking/ipddp.txt for more
-  information.  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 is called ipddp.o. If you want to
-  compile it as a module, say M here and read
-  Documentation/modules.txt.
+  information.
+
+  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 is called ipddp.o. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt.
 
 IP to Appletalk-IP Encapsulation support
 CONFIG_IPDDP_ENCAP
@@ -2064,9 +2234,10 @@
   (to browse the WWW, you need to have access to a machine on the
   Internet that has a program like lynx or netscape) and the HAM-HOWTO
   and the AX25-HOWTO, both available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that the answer to this
-  question won't directly affect the kernel: saying N will just cause
-  this configure script to skip all the questions about amateur radio.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that the answer to
+  this question won't directly affect the kernel: saying N will just
+  cause this configure script to skip all the questions about amateur
+  radio.
 
 Amateur Radio AX.25 Level 2
 CONFIG_AX25
@@ -2081,28 +2252,30 @@
   the Gracilis Packetwin or the generic Z8530 driver. Another option
   are the Baycom modem serial and parallel port hacks or the sound card
   modem (supported by their own drivers). If you say Y here, you also
-  have to say Y to one of those drivers. Information about where to
-  get supporting software for Linux amateur radio as well as
-  information about how to configure an AX.25 port is contained in the
-  AX25-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. You might also want to check
-  out the file Documentation/networking/ax25.txt in the kernel
+  have to say Y to one of those drivers. 
+
+  Information about where to get supporting software for Linux amateur
+  radio as well as information about how to configure an AX.25 port is
+  contained in the AX25-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You might also want to
+  check out the file Documentation/networking/ax25.txt in the kernel
   source. More information about digital amateur radio in general is
-  on the WWW at http://www.tapr.org/tapr/html/pkthome.html.  (To
-  browse the WWW, you need to have access to a machine on the Internet
-  that has a program like lynx or netscape).  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 ax25.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt.
+  on the WWW at http://www.tapr.org/tapr/html/pkthome.html. (To browse
+  the WWW, you need to have access to a machine on the Internet that
+  has a program like lynx or netscape).
+
+  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 ax25.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 AX.25 DAMA Slave support
 CONFIG_AX25_DAMA_SLAVE
   DAMA is a mechanism to prevent collisions when doing AX.25
   networking. A DAMA server (called "master") accepts incoming traffic
-  from clients (called "slaves") and redistributes it to other
-  slaves. If you say Y here, your Linux box will act as a DAMA slave;
-  this is transparent in that you don't have to do any special DAMA
+  from clients (called "slaves") and redistributes it to other slaves.
+  If you say Y here, your Linux box will act as a DAMA slave; this is
+  transparent in that you don't have to do any special DAMA
   configuration. (Linux cannot yet act as a DAMA server.) If unsure,
   say N.
 
@@ -2117,46 +2290,289 @@
 Amateur Radio NET/ROM
 CONFIG_NETROM
   NET/ROM is a network layer protocol on top of AX.25 useful for
-  routing.  A comprehensive listing of all the software for Linux
-  amateur radio users as well as information about how to configure an
-  AX.25 port is contained in the AX25-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. You also might
-  want to check out the file Documentation/networking/ax25.txt. More
+  routing.
+
+  A comprehensive listing of all the software for Linux amateur radio
+  users as well as information about how to configure an AX.25 port is
+  contained in the AX25-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You also might want to
+  check out the file Documentation/networking/ax25.txt. More
   information about digital amateur radio in general is on the WWW at
   http://www.tapr.org/tapr/html/pkthome.html (To browse the WWW, you
   need to have access to a machine on the Internet that has a program
-  like lynx or netscape).  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 netrom.o. If you want
-  to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  like lynx or netscape).
 
-AX.25 over Ethernet
-CONFIG_BPQETHER
-  AX.25 is the protocol used for computer communication over amateur
-  radio. If you say Y here, you will be able to send and receive AX.25
-  traffic over Ethernet (also called "BPQ AX.25"), which could be
-  useful if some other computer on your local network has a direct
-  amateur radio connection.
+  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 netrom.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Amateur Radio X.25 PLP (Rose)
 CONFIG_ROSE
   The Packet Layer Protocol (PLP) is a way to route packets over X.25
   connections in general and amateur radio AX.25 connections in
-  particular, essentially an alternative to NET/ROM.  A comprehensive
-  listing of all the software for Linux amateur radio users as well as
-  information about how to configure an AX.25 port is contained in the
-  AX25-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. You also might want to check
+  particular, essentially an alternative to NET/ROM.
+
+  A comprehensive listing of all the software for Linux amateur radio
+  users as well as information about how to configure an AX.25 port is
+  contained in the AX25-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You also might want to check
   out the file Documentation/networking/ax25.txt. More information
   about digital amateur radio in general is on the WWW at
   http://www.tapr.org/tapr/html/pkthome.html (To browse the WWW, you
   need to have access to a machine on the Internet that has a program
-  like lynx or netscape).  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 rose.o. If you want to
-  compile it as a module, say M here and read
-  Documentation/modules.txt.
+  like lynx or netscape).
+
+  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 rose.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
+Serial port KISS driver for AX.25
+CONFIG_MKISS
+  KISS is a protocol used to send IP traffic over AX.25 radio
+  connections, somewhat similar to SLIP for telephone lines. Say Y
+  here if you intend to send Internet traffic over amateur radio,
+  using some device connected to your machine's serial port. In that
+  case, you also have to say Y to "Amateur Radio AX.25 Level 2"
+  support.  
+
+  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 mkiss.o.
+
+Serial port 6PACK driver for AX.25
+CONFIG_6PACK
+  6pack is a transmission protocol for the data exchange between your
+  PC and your TNC (the Terminal Node Controller acts as a kind of
+  modem connecting your computer's serial port to your radio's
+  microphone input and speaker output). This protocol can be used as
+  an alternative to KISS for networking over AX.25 amateur radio
+  connections, but it has some extended functionality.
+
+  Note that this driver is still experimental and might cause
+  problems. For details about the features and the usage of the
+  driver, read Documentation/networking/6pack.txt.
+
+  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 6pack.o.
+
+BPQ Ethernet driver
+CONFIG_BPQETHER
+  AX.25 is the protocol used for computer communication over amateur
+  radio. If you say Y here, you will be able to send and receive AX.25
+  traffic over Ethernet (also called "BPQ AX.25"), which could be
+  useful if some other computer on your local network has a direct
+  amateur radio connection.
+
+High-speed (DMA) SCC driver for AX.25
+CONFIG_DMASCC
+  This is a driver for high-speed SCC boards (used to connect your
+  computer to your amateur radio and send Internet traffic over the
+  radio), i.e. those supporting DMA on one port. Currently, only
+  Ottawa PI/PI2 boards (see http://hydra.carleton.ca/info/pi2.html)
+  and Gracilis PackeTwin boards (see http://www.paccomm.com/; to
+  browse the WWW, you need to have access to a machine on the Internet
+  that has a program like lynx or netscape) are supported and detected
+  automatically.
+
+  If you have one of these cards, you can say Y here and should read
+  the HAM-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  This driver operates multiple boards simultaneously. If you compile
+  this driver as a module, it will be called dmascc.o. If you don't
+  give any parameter to the driver, all possible I/O addresses are
+  probed. This could irritate other devices that are currently not in
+  use. You may specify the list of addresses to be probed by
+  "dmascc=addr1,addr2,..." (when compiled into the kernel image) or
+  "io=addr1,addr2,..." (when loaded as a module). The network
+  interfaces will be called dmascc0 and dmascc1 for the board detected
+  first, dmascc2 and dmascc3 for the second one, and so on. Before you
+  configure each interface with ifconfig, you MUST set certain
+  parameters, such as channel access timing, clock mode, and DMA
+  channel. This is accomplished with a small utility program called
+  dmascc_cfg, which is part of the ax25-utils package. Alternatively,
+  you may download the utility from
+  http://www.oevsv.at/~oe1kib/Linux.html.
+
+Z8530 SCC driver for AX.25
+CONFIG_SCC
+  These cards are used to connect your Linux box to an amateur radio
+  in order to communicate with other computers.  If you want to use
+  this, read Documentation/networking/z8530drv.txt and the
+  AX.25-HOWTO, available via ftp (user: anonymous) at
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  Also make sure to say Y to
+  "Amateur Radio AX.25 Level 2" support. 
+
+  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 scc.o.
+
+additional delay for PA0HZP OptoSCC compatible boards
+CONFIG_SCC_DELAY
+  Say Y here if you experience problems with the SCC driver not
+  working properly; please read Documentation/networking/z8530drv.txt
+  for details. If unsure, say N.
+
+#support for TRX that feedback the tx signal to rx
+#CONFIG_SCC_TRXECHO
+###
+### Don't know what's going on here.
+###
+#
+BAYCOM picpar and par96 driver for AX.25
+CONFIG_BAYCOM_PAR
+  This is a driver for Baycom style simple amateur radio modems that
+  connect to a parallel interface. The driver supports the picpar and
+  par96 designs. To configure the driver, use the sethdlc utility
+  available in the standard ax25 utilities package. For information on
+  the modems, see http://www.baycom.de (to browse the WWW, you need to
+  have access to a machine on the Internet that has a program like
+  lynx or netscape) and Documentation/networking/baycom.txt. 
+
+  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 baycom_par.o.
+
+BAYCOM ser12 full duplex driver for AX.25
+CONFIG_BAYCOM_SER_FDX
+  This is one of two drivers for Baycom style simple amateur radio
+  modems that connect to a serial interface. The driver supports the
+  ser12 design in full duplex mode. In addition, it allows the
+  baudrate to be set between 300 and 4800 baud (however not all modems
+  support all baudrates). This is the preferred driver. The next
+  driver, "BAYCOM ser12 half duplex driver for AX.25" is the old
+  driver and still provided in case this driver does not work with
+  your serial interface chip. To configure the driver, use the sethdlc
+  utility available in the standard ax25 utilities package.  For
+  information on the modems, see http://www.baycom.de (to browse the
+  WWW, you need to have access to a machine on the Internet that has a
+  program like lynx or netscape) and
+  Documentation/networking/baycom.txt. 
+
+  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 baycom_ser_fdx.o.
+
+BAYCOM ser12 half duplex driver for AX.25
+CONFIG_BAYCOM_SER_HDX
+  This is one of two drivers for Baycom style simple amateur radio
+  modems that connect to a serial interface. The driver supports the
+  ser12 design in full duplex mode. This is the old driver.  It is
+  still provided in case your serial interface chip does not work with
+  the full duplex driver. This driver is depreciated.  To configure
+  the driver, use the sethdlc utility available in the standard ax25
+  utilities package. For information on the modems, see
+  http://www.baycom.de (to browse the WWW, you need to have access to
+  a machine on the Internet that has a program like lynx or netscape)
+  and Documentation/networking/baycom.txt. 
+
+  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 baycom_ser_hdx.o.
+
+Sound card modem driver for AX.25
+CONFIG_SOUNDMODEM
+  This experimental driver allows a standard SoundBlaster or
+  WindowsSoundSystem compatible sound card to be used as a packet radio
+  modem (NOT as a telephone modem!), to send digital traffic over
+  amateur radio. 
+
+  To configure the driver, use the sethdlc, smdiag and smmixer
+  utilities available in the standard ax25 utilities package. For
+  information on how to key the transmitter, see
+  http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html (to browse
+  the WWW, you need to have access to a machine on the Internet that
+  has a program like lynx or netscape) and
+  Documentation/networking/soundmodem.txt. 
+
+  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 soundmodem.o.
+
+Sound card modem support for SoundBlaster and compatible cards
+CONFIG_SOUNDMODEM_SBC
+  This option enables the soundmodem driver to use SoundBlaster and
+  compatible cards. If you have a dual mode card (i.e. a WSS cards
+  with a SoundBlaster emulation) you should say N here and Y to
+  "Sound card modem support for WSS and Crystal cards", below, because
+  this usually results in better performance. This option also supports
+  SB16/32/64 in full duplex mode.
+
+Sound card modem support for WSS and Crystal cards
+CONFIG_SOUNDMODEM_WSS
+  This option enables the soundmodem driver to use WindowsSoundSystem
+  compatible cards. These cards feature a codec chip from either
+  Analog Devices (such as AD1848, AD1845, AD1812) or Crystal
+  Semiconductors (such as CS4248, CS423x). This option also supports
+  the WSS full duplex operation which currently works with Crystal
+  CS423x chips. If you don't need full duplex operation, do not enable
+  it to save performance.
+
+Sound card modem support for 1200 baud AFSK modulation
+CONFIG_SOUNDMODEM_AFSK1200
+  This option enables the soundmodem driver 1200 baud AFSK modem, 
+  compatible to popular modems using TCM3105 or AM7911. The demodulator
+  requires about 12% of the CPU power of a Pentium 75 CPU per channel.
+
+Sound card modem support for 2400 baud AFSK modulation (7.3728MHz crystal)
+CONFIG_SOUNDMODEM_AFSK2400_7
+  This option enables the soundmodem driver 2400 baud AFSK modem,
+  compatible to TCM3105 modems (over-)clocked with a 7.3728MHz
+  crystal.  Note that the availability of this driver does _not_ imply
+  that I recommend building such links. It is only here since users
+  especially in eastern Europe have asked me to do so. In fact this
+  modulation scheme has many disadvantages, mainly its incompatibility
+  with many transceiver designs and the fact that the TCM3105 (if
+  used) is operated widely outside its specifications.
+
+Sound card modem support for 2400 baud AFSK modulation (8MHz crystal)
+CONFIG_SOUNDMODEM_AFSK2400_8
+  This option enables the soundmodem driver 2400 baud AFSK modem,
+  compatible to TCM3105 modems (over-)clocked with an 8MHz crystal.
+  Note that the availability of this driver does _not_ imply that I
+  recommend building such links. It is only here since users
+  especially in eastern Europe have asked me to do so. In fact this
+  modulation scheme has many disadvantages, mainly its incompatibility
+  with many transceiver designs and the fact that the TCM3105 (if
+  used) is operated widely outside its specifications.
+
+Sound card modem support for 2666 baud AFSK modulation
+CONFIG_SOUNDMODEM_AFSK2666
+  This option enables the soundmodem driver 2666 baud AFSK modem.
+  This modem is experimental, and not compatible to anything
+  else I know of.
+
+Sound card modem support for 4800 baud 8PSK modulation
+CONFIG_SOUNDMODEM_PSK4800
+  This option enables the soundmodem driver 4800 baud 8PSK modem.
+  This modem is experimental, and not compatible to anything
+  else I know of.
+
+Sound card modem support for 4800 baud HAPN-1 modulation
+CONFIG_SOUNDMODEM_HAPN4800
+  This option enables the soundmodem driver 4800 baud HAPN-1
+  compatible modem. This modulation seems to be widely used 'down
+  under' and in the Netherlands. Here, nobody uses it, so I could not
+  test if it works.  It is compatible to itself, however :-)
+
+Sound card modem support for 9600 baud FSK G3RUH modulation
+CONFIG_SOUNDMODEM_FSK9600
+  This option enables the soundmodem driver 9600 baud FSK modem,
+  compatible to the G3RUH standard. The demodulator requires about 4%
+  of the CPU power of a Pentium 75 CPU per channel. You can say Y to
+  both 1200 baud AFSK and 9600 baud FSK if you want (but obviously you
+  can only use one protocol at a time, depending on what the other end
+  can understand).
 
 CCITT X.25 Packet Layer
 CONFIG_X25
@@ -2169,25 +2585,28 @@
   countries have public X.25 networks.  X.25 consists of two
   protocols: the higher level Packet Layer Protocol (PLP) (say Y here
   if you want that) and the lower level data link layer protocol LAPB
-  (say Y to "LAPB Data Link Driver" below if you want that). You can
-  read more about X.25 at http://www.sangoma.com/x25.html and
+  (say Y to "LAPB Data Link Driver" below if you want that). 
+
+  You can read more about X.25 at http://www.sangoma.com/x25.html and
   http://www.cisco.com/univercd/data/doc/software/11_0/rpcg/cx25.htm
   (to browse the WWW, you need to have access to a machine on the
-  Internet that has a program like lynx or netscape).  Information
+  Internet that has a program like lynx or netscape). Information
   about X.25 for Linux is contained in the files
   Documentation/networking/x25.txt and
-  Documentation/networking/x25-iface.txt.  One connects to an X.25
-  network either with a dedicated network card using the X.21 protocol
-  (not yet supported by Linux) or one can do X.25 over a standard
-  telephone line using an ordinary modem (say Y to "X.25 async driver"
-  below) or over Ethernet using an ordinary Ethernet card and either
-  the 802.2 LLC protocol (say Y to "802.2 LLC" below) or LAPB over
-  Ethernet (say Y to "LAPB Data Link Driver" and "LAPB over Ethernet
-  driver" below).  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 x25.o. If
-  unsure, say N.
+  Documentation/networking/x25-iface.txt. 
+
+  One connects to an X.25 network either with a dedicated network card
+  using the X.21 protocol (not yet supported by Linux) or one can do
+  X.25 over a standard telephone line using an ordinary modem (say Y
+  to "X.25 async driver" below) or over Ethernet using an ordinary
+  Ethernet card and either the 802.2 LLC protocol (say Y to "802.2
+  LLC" below) or LAPB over Ethernet (say Y to "LAPB Data Link Driver"
+  and "LAPB over Ethernet driver" below). 
+
+  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 x25.o. If unsure, say N.
 
 LAPB Data Link Driver (EXPERIMENTAL) 
 CONFIG_LAPB
@@ -2200,11 +2619,12 @@
   Linux currently supports LAPB only over Ethernet connections. If you
   want to use LAPB connections over Ethernet, say Y here and to "LAPB
   over Ethernet driver" below.  Read
-  Documentation/networking/lapb-module.txt for technical details.  If
-  you want to compile this driver as a module though ( = code which
+  Documentation/networking/lapb-module.txt for technical details.  
+
+  If you want to compile this driver as a module though ( = 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 lapb.o.  If unsure, say N.
+  will be called lapb.o. If unsure, say N.
 
 802.2 LLC (VERY EXPERIMENTAL)
 CONFIG_LLC
@@ -2219,15 +2639,17 @@
   Several such bridges can work together to create even larger
   networks of Ethernets using the IEEE802.1 spanning tree algorithm.
   As this is a standard, Linux bridges will interwork properly with
-  other third party bridge products. In order to use this, you'll need
-  the bridge configuration tools available via ftp (user: anonymous)
-  from shadow.cabi.net in /pub/Linux. Please read the Bridge
-  mini-HOWTO for more information. Note that if your box acts as a
-  bridge, it probably contains several Ethernet devices, but the
-  kernel is not able to recognize more than one at boot time without
-  help; for details read the Ethernet-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. The
-  Bridging code is still in test. If unsure, say N.
+  other third party bridge products. 
+
+  In order to use this, you'll need the bridge configuration tools
+  available via ftp (user: anonymous) from
+  ftp://shadow.cabi.net/pub/Linux. Please read the Bridge mini-HOWTO
+  for more information. Note that if your box acts as a bridge, it
+  probably contains several Ethernet devices, but the kernel is not
+  able to recognize more than one at boot time without help; for
+  details read the Ethernet-HOWTO, available via ftp (user: anonymous)
+  in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. The Bridging code is
+  still in test. If unsure, say N.
 
 Packet socket
 CONFIG_PACKET
@@ -2260,8 +2682,9 @@
 CONFIG_RTNETLINK
   If you say Y here and create a character special file /dev/route
   with major number 36 and minor number 0 using mknod ("man mknod"),
-  you can read some network related routing information from that
-  file. Everything you write to that file will be discarded.
+  you (or some user space utility) can read some network related
+  routing information from that file. Everything you write to that
+  file will be discarded.
 
 Netlink device emulation
 CONFIG_NETLINK_DEV
@@ -2277,11 +2700,12 @@
   it. You also need to say Y here if you want support for the parallel
   port version of the 100MB IOMEGA ZIP drive. Please read the
   SCSI-HOWTO, available via ftp (user: anonymous) in
-  sunsite.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). The module will be
-  called scsi_mod.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt and
+  ftp://sunsite.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).
+  The module will be called scsi_mod.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt and
   Documentation/scsi.txt. However, do not compile this as a module if
   your root filesystem (the one containing the directory /) is located
   on a SCSI device.
@@ -2291,38 +2715,44 @@
   If you want to use a SCSI hard disk or the SCSI or parallel port
   version of the IOMEGA ZIP drive under Linux, say Y and read the
   SCSI-HOWTO and the Disk-HOWTO, both available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. This is NOT for
-  SCSI CDROMs. 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 sd_mod.o. If you want
-  to compile it as a module, say M here and read
-  Documentation/modules.txt and Documentation/scsi.txt. Do not compile
-  this driver as a module if your root filesystem (the one containing
-  the directory /) is located on a SCSI disk. In this case, do not
-  compile the driver for your SCSI host adapter (below) as a module
-  either.
+  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. This is
+  NOT for SCSI CDROMs.
+
+  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 sd_mod.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt and
+  Documentation/scsi.txt. Do not compile this driver as a module if
+  your root filesystem (the one containing the directory /) is located
+  on a SCSI disk. In this case, do not compile the driver for your
+  SCSI host adapter (below) as a module either.
 
 SCSI tape support
 CONFIG_CHR_DEV_ST
   If you want to use a SCSI tapedrive under Linux, say Y and read the
   SCSI-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO and drivers/scsi/README.st in
-  the kernel source. This is NOT for SCSI CDROMs. 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 st.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt and Documentation/scsi.txt .
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and
+  drivers/scsi/README.st in the kernel source. This is NOT for SCSI
+  CDROMs.
+
+  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 st.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt and
+  Documentation/scsi.txt .
 
 SCSI CDROM support
 CONFIG_BLK_DEV_SR
   If you want to use a SCSI CDROM under Linux, say Y and read the
   SCSI-HOWTO and the CDROM-HOWTO from
   sunsite.unc.edu:/pub/Linux/docs/HOWTO. Also make sure to say Y to
-  "ISO9660 cdrom filesystem support" later. 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 sr_mod.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt and Documentation/scsi.txt .
+  "ISO9660 cdrom filesystem support" later. 
+
+  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 sr_mod.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt and
+  Documentation/scsi.txt .
 
 Enable vendor-specific extensions (for SCSI CDROM)
 CONFIG_BLK_DEV_SR_VENDOR
@@ -2339,15 +2769,17 @@
   directly, so you need some additional software which knows how to
   talk to these devices using the SCSI protocol. For CD-writers, you
   would need the program cdwrite, available via ftp (user: anonymous)
-  from sunsite.unc.edu:/pub/Linux/utils/disk-management; for other
+  from ftp://sunsite.unc.edu/pub/Linux/utils/disk-management; for other
   devices, it's possible that you'll have to write the driver software
   yourself, so have a look at the SCSI-HOWTO and at the
   SCSI-Programming-HOWTO, both available via ftp (user: anonymous) in
-  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 and Documentation/scsi.txt. The module
-  will be called sg.o. If unsure, say N.
+  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 and
+  Documentation/scsi.txt. The module will be called sg.o. If unsure,
+  say N.
 
 Probe all LUNs on each SCSI device
 CONFIG_SCSI_MULTI_LUN
@@ -2370,45 +2802,51 @@
   This turns on a logging facility that can be used to debug a number
   of problems.  Normally no logging output will appear, but you can
   enable logging with a shell command like: 
+
      echo "scsi log token [level]" > /proc/scsi/scsi
+
   There are a number of things that can be used for 'token' (you can
   find them in the source: drivers/scsi/scsi.c), and this allows you
   to select the types of information you want, and the level allows
-  you to select the level of verbosity.  If you say 'N' here, it may
-  be harder to track down some types of SCSI problems.  If you say 'Y'
-  here your kernel will be somewhat larger, but there should be no
-  noticeable performance impact as long as you have logging turned off.
+  you to select the level of verbosity. If you say N here, it may be
+  harder to track down some types of SCSI problems. If you say Y here
+  your kernel will be somewhat larger, but there should be no
+  noticeable performance impact as long as you have logging turned
+  off.
 
 AdvanSys SCSI support
 CONFIG_SCSI_ADVANSYS
   This is a driver for all SCSI host adapters manufactured by
   AdvanSys. It is documented in the kernel source in
-  drivers/scsi/advansys.c. This driver is also available as a module (
-  = code which can be inserted in and removed from the running kernel
-  whenever you want). If you want to compile it as a module, say M
-  here and read Documentation/modules.txt. The module will be called
-  advansys.o.
+  drivers/scsi/advansys.c. 
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The module will be called advansys.o.
 
 Adaptec AHA152X/2825 support
 CONFIG_SCSI_AHA152X
   This is support for the 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
-  sunsite.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 inserted in and
-  removed from the running kernel whenever you want). The module will
-  be called aha152x.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  ftp://sunsite.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
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called aha152x.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Adaptec AHA1542 support
 CONFIG_SCSI_AHA1542
   This is support for a SCSI host adapter. It is explained in section
   3.4 of the SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  Note that Trantor was
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  Note that Trantor was
   recently purchased by Adaptec, and some former Trantor products are
   being sold under the Adaptec name. If it doesn't work out of the
   box, you may have to change some settings in drivers/scsi/aha1542.h.
+  
   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
@@ -2418,86 +2856,111 @@
 CONFIG_SCSI_AHA1740
   This is support for a SCSI host adapter. It is explained in section
   3.5 of the SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If it doesn't work out of
-  the box, you may have to change some settings in
-  drivers/scsi/aha1740.h. 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 aha17400.o. If you
-  want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  of the box, you may have to change some settings in
+  drivers/scsi/aha1740.h.
+
+  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 aha17400.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 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, 294x PCI cards,
-  394x PCI cards, 3985 PCI card, and several versions of the Adaptec
-  built-in SCSI controllers on various PC motherboards.  Information on
-  the configuration options for this controller can be found by checking
-  the README.aic7xxx file, usually in /usr/src/linux/drivers/scsi.
+  This is support for the various aic7xxx based Adaptec SCSI
+  controllers. These include the 274x EISA cards, 284x VLB cards, 294x
+  PCI cards, 394x PCI cards, 3985 PCI card, and several versions of
+  the Adaptec built-in SCSI controllers on various PC motherboards.
+  Information on the configuration options for this controller can be
+  found by checking the help file for each of the available
+  configuration options. You also want to read
+  drivers/scsi/README.aic7xxx and the SCSI-HOWTO, available via ftp
+  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 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. 
+
+  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 aic7xxx.o.
 
 Override driver defaults for commands per LUN
 CONFIG_OVERRIDE_CMDS
-  Use this option to allow you to override the default maximum number of
-  commands that a single device on the aic7xxx controller is allowed to have
-  active at one time.  This option only effects tagged queueing capable
-  devices.  The driver uses a "failsafe" value of 8 by default.  This is
-  much lower than many devices can handle, but left in place for safety sake.
-  NOTE: This does not actually enabled tagged queueing on any particular
-  device.  The driver has changed in this respect.  Please see the file
-  README.aic7xxx in /usr/src/linux/drivers/scsi for more information on how
+  Say Y here if you want to override the default maximum number of
+  commands that a single device on the aic7xxx controller is allowed
+  to have active at one time. This option only effects tagged queueing
+  capable devices. The driver uses a "failsafe" value of 8 by default.
+  This is much lower than many devices can handle, but left in place
+  for safety's sake. If you say Y here, you can adjust the number of
+  commands per LUN with the following configuration option.
+  
+  NOTE: This does not actually enable tagged queueing on any
+  particular device. The driver has changed in this respect. Please
+  see the file drivers/scsi/README.aic7xxx for more information on how
   to get particular devices to use tagged command queueing.
-  Default: N
+  
+  If unsure, say N.
 
 Maximum number of commands per LUN
 CONFIG_AIC7XXX_CMDS_PER_LUN
-  Specify the maximum number of commands per lun you would like to allocate
-  per device.  Reasonable figures are in the range of 14 to 32 commands per
-  device, but depending on hardware could be increased or decreased from
-  that figure.  If the number is too high for any particular device, the
-  driver will automatically compensate usually after only 10 minutes of
-  uptime and will issue a message to alert you to the fact that the number
-  of commands for that device has been reduced.  It will not hinder
-  performance if a portion of your devices eventually have their commands
-  per lun reduced, but is a waste of memory if all of your devices end
-  up reducing this number down to a more reasonable figure.  Default: 24
+  Specify the maximum number of commands you would like to allocate
+  per LUN (a LUN is a Logical Unit Number - some physical SCSI devices,
+  e.g. CD jukeboxes, act logically as several separate units, each of
+  which gets its own number).  
+
+  Reasonable figures are in the range of 14 to 32 commands per device,
+  but depending on hardware could be increased or decreased from that
+  figure. If the number is too high for any particular device, the
+  driver will automatically compensate usually after only 10 minutes
+  of uptime and will issue a message to alert you to the fact that the
+  number of commands for that device has been reduced. It will not
+  hinder performance if some of your devices eventually have their
+  commands per LUN reduced, but is a waste of memory if all of your
+  devices end up reducing this number down to a more reasonable
+  figure. Default: 24
 
 Collect statistics to report in /proc
 CONFIG_AIC7XXX_PROC_STATS
-  This option tells the driver to keep track of how many commands have been
-  sent to each particular device and report that information to the user
-  via the /proc/scsi/aic7xxx/x file, where x is the number of the aic7xxx
-  controller you want the information on.  This adds a small amount of
-  overhead to each and every SCSI command the aic7xxx driver handles, so if
-  you aren't really interested in this information, it is best to leave it
-  disabled.  Default: N
+  This option tells the driver to keep track of how many commands have
+  been sent to each particular device and report that information to
+  the user via the /proc/scsi/aic7xxx/n file, where n is the number of
+  the aic7xxx controller you want the information on. This adds a
+  small amount of overhead to each and every SCSI command the aic7xxx
+  driver handles, so if you aren't really interested in this
+  information, it is best to leave it disabled. This will only work if
+  you also say Y to "/proc filesystem support", below. If unsure, say N.
 
 Delay in seconds after SCSI bus reset
 CONFIG_AIC7XXX_RESET_DELAY
-  This sets how long the driver will wait after resetting the SCSI bus before
-  attempting to communicate with the devices on the SCSI bus again.  This
-  delay will be used during the reset phase at bootup time as well as after
-  any reset that might occur during normal operation.  Reasonable numbers
-  range anywhere from 5 to 15 seconds depending on your devices.  DAT tape
-  drives are notorious for needing more time after a bus reset to be
-  ready for the next command, but most hard drives and CD-ROM devices are
-  ready in only a few seconds.  This option has a maximum upper limit of
-  20 seconds to avoid bad interactions between the aic7xxx driver and the
-  rest of the linux kernel.  The default value has been reduced.  If this
-  doesn't work with your hardware, try increasing this value.  Default: 5
+  This sets how long the driver will wait after resetting the SCSI bus
+  before attempting to communicate with the devices on the SCSI bus
+  again. This delay will be used during the reset phase at bootup time
+  as well as after any reset that might occur during normal operation.
+  Reasonable numbers range anywhere from 5 to 15 seconds depending on
+  your devices. DAT tape drives are notorious for needing more time
+  after a bus reset to be ready for the next command, but most hard
+  drives and CD-ROM devices are ready in only a few seconds. This
+  option has a maximum upper limit of 20 seconds to avoid bad
+  interactions between the aic7xxx driver and the rest of the linux
+  kernel. The default value has been reduced to 5 seconds. If this
+  doesn't work with your hardware, try increasing this value.
 
 BusLogic SCSI support
 CONFIG_SCSI_BUSLOGIC
   This is support for BusLogic MultiMaster and FlashPoint SCSI Host
   Adapters.  Consult the SCSI-HOWTO, available via anonymous ftp from
-  sunsite.unc.edu in /pub/Linux/docs/HOWTO, and the files
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, and the files
   README.BusLogic and README.FlashPoint in drivers/scsi for more
   information.  If this driver does not work correctly without
   modification, please contact the author, Leonard N. Zubkoff, by
-  email to lnz@dandelion.com.  You can also build this driver as a
-  module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), but only a single instance may be
-  loaded.  If you want to compile it as a module, say M here and read
-  Documentation/modules.txt. The module will be called BusLogic.o.
+  email to lnz@dandelion.com.  
+
+  You can also build this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  but only a single instance may be loaded. If you want to compile it
+  as a module, say M here and read Documentation/modules.txt. The
+  module will be called BusLogic.o.
 
 Omit BusLogic SCSI FlashPoint support
 CONFIG_SCSI_OMIT_FLASHPOINT
@@ -2506,17 +2969,17 @@
   substantial, so users of MultiMaster Host Adapters may wish to omit
   it.
 
-
 DTC3180/3280 SCSI support
 CONFIG_SCSI_DTC3280
   This is support for DTC 3180/3280 SCSI Host Adapters.  Please read
   the SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO and the file
-  drivers/scsi/README.dtc3x80.  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 dtc.o. If you
-  want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and the file
+  drivers/scsi/README.dtc3x80.  
+
+  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 dtc.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support
 CONFIG_SCSI_EATA_DMA
@@ -2526,11 +2989,12 @@
   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
-  sunsite.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). The module will be
-  called eata_dma.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  ftp://sunsite.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).
+  The module will be called eata_dma.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 EATA-PIO (old DPT PM2001, PM2012A) support
 CONFIG_SCSI_EATA_PIO
@@ -2540,10 +3004,12 @@
   doing so, since this driver only supports hard disks and lacks
   numerous features.  You might want to have a look at the SCSI-HOWTO,
   available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to compile this
-  as a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), say M here and read
-  Documentation/modules.txt. The module will be called eata_pio.o.
+  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 eata_pio.o.
 
 UltraStor 14F/34F support
 CONFIG_SCSI_U14_34F
@@ -2552,13 +3018,15 @@
   this hardware. If the driver doesn't work out of the box, you may
   have to change some settings in drivers/scsi/u14-34f.c.  Read the
   SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that there is also
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that there is also
   another driver for the same hardware: "UltraStor SCSI support",
   below.  You should say Y to both only if you want 24F support 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). The module will be called u14-34f.o. If you want to compile
-  it as a module, say M here and read Documentation/modules.txt.
+  well. 
+
+  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 u14-34f.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 enable elevator sorting
 CONFIG_SCSI_U14_34F_LINKED_COMMANDS
@@ -2580,10 +3048,11 @@
   other adapters based on the Future Domain chipsets (Quantum
   ISA-200S, ISA-250MG; Adaptec AHA-2920; and at least one IBM board).
   It is explained in section 3.7 of the SCSI-HOWTO, available via ftp
-  (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO.  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 fdomain.o. If you want to compile it as a
+  (user: anonymous) at ftp://sunsite.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).
+  The module will be called fdomain.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
 Generic NCR5380/53c400 SCSI support
@@ -2591,13 +3060,14 @@
   This is the generic NCR family of SCSI controllers, not to be
   confused with the NCR 53c7 or 8xx controllers. It is explained in
   section 3.8 of the SCSI-HOWTO, available via ftp (user: anonymous)
-  at sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If it doesn't work out of
-  the box, you may have to change some settings in
-  drivers/scsi/g_NCR5380.h. 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 g_NCR5380.o. If
-  you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work
+  out of the box, you may have to change some settings in
+  drivers/scsi/g_NCR5380.h.
+
+  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 g_NCR5380.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
 
 Enable NCR53c400 extensions
 CONFIG_SCSI_GENERIC_NCR53C400
@@ -2619,13 +3089,14 @@
   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
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't work out of the
-  box, you may have to change some settings in
-  drivers/scsi/53c7,8xx.h. 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 53c7,8xx.o. If you
-  want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  of the box, you may have to change some settings in
+  drivers/scsi/53c7,8xx.h.
+
+  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 53c7,8xx.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 always negotiate synchronous transfers
 CONFIG_SCSI_NCR53C7xx_sync
@@ -2653,7 +3124,7 @@
 
 NCR53C8XX SCSI support
 CONFIG_SCSI_NCR53C8XX
-  This is the BSD ncr driver adapted to linux for the NCR53C8XX family
+  This is the BSD ncr driver adapted to Linux for the NCR53C8XX family
   of PCI-SCSI controllers. This driver supports parity checking,
   tagged command queuing, Fast-20 data transfer up to 20 MB/s with
   narrow SCSI devices and 40 MB/s with wide SCSI devices.
@@ -2664,21 +3135,26 @@
 CONFIG_SCSI_NCR53C8XX_SYNC
   SCSI-2 specifications allow SCSI devices to negotiate a synchronous 
   transfer period of 25 nano-seconds or more.
+
   The transfer period value is 4 times the agreed transfer period.
   So, data can be transferred at a 10 MHz frequency, allowing 10
   MB/second throughput with 8 bits SCSI-2 devices and 20 MB/second
   with wide16 devices.  This frequency can be used safely with
   differential devices but may cause problems with single-ended
   devices.
+
   Specify 0 if you want to only use asynchronous data transfers.
   Otherwise, specify a value between 5 and 10.  Commercial O/Ses
   generally use 5 Mhz frequency for synchronous transfers.  It is a
   reasonable default value.
+
   However, a flawless single-ended SCSI bus supports 10 MHz data
   transfers.  Regardless of the value chosen in the Linux
   configuration, the synchronous period can be changed after boot-up
   through the /proc/scsi file system. The generic command is:
+
       echo "setsync #target period" >/proc/scsi/ncr53c8xx/0
+
   Use a 25 ns period for 10 Mhz synchronous data transfers.
   If you don't know what to do now, go with the default.
 
@@ -2722,15 +3198,19 @@
 enable tagged command queuing
 CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
   This option allows you to enable tagged command queuing support at
-  linux start-up.  Some SCSI devices do not properly support this
+  Linux start-up.  Some SCSI devices do not properly support this
   feature.  The suggested method is to say N here and to use the
   "settags" control command after boot-up to enable this feature:
+
       echo "settags 2 4" >/proc/scsi/ncr53c8xx/0
+
   asks the driver to use up to 4 concurrent tagged commands for target
   2 of controller 0.
+
   See the file drivers/scsi/README.ncr53c8xx for more information.
   WARNING! If you say Y here, then you have to say N to "not allow
   targets to disconnect", above.
+
   The safe answer therefore is N.
   The normal answer therefore is Y.
 
@@ -2749,6 +3229,7 @@
   features.  Genuine SYMBIOS boards use GPIO0 in output for controller
   LED and GPIO3 bit as a flag indicating single-ended/differential
   interface.
+
   If all the boards of your system are genuine SYMBIOS boards or use
   BIOS and drivers from SYMBIOS, you would want to enable this option.
   The driver behaves correctly on my system with this option enabled.
@@ -2756,11 +3237,13 @@
   0x12).  This option must be set to N if your system has at least one
   53C8XX based SCSI board with a vendor-specific BIOS (example: Tekram
   DC-390/U/W/F). 
+
   However, if all your non Symbios compatible boards have NVRAM,
   setting option "detect and read serial NVRAMs"
   (CONFIG_SCSI_NCR53C8XX_NVRAM_DETECT) above allows the driver to
   distinguish Symbios compatible boards from other ones.  So, you can
   answer Y if all non Symbios compatible boards have NVRAM.
+
   If unsure, say N.
 
 IBMMCA SCSI support
@@ -2768,6 +3251,7 @@
   This is support for the IBM SCSI adapter found in many of the PS/2
   series computers. These machines have an MCA bus, so you need to say
   Y to "MCA support" as well and read Documentation/mca.txt.
+
   If the adapter isn't found during boot (a common problem for models
   56, 57, 76, and 77) you'll need to use the 'ibmmcascsi=<pun>' kernel
   option, where <pun> is the id of the SCSI subsystem (usually 7, but
@@ -2778,7 +3262,8 @@
   bootparam" or see the documentation of your boot loader about how to
   pass options to the kernel. The lilo procedure is also explained in
   the SCSI-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read Documentation/modules.txt. The module will be
@@ -2801,12 +3286,14 @@
   original definition of the SCSI-standard as also industrial- and
   process-control-machines, like VME-CPUs running under realtime-OSs
   (e.g. LynxOS, OS9) do.
+
   If you like to run Linux on your MCA-machine with the same assignment
   of hard disks as seen from e.g. DOS or OS/2 on your machine, which
   is in addition conformant to the SCSI-standard, you must say Y here.
   This is also necessary for MCA-Linux-users who want to keep downward-
   compatibility to older releases of the IBM-MCA-SCSI-driver (older than
   driver-release 2.00 and older than June 1997).
+
   If you like to have the lowest SCSI-id assigned as drive C:, as
   modern SCSI-BIOSes do, which does not conform to the standard, but
   is widespread and common in the PC-world of today, you must say N
@@ -2830,39 +3317,44 @@
   This is support for an ISA bus SCSI host adapter. You'll find more
   information in drivers/scsi/in2000.readme. If it doesn't work out of
   the box, you may have to change the jumpers for IRQ or address
-  selection. 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 in2000.o.
+  selection. 
+
+  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 in2000.o.
 
 PAS16 SCSI support
 CONFIG_SCSI_PAS16
   This is support for a SCSI host adapter. It is explained in section
   3.10 of the SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't work out of the
-  box, you may have to change some settings in drivers/scsi/pas16.h.
-  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
-  pas16.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  of the box, you may have to change some settings in
+  drivers/scsi/pas16.h.
+  
+  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 pas16.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 PCI2000 support
 CONFIG_SCSI_PCI2000
   This is support for the PCI2000I EIDE interface card which acts as a
   SCSI host adapter. Please read the SCSI-HOWTO, available via ftp
-  (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. This
-  driver is also available as a module called pci2000.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.
+  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+
+  This driver is also available as a module called pci2000.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.
 
 PCI2220i support
 CONFIG_SCSI_PCI2220I
   This is support for the PCI2220i EIDE interface card which acts as a
   SCSI host adapter. Please read the SCSI-HOWTO, available via ftp
-  (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. This
-  driver is also available as a module called pci2220i.o ( = code
+  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+
+  This driver is also available as a module called pci2220i.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.
@@ -2871,11 +3363,12 @@
 CONFIG_SCSI_PSI240I
   This is support for the PSI240i EIDE interface card which acts as a
   SCSI host adapter. Please read the SCSI-HOWTO, available via ftp
-  (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. This
-  driver is also available as a module called psi240i.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.
+  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+
+  This driver is also available as a module called psi240i.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.
 
 Qlogic FAS SCSI support
 CONFIG_SCSI_QLOGIC_FAS
@@ -2886,11 +3379,12 @@
   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
-  sunsite.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). The module will be called
-  qlogicfas.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt.
+  ftp://sunsite.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).
+  The module will be called qlogicfas.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
 
 Qlogic ISP SCSI support (EXPERIMENTAL)
 CONFIG_SCSI_QLOGIC_ISP
@@ -2901,55 +3395,63 @@
   information is contained in the file
   drivers/scsi/README.qlogicisp. You should also read the SCSI-HOWTO,
   available via ftp (user: anonymous) at
-  sunsite.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). The module will be called
-  qlogicisp.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt.
+  ftp://sunsite.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).
+  The module will be called qlogicisp.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
 
 Seagate ST-02 and Future Domain TMC-8xx SCSI support
 CONFIG_SCSI_SEAGATE
   These are 8-bit SCSI controllers; the ST-01 is also supported by
-  this driver.  It is explained in section 3.9 of the SCSI-HOWTO,
+  this driver. It is explained in section 3.9 of the SCSI-HOWTO,
   available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't work out of the
-  box, you may have to change some settings in drivers/scsi/seagate.h.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  of the box, you may have to change some settings in
+  drivers/scsi/seagate.h.
+
   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 seagate.o. If you want to compile
-  it as a module, say M here and read Documentation/modules.txt.
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called seagate.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Trantor T128/T128F/T228 SCSI support
 CONFIG_SCSI_T128
   This is support for a SCSI host adapter. It is explained in section
   3.11 of the SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If it doesn't work out of
-  the box, you may have to change some settings in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  of the box, you may have to change some settings in
   drivers/scsi/t128.h. Note that Trantor was purchased by Adaptec, and
-  some former Trantor products are being sold under the Adaptec
-  name. 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 t128.o. If you want to compile it
-  as a module, say M here and read Documentation/modules.txt.
+  some former Trantor products are being sold under the Adaptec name.
+
+  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 t128.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 UltraStor SCSI support
 CONFIG_SCSI_ULTRASTOR
   This is support for the UltraStor 14F, 24F and 34F SCSI-2 host
   adapter family. This driver is explained in section 3.12 of the
   SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't work out of the
-  box, you may have to change some settings in
-  drivers/scsi/ultrastor.h. 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 ultrastor.o.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  of the box, you may have to change some settings in
+  drivers/scsi/ultrastor.h.
+  
   Note that there is also another driver for the same hardware:
   "UltraStor 14F/34F support", above.
 
+  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 ultrastor.o. 
+
 7000FASST SCSI support
 CONFIG_SCSI_7000FASST
   This driver supports the Western Digital 7000 SCSI host adapter
   family.  Some information is in the source: drivers/scsi/wd7000.c.
+
   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 wd7000.o. If you want to compile it
@@ -2961,15 +3463,17 @@
   and does not need any BIOS32 service.  DPT ISA and all EISA i/o
   addresses are probed looking for the "EATA" signature. If you said Y
   to "PCI bios support", the addresses of all the PCI SCSI controllers
-  reported by BIOS32 are probed as well.  Note that there is also
-  another driver for the same hardware available: "EATA-DMA
-  support". You should say Y to only one of them.  You want to read
+  reported by BIOS32 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 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
-  eata.o.
+  ftp (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  
+
+  Note that there is also another driver for the same hardware
+  available: "EATA-DMA support". You should say Y to only one of them.
+
+  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 eata.o.
 
 enable tagged command queuing
 CONFIG_SCSI_EATA_TAGGED_QUEUE
@@ -2997,11 +3501,12 @@
   This is support for the NCR53c406a SCSI host adapter. For user
   configurable parameters, check out drivers/scsi/NCR53c406.c in the
   kernel source. Also read the SCSI-HOWTO, available via ftp (user:
-  anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to
-  compile this driver as a module ( = code which can be inserted in
-  and removed from the running kernel whenever you want), say M here
-  and read Documentation/modules.txt. The module will be called
-  NCR53c406.o.
+  anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called NCR53c406.o.
 
 Tekram DC390(T) (AMD PCscsi) SCSI support
 CONFIG_SCSI_DC390T
@@ -3009,6 +3514,7 @@
   the Am53C974A chip, and perhaps other cards using the same chip.
   This driver does _not_ support the DC390W/U/F adaptor with the
   NCR/Symbios chips; use "NCR53C8XX SCSI support" for that 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
@@ -3019,37 +3525,44 @@
   This is support for the AM53/79C974 SCSI host adapters. Please read
   drivers/scsi/README.AM53C974 for details. Also, the SCSI-HOWTO,
   available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO, is for you. 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.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, is for you. 
+
+  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.
 
 GDT SCSI Disk Array Controller support
 CONFIG_SCSI_GDTH
   This is a driver for all SCSI Disk Array Controllers (EISA/ISA/PCI) 
   manufactured by ICP vortex. It is documented in the kernel source in
-  drivers/scsi/gdth.c and drivers/scsi/gdth.h. This driver is also
-  available as a module ( = code which can be inserted in and removed
-  from the running kernel whenever you want). If you want to compile 
-  it as a module, say M here and read Documentation/modules.txt. 	
+  drivers/scsi/gdth.c and drivers/scsi/gdth.h. 
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.
 
 IOMEGA Parallel Port ZIP drive SCSI support
 CONFIG_SCSI_PPA
   This driver supports the parallel port version of IOMEGA's ZIP drive
-  (a 100Mb removable media device).  For more information about this
+  (a 100Mb 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 anonymous ftp from sunsite.unc.edu in the directory
-  /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. 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.
+  drivers/scsi/README.ppa. You should also read the SCSI-HOWTO, which
+  is available via ftp (user: anonymous) from
+  ftp://sunsite.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.
+
+  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.
+
+  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. 
 
 EPP FIFO Checking
 CONFIG_SCSI_PPA_HAVE_PEDANTIC
@@ -3065,30 +3578,32 @@
 
 SCSI Debug host simulator.
 CONFIG_SCSI_DEBUG
-  This is a host adapter simulator that can be programmed to simulate a
-  large number of conditions that could occur on a real bus.  The advantage
-  is that many hard to reproduce problems can be tested in a controlled
-  environment where there is reduced risk of losing important data.
-  This is primarily of use to people trying to debug the middle and upper
-  layers of the SCSI subsystem. If unsure, say N.
+  This is a host adapter simulator that can be programmed to simulate
+  a large number of conditions that could occur on a real bus. The
+  advantage is that many hard to reproduce problems can be tested in a
+  controlled environment where there is reduced risk of losing
+  important data. This is primarily of use to people trying to debug
+  the middle and upper layers of the SCSI subsystem. If unsure, say N.
 
 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 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 sunsite.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 shell account on some Internet connected Unix computer. Read
+  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://sunsite.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
+  shell account on some Internet connected Unix computer. Read
   http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html (to browse
   the WWW, you need to have access to a machine on the Internet that
-  has a program like lynx or netscape)). You'll have to say Y if your
-  computer contains a network card that you want to use under linux
-  (make sure you know its name because you will be asked for it and
-  read the Ethernet-HOWTO (especially if you plan to use more than one
-  network card under linux), available from
+  has a program like lynx or netscape)).
+
+  You'll have to say Y if your computer contains a network card that
+  you want to use under Linux (make sure you know its name because you
+  will be asked for it and read the Ethernet-HOWTO (especially if you
+  plan to use more than one network card under Linux), available from
   sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini) or if you want to use
   SLIP (Serial Line Internet Protocol is the protocol used to send
   Internet traffic over telephone lines or nullmodem cables) or CSLIP
@@ -3096,28 +3611,31 @@
   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). Make sure to read the
-  NET-2-HOWTO. Eventually, you will have to read Olaf Kirch's
-  excellent and free book "Network Administrator's Guide", to be found
-  in sunsite.unc.edu:/pub/Linux/docs/LDP. If unsure, say Y.
+  Internet traffic over radio links).
+
+  Make sure to read the NET-2-HOWTO. Eventually, you will have to read
+  Olaf Kirch's excellent and free book "Network Administrator's
+  Guide", to be found in sunsite.unc.edu:/pub/Linux/docs/LDP. If
+  unsure, say Y.
 
 Dummy net driver support
 CONFIG_DUMMY
   This is essentially a bit-bucket device (i.e. traffic you send to
   this device is consigned into oblivion) with a configurable IP
   address. It is most commonly used in order to make your currently
-  inactive SLIP address seem like a real address for local
-  programs. If you use SLIP or PPP, you might want to say Y here. Read
-  about it in the Network Administrator's Guide, available via ftp
-  (user: anonymous) from sunsite.unc.edu:/pub/Linux/docs/LDP. Since
-  this thing often comes in handy, the default is Y. It won't enlarge
-  your kernel either. What a deal.  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 dummy.o. If you
-  want to use more than one dummy device at a time, you need to
-  compile this driver as a module. Instead of 'dummy', the devices
-  will then be called 'dummy0', 'dummy1' etc.
+  inactive SLIP address seem like a real address for local programs.
+  If you use SLIP or PPP, you might want to say Y here. Read about it
+  in the Network Administrator's Guide, available via ftp (user:
+  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/LDP. Since this
+  thing often comes in handy, the default is Y. It won't enlarge your
+  kernel either. What a deal.
+
+  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 dummy.o. If you want to use more than one dummy device at a
+  time, you need to compile this driver as a module. Instead of
+  'dummy', the devices will then be called 'dummy0', 'dummy1' etc.
 
 SLIP (serial line) support
 CONFIG_SLIP
@@ -3125,27 +3643,30 @@
   connect to your Internet service provider or to connect to some
   other local Unix box or if you want to configure your Linux box as a
   Slip/CSlip server for other people to dial in.  SLIP (Serial Line
-  Internet Protocol) is the protocol used to send Internet traffic
+  Internet Protocol) is a protocol used to send Internet traffic
   over telephone lines or serial cables (also known as
-  nullmodems). Normally, your access provider has to support SLIP in
-  order for you to be able to use it, but there is now a SLIP emulator
-  called SLiRP around (available via ftp (user: anonymous) from
-  sunsite.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
-  sunsite.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 Internet
-  connectivity if you have a regular dial up shell account on some
-  Internet connected Unix computer. Read
+  nullmodems); nowadays, the protocol PPP is more common than SLIP. 
+
+  Normally, your access provider has to support SLIP in order for you
+  to be able to use it, but there is now a SLIP emulator called SLiRP
+  around (available via ftp (user: anonymous) from
+  ftp://sunsite.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
+  ftp://sunsite.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
+  Internet connectivity if you have a regular dial up shell account on
+  some Internet connected Unix computer. Read
   http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html (to browse
   the WWW, you need to have access to a machine on the Internet that
   has a program like lynx or netscape)). SLIP support will enlarge
-  your kernel by about 4kB. If unsure, say N.  If you want to compile
-  this as a module ( = code which can be inserted in and removed from
-  the running kernel whenever you want), say M here and read
-  Documentation/modules.txt as well as
+  your kernel by about 4kB. If unsure, say N.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt. The module will be called
   slip.o.
 
@@ -3156,12 +3677,12 @@
   on both ends. Ask your access provider if you are not sure and say
   Y, just in case. You will still be able to use plain SLIP. If you
   plan to use SLiRP, the SLIP emulator (available via ftp (user:
-  anonymous) from sunsite.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 (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO, explains how to configure
-  CSLIP. This won't enlarge your kernel.
+  anonymous) from
+  ftp://sunsite.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
+  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO,
+  explains how to configure CSLIP. This won't enlarge your kernel.
 
 Keepalive and linefill
 CONFIG_SLIP_SMART
@@ -3179,43 +3700,37 @@
   end of the link as well. It's good enough, for example, to run IP
   over the async ports of a Camtec JNT Pad. If unsure, say N.
 
-Wireless LAN (non-hamradio)
-CONFIG_NET_RADIO
-  Support for wireless LAN's and everything having to do with radio,
-  but not with amateur radio. Note that the answer to this question
-  won't directly affect the kernel: saying N will just cause this
-  configure script to skip all the questions about radio
-  interfaces. Some user-level drivers for scarab devices which don't
-  require special kernel support are available via ftp (user:
-  anonymous) from shadow.cabi.net in /pub/Linux.
-
 PPP (point-to-point) support
 CONFIG_PPP
   PPP (Point to Point Protocol) is a newer and better SLIP. It serves
   the same purpose: sending Internet traffic over telephone (and other
-  serial) lines.  Ask your access provider if they support it, because
+  serial) lines. Ask your access provider if they support it, because
   otherwise you can't use it (not quite true any more: the free
   program SLiRP can emulate a PPP line if you just have a regular dial
   up shell account on some UNIX computer; get it via ftp (user:
-  anonymous) from sunsite.unc.edu:/pub/Linux/system/network/serial/).
-  To use PPP, you need an additional program called pppd as described
-  in Documentation/networking/ppp.txt and in the PPP-HOWTO, available
-  from sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you upgrade from an
-  older kernel, you might need to upgrade pppd as well.  Note that you
-  don't need "PPP support" if you just want to run term (term is a
+  anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/system/network/serial/). Note that
+  you don't need "PPP support" if you just want to run 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. Read
   http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html (to browse
   the WWW, you need to have access to a machine on the Internet that
-  has a program like lynx or netscape)). The PPP option enlarges your
-  kernel by about 16kB. This driver is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). If you said Y to "Version information on all
-  symbols" above, then you cannot compile the PPP driver into the
-  kernel; you can then only compile it as a module. The module will be
-  called ppp.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt as well as
+  has a program like lynx or netscape)).
+
+  To use PPP, you need an additional program called pppd as described
+  in Documentation/networking/ppp.txt and in the PPP-HOWTO, available
+  from sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you upgrade from an
+  older kernel, you might need to upgrade pppd as well. The PPP option
+  enlarges your kernel by about 16kB.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you said Y to "Version information on all symbols" above, then
+  you cannot compile the PPP driver into the kernel; you can then only
+  compile it as a module. The module will be called ppp.o. If you want
+  to compile it as a module, say M here and read
+  Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt. Note that, no matter what
   you do, the BSD compression code (used to compress the IP packets
   sent over the serial line; has to be supported at the other end as
@@ -3223,25 +3738,17 @@
   and will show up in the directory modules once you have said "make
   modules". If unsure, say N.
 
-Shortwave radio modem driver
-CONFIG_HFMODEM
-  This experimental driver is used by a package (to be released)
-  that implements the shortwave radio protocols RTTY, Sitor (Amtor),
-  Pactor 1 and GTOR using a standard PC sound card. If unsure,
-  say N.
-
-Shortwave radio modem driver support for SoundBlaster and compatible cards
-CONFIG_HFMODEM_SBC
-  This option enables the hfmodem driver to use SoundBlaster and
-  compatible cards. It requires a 16bit capable card, i.e.
-  SB16 or better, or ESS1688 or newer.
+Wireless LAN (non-hamradio)
+CONFIG_NET_RADIO
+  Support for wireless LAN's and everything having to do with radio,
+  but not with amateur radio. Note that the answer to this question
+  won't directly affect the kernel: saying N will just cause this
+  configure script to skip all the questions about radio
+  interfaces. 
 
-Shortwave radio modem driver support for WSS and Crystal cards
-CONFIG_HFMODEM_WSS
-  This option enables the hfmodem driver to use WindowsSoundSystem
-  compatible cards. These cards feature a codec chip from either
-  Analog Devices (such as AD1848, AD1845) or Crystal
-  Semiconductors (such as CS4248, CS423x).
+  Some user-level drivers for scarab devices which don't require
+  special kernel support are available via ftp (user: anonymous) from
+  ftp://shadow.cabi.net/pub/Linux.
 
 STRIP (Metricom Starmode radio IP)
 CONFIG_STRIP
@@ -3255,23 +3762,48 @@
   a cellular telephone.  (You may also have heard them called
   "Metricom modems" but we avoid the term "modem" because it misleads
   many people into thinking that you can plug a Metricom modem into a
-  phone line and use it as a modem.)  You can use STRIP on any Linux
-  machine with a serial port, although it is obviously most useful for
-  people with laptop computers. If you think you might get a Metricom
-  radio in the future, there is no harm in saying Y to STRIP now,
-  except that it makes the kernel a bit bigger. You can also 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 strip.o.
+  phone line and use it as a modem.)  
+
+  You can use STRIP on any Linux machine with a serial port, although
+  it is obviously most useful for people with laptop computers. If you
+  think you might get a Metricom radio in the future, there is no harm
+  in saying Y to STRIP now, except that it makes the kernel a bit
+  bigger. 
+
+  You can also 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
+  strip.o.
+
+AT&T WaveLAN & DEC RoamAbout DS support
+CONFIG_WAVELAN
+  The Lucent Wavelan (formerly NCR and AT&T ; or DEC RoamAbout DS) is
+  a Radio LAN (wireless Ethernet-like Local Area Network) using the
+  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's pcmcia
+  package. If you want to use an ISA Wavelan card under Linux, say Y
+  and read the Ethernet-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Some more specific
+  information is contained in Documentation/networking/wavelan.txt.
+  You will also need the wireless tools package available from
+  ftp://ftp.inka.de/pub/comp/Linux/networking/NetTools/contrib/.
+
+  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 wavelan.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
 
 Radio support
 CONFIG_MISC_RADIO
   If you have a radio card (which enables your computer to receive
-  regular radio broadcasts), then you will want to say "y" here and
+  regular radio broadcasts), then you will want to say Y here and
   make a character device file (usually /dev/radio) with major number
   10 and minor 152 using mknod ("man mknod").  And then, don't forget
   to pick up some useful tools to use said device (you _might_ find
-  something at ftp.lmh.ox.ac.uk: /users/weejock/linux/, but I haven't
+  something at ftp://ftp.lmh.ox.ac.uk/users/weejock/linux/, but I haven't
   written anything too useful yet...)
 
 AIMSlab RadioTrack card
@@ -3290,11 +3822,12 @@
   which allows you to open an LAPB point-to-point connection to some
   other computer on your Ethernet network. In order to do this, you
   need to say Y or M to the driver for your Ethernet card as well as
-  to "LAPB Data Link Driver".  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 lapbether.o.
-  If unsure, say N.
+  to "LAPB Data Link Driver".  
+
+  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 lapbether.o. If unsure, say N.
 
 X.25 async driver
 CONFIG_X25_ASY
@@ -3302,223 +3835,32 @@
   asynchronous serial lines such as telephone lines equipped with
   ordinary modems. Experts should note that this driver doesn't
   currently comply with the asynchronous HDLS framing protocols in
-  CCITT recommendation X.25. 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 x25_asy.o.  If
-  unsure, say N.
-
-Z8530 SCC driver for AX.25
-CONFIG_SCC
-  These cards are used to connect your Linux box to an amateur radio
-  in order to communicate with other computers.  If you want to use
-  this, read Documentation/networking/z8530drv.txt and the
-  AX.25-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  Also make sure to say Y to
-  "Amateur Radio AX.25 Level 2" support. 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 scc.o.
-
-additional delay for PA0HZP OptoSCC compatible boards
-CONFIG_SCC_DELAY
-
-support for TRX that feedback the tx signal to rx
-CONFIG_SCC_TRXECHO
-###
-### Don't know what's going on here.
-###
-
-High-speed (DMA) SCC driver for AX.25
-CONFIG_DMASCC
-  This is a driver for high-speed SCC boards (used to connect your
-  computer to your amateur radio and send Internet traffic over the
-  radio), i.e. those supporting DMA on one port. Currently, only
-  Ottawa PI/PI2 boards (see http://hydra.carleton.ca/info/pi2.html)
-  and Gracilis PackeTwin boards (see http://www.paccomm.com/; to
-  browse the WWW, you need to have access to a machine on the Internet
-  that has a program like lynx or netscape) are supported and detected
-  automatically. If you have one of these cards, you can say Y here
-  and should read the HAM-HOWTO, available via ftp (user: anonymous)
-  in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
-  This driver operates multiple boards simultaneously. If you compile
-  this driver as a module, it will be called dmascc.o.  If you don't
-  give any parameter to the driver, all possible I/O addresses are
-  probed. This could irritate other devices that are currently not in
-  use. You may specify the list of addresses to be probed by
-  "dmascc=addr1,addr2,..." (when compiled into the kernel image) or
-  "io=addr1,addr2,..." (when loaded as a module).  The network
-  interfaces will be called dmascc0 and dmascc1 for the board detected
-  first, dmascc2 and dmascc3 for the second one, and so on. Before you
-  configure each interface with ifconfig, you MUST set certain
-  parameters, such as channel access timing, clock mode, and DMA
-  channel. This is accomplished with a small utility program called
-  dmascc_cfg, which is part of the ax25-utils package.  Alternatively,
-  you may download the utility from
-  http://www.oevsv.at/~oe1kib/Linux.html.
+  CCITT recommendation X.25. 
 
-BAYCOM picpar and par96 driver for AX.25
-CONFIG_BAYCOM_PAR
-  This is a driver for Baycom style simple amateur radio modems that
-  connect to a parallel interface. The driver supports the picpar and
-  par96 designs. To configure the driver, use the sethdlc utility
-  available in the standard ax25 utilities package. For information on
-  the modems, see http://www.baycom.de (to browse the WWW, you need to
-  have access to a machine on the Internet that has a program like
-  lynx or netscape) and Documentation/networking/baycom.txt. If you
-  want to compile this driver as a module ( = code which can be
+  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 baycom_par.o.
-
-BAYCOM ser12 full duplex driver for AX.25
-CONFIG_BAYCOM_SER_FDX
-  This is one of two drivers for Baycom style simple amateur radio
-  modems that connect to a serial interface. The driver supports the
-  ser12 design in full duplex mode. In addition, it allows the
-  baudrate to be set between 300 and 4800 baud (however not all modems
-  support all baudrates). This is the preferred driver. The next
-  driver, "BAYCOM ser12 half duplex driver for AX.25" is the old
-  driver and still provided in case this driver does not work with
-  your serial interface chip. To configure the driver, use the sethdlc
-  utility available in the standard ax25 utilities package.  For
-  information on the modems, see http://www.baycom.de (to browse the
-  WWW, you need to have access to a machine on the Internet that has a
-  program like lynx or netscape) and
-  Documentation/networking/baycom.txt. 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 baycom_ser_fdx.o.
-
-BAYCOM ser12 half duplex driver for AX.25
-CONFIG_BAYCOM_SER_HDX
-  This is one of two drivers for Baycom style simple amateur radio
-  modems that connect to a serial interface. The driver supports the
-  ser12 design in full duplex mode. This is the old driver.  It is
-  still provided in case your serial interface chip does not work with
-  the full duplex driver. This driver is depreciated.  To configure
-  the driver, use the sethdlc utility available in the standard ax25
-  utilities package. For information on the modems, see
-  http://www.baycom.de (to browse the WWW, you need to have access to
-  a machine on the Internet that has a program like lynx or netscape)
-  and Documentation/networking/baycom.txt. 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 baycom_ser_hdx.o.
+  say M here and read Documentation/modules.txt. The module will be
+  called x25_asy.o. If unsure, say N.
 
-Sound card modem driver for AX.25
-CONFIG_SOUNDMODEM
-  This experimental driver allows a standard SoundBlaster or
-  WindowsSoundSystem compatible sound card to be used as a packet radio
-  modem (NOT as a telephone modem!), to send digital traffic over
-  amateur radio. To configure the driver, use the sethdlc, smdiag and
-  smmixer utilities available in the standard ax25 utilities
-  package. For information on how to key the transmitter, see
-  http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html (to browse
-  the WWW, you need to have access to a machine on the Internet that
-  has a program like lynx or netscape) and
-  Documentation/networking/soundmodem.txt. 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 soundmodem.o.
+Shortwave radio modem driver
+CONFIG_HFMODEM
+  This experimental driver is used by a package (to be released)
+  that implements the shortwave radio protocols RTTY, Sitor (Amtor),
+  Pactor 1 and GTOR using a standard PC sound card. If unsure,
+  say N.
 
-Sound card modem support for SoundBlaster and compatible cards
-CONFIG_SOUNDMODEM_SBC
-  This option enables the soundmodem driver to use SoundBlaster and
-  compatible cards. If you have a dual mode card (i.e. a WSS cards
-  with a SoundBlaster emulation) you should say N here and Y to
-  "Sound card modem support for WSS and Crystal cards", below, because
-  this usually results in better performance. This option also supports
-  SB16/32/64 in full duplex mode.
+Shortwave radio modem driver support for SoundBlaster and compatible cards
+CONFIG_HFMODEM_SBC
+  This option enables the hfmodem driver to use SoundBlaster and
+  compatible cards. It requires a 16bit capable card, i.e.
+  SB16 or better, or ESS1688 or newer.
 
-Sound card modem support for WSS and Crystal cards
-CONFIG_SOUNDMODEM_WSS
-  This option enables the soundmodem driver to use WindowsSoundSystem
+Shortwave radio modem driver support for WSS and Crystal cards
+CONFIG_HFMODEM_WSS
+  This option enables the hfmodem driver to use WindowsSoundSystem
   compatible cards. These cards feature a codec chip from either
-  Analog Devices (such as AD1848, AD1845, AD1812) or Crystal
-  Semiconductors (such as CS4248, CS423x). This option also supports
-  the WSS full duplex operation which currently works with Crystal
-  CS423x chips. If you don't need full duplex operation, do not enable
-  it to save performance.
-
-Sound card modem support for 1200 baud AFSK modulation
-CONFIG_SOUNDMODEM_AFSK1200
-  This option enables the soundmodem driver 1200 baud AFSK modem, 
-  compatible to popular modems using TCM3105 or AM7911. The demodulator
-  requires about 12% of the CPU power of a Pentium 75 CPU per channel.
-
-Sound card modem support for 2400 baud AFSK modulation (7.3728MHz crystal)
-CONFIG_SOUNDMODEM_AFSK2400_7
-  This option enables the soundmodem driver 2400 baud AFSK modem,
-  compatible to TCM3105 modems (over-)clocked with a 7.3728MHz
-  crystal.  Note that the availability of this driver does _not_ imply
-  that I recommend building such links. It is only here since users
-  especially in eastern Europe have asked me to do so. In fact this
-  modulation scheme has many disadvantages, mainly its incompatibility
-  with many transceiver designs and the fact that the TCM3105 (if
-  used) is operated widely outside its specifications.
-
-Sound card modem support for 2400 baud AFSK modulation (8MHz crystal)
-CONFIG_SOUNDMODEM_AFSK2400_8
-  This option enables the soundmodem driver 2400 baud AFSK modem,
-  compatible to TCM3105 modems (over-)clocked with an 8MHz crystal.
-  Note that the availability of this driver does _not_ imply that I
-  recommend building such links. It is only here since users
-  especially in eastern Europe have asked me to do so. In fact this
-  modulation scheme has many disadvantages, mainly its incompatibility
-  with many transceiver designs and the fact that the TCM3105 (if
-  used) is operated widely outside its specifications.
-
-Sound card modem support for 2666 baud AFSK modulation
-CONFIG_SOUNDMODEM_AFSK2666
-  This option enables the soundmodem driver 2666 baud AFSK modem.
-  This modem is experimental, and not compatible to anything
-  else I know of.
-
-Sound card modem support for 4800 baud 8PSK modulation
-CONFIG_SOUNDMODEM_PSK4800
-  This option enables the soundmodem driver 4800 baud 8PSK modem.
-  This modem is experimental, and not compatible to anything
-  else I know of.
-
-Sound card modem support for 4800 baud HAPN-1 modulation
-CONFIG_SOUNDMODEM_HAPN4800
-  This option enables the soundmodem driver 4800 baud HAPN-1
-  compatible modem. This modulation seems to be widely used 'down
-  under' and in the Netherlands. Here, nobody uses it, so I could not
-  test if it works.  It is compatible to itself, however :-)
-
-Sound card modem support for 9600 baud FSK G3RUH modulation
-CONFIG_SOUNDMODEM_FSK9600
-  This option enables the soundmodem driver 9600 baud FSK modem,
-  compatible to the G3RUH standard. The demodulator requires about 4%
-  of the CPU power of a Pentium 75 CPU per channel. You can say Y to
-  both 1200 baud AFSK and 9600 baud FSK if you want (but obviously you
-  can only use one protocol at a time, depending on what the other end
-  can understand).
-
-Serial port KISS driver for AX.25
-CONFIG_MKISS
-  KISS is the protocol used to send IP traffic over AX.25 radio
-  connections, somewhat similar to SLIP for telephone lines. Say Y
-  here if you intend to send Internet traffic over amateur radio,
-  using some device connected to your machine's serial port. In that
-  case, you also have to say Y to "Amateur Radio AX.25 Level 2"
-  support.  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 mkiss.o.
-
-Serial port 6PACK driver for AX.25
-CONFIG_6PACK
-6pack is a protocol that attaches a TNC connected to a serial interface
-to be used as a network device. 6pack can be used as an alternative to KISS,
-but has some extended functionality. Note that this driver is still
-experimental and might cause problems. For details about the features
-and the usage of the driver, read Documentation/networking/6pack.txt.
+  Analog Devices (such as AD1848, AD1845) or Crystal
+  Semiconductors (such as CS4248, CS423x).
 
 PLIP (parallel port) support
 CONFIG_PLIP
@@ -3529,27 +3871,31 @@
   drive (a minimal system has to be transferred with floppies
   first). The kernels on both machines need to have this PLIP option
   enabled for this to work.
+
   The PLIP driver has two modes, mode 0 and mode 1. The parallel ports
   (the connectors at the computers with 25 holes) are connected with
   "null printer" or "Turbo Laplink" cables which can transmit 4 bits
   at a time (mode 0) or with special PLIP cables, to be used on
   bidirectional parallel ports only, which can transmit 8 bits at a
   time (mode 1); you can find the wiring of these cables in
-  Documentation/networking/PLIP.txt. The cables can be up to 15m
-  long. Mode 0 works also if one of the machines runs DOS/Windows and
-  has some PLIP software installed, e.g. the Crynwr PLIP packet driver
-  (http://www.kanren.net/pktdrvr-info.html; to browse the WWW, you
-  need to have access to a machine on the Internet that has a program
-  like lynx or netscape) and winsock or NCSA's telnet.  If you want to
-  use PLIP, say Y and read the PLIP mini-HOWTO, available via ftp
-  (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini as
-  well as the NET-2-HOWTO in
-  sunsite.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 8kB. If you want to compile this as a module (= code which
-  can be inserted in and removed from the running kernel whenever you
-  want), say M here and read Documentation/modules.txt as well as
+  Documentation/networking/PLIP.txt. The cables can be up to 15m long.
+  Mode 0 works also if one of the machines runs DOS/Windows and has
+  some PLIP software installed, e.g. the Crynwr PLIP packet driver
+  (http://oak.oakland.edu/simtel.net/msdos/pktdrvr-pre.html; to browse
+  the WWW, you need to have access to a machine on the Internet that
+  has a program like lynx or netscape) and winsock or NCSA's telnet.
+
+  If you want to use PLIP, say Y and read the PLIP mini-HOWTO,
+  available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini as well as the
+  NET-2-HOWTO in ftp://sunsite.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 8kB.
+
+  If you want to compile this as a module (= code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt. The module will be called
   plip.o. If unsure, say Y or M, in case you buy a laptop later.
 
@@ -3562,11 +3908,13 @@
   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. 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 eql.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt. If unsure, say N.
+  want this and read Documentation/networking/eql.txt. 
+
+  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 eql.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt. If unsure,
+  say N.
 
 Ethertap network tap
 CONFIG_ETHERTAP
@@ -3582,10 +3930,11 @@
   device tap0 can instead be read by the user from /dev/tap0: the user
   mode program replaces the LAN that would be attached to an ordinary
   Ethernet device.  Please read the file
-  Documentation/networking/ethertap.txt for more information.  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 ethertap.o. If you want to compile it as a
+  Documentation/networking/ethertap.txt for more information.  
+
+  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 ethertap.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt. If you don't
   know what to use this for, you don't need it.
 
@@ -3601,12 +3950,13 @@
   http://www.frforum.com/ 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.) To use frame relay, you need supporting hardware
-  (FRAD) and certain programs from the net-tools package as explained
-  in Documentation/networking/framerelay.txt. 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 dlci.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt.
+  (called FRAD) and certain programs from the net-tools package as
+  explained in Documentation/networking/framerelay.txt.
+
+  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 dlci.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Max open DLCI
 CONFIG_DLCI_COUNT
@@ -3626,39 +3976,71 @@
   Say Y here if you need a driver for the Sangoma S502A, S502E, and
   S508 Frame Relay Access Devices. These are multi-protocol cards, but
   only frame relay is supported by the driver at this time. Please
-  read Documentation/framerelay.txt. 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
-  sdla.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  read Documentation/framerelay.txt. 
+
+  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 sdla.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
+WAN Router
+CONFIG_WAN_ROUTER
+  Wide Area Networks (WANs), such as X.25, frame relay and leased
+  lines, are used to interconnect Local Area Networks (LANs) over vast
+  distances with data transfer rates significantly higher than those
+  achievable with commonly used asynchronous modem connections.
+  Usually, a quite expensive external device called a `WAN router' is
+  needed to connect to a WAN.
+
+  As an alternative, WAN routing can be built into the Linux kernel.
+  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
+  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.
+
+Fast switching (read help!)
+CONFIG_NET_FASTROUTE
+  Saying Y here enables direct NIC-to-NIC (NIC = Network Interface
+  Card) data transfers, which is fast.
+
+    *** This option is NOT COMPATIBLE with several important ***
+    *** networking options: especially CONFIG*FIREWALL.      ***
+
+  However, it will work with all options in CONFIG_IP_ADVANCED_ROUTER
+  section (except for CONFIG_IP_ROUTE_TOS). At the moment, few devices
+  support fast switching (tulip is one of them, modified 8390 can be
+  found at ftp://ftp.inr.ac.ru/ip-routing/fastroute-8390.tar.gz). 
+
+  If unsure, say N.
+
+Forwarding between high speed interfaces
+CONFIG_NET_HW_FLOWCONTROL
+  This option enables NIC (Network Interface Card) hardware throttling
+  during periods of extremal congestion. At the moment only a couple
+  of device drivers support it (really only one ---tulip, modified
+  8390 can be found at
+  ftp://ftp.inr.ac.ru/ip-routing/fastroute-8390.tar.gz). Really, this
+  option is applicable to any machine attached to a fast enough
+  network, and even a 10Mb NIC is able to kill a not very slow box,
+  such as a 120MHz Pentium.
 
-WAN Router
-CONFIG_WAN_ROUTER
-  Wide Area Networks (WANs), such as X.25, frame relay and leased
-  lines, are used to interconnect Local Area Networks (LANs) over vast
-  distances with data transfer rates significantly higher than those
-  achievable with commonly used asynchronous modem connections.
-  Usually, a quite expensive external device called a `WAN router' is
-  needed to connect to a WAN.
-  As an alternative, WAN routing can be built into the Linux
-  kernel.  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 (with appropriate WAN Link Driver) and wish to use your Linux
-  box as a WAN router, you may say 'Y' to this option.  You will also
-  need a wan-tools package available via FTP (user: anonymous) from
-  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.
+  However, do not say Y here if you did not experience any serious
+  problems.
 
 CPU is too slow to handle full bandwidth
 CONFIG_CPU_IS_SLOW
-###
-### How to know when the CPU is too slow?
-###
+  If you suspect that your CPU is not fast enough to handle the
+  full bandwidth of your network connection, try saying Y here. If
+  unsure, say N.
 
 QoS and/or fair queueing
 CONFIG_NET_SCHED
@@ -3670,7 +4052,12 @@
   called packet schedulers. You can attach different schedulers to
   different network devices. If you want to stick to the default
   scheduling algorithm, say N here. If you want to experiment with a
-  couple of different algorithms, say Y. The available schedulers are
+  couple of different algorithms, say Y. 
+
+  To administer these schedulers, you'll need the user-level utilities
+  from the package iproute2+tc at ftp://ftp.inr.ac.ru/ip-routing/
+
+  The available schedulers are
   listed in the following questions; you can say Y to as many as you
   like.  If unsure, say N now.
 
@@ -3683,11 +4070,11 @@
   separate algorithms (called "disciplines" in this context) which you
   can choose below from among the "auxiliary disciplines".  See the top
   of net/sched/sch_cbq.c for references about the CBQ algorithm.
-  This code is also available as a
-  module called sch_cbq.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.
+
+  This code is also available as a module called sch_cbq.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.
 
 CSZ packet scheduler
 CONFIG_NET_SCH_CSZ
@@ -3695,21 +4082,26 @@
   scheduling algorithm for some of your network devices. At the
   moment, this is the only algorithm that can guarantee service for
   real-time applications (see the top of net/sched/sch_csz.c for
-  details and references about the algorithm). This code is also
-  available as a module called sch_csz.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.
+  details and references about the algorithm). 
+  
+  Note: this scheduler is currently broken.
+
+  This code is also available as a module called sch_csz.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.
 
 RED queueing discipline
 CONFIG_NET_SCH_RED
   Say Y here if you want to use the Random Early Detection (RED)
   packet scheduling algorithm for some of your network devices (see
   the top of net/sched/sch_red.c for details and references about the
-  algorithm). This code is also available as a module called sch_red.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.
+  algorithm). 
+
+  This code is also available as a module called sch_red.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.
 
 SFQ queueing discipline
 CONFIG_NET_SCH_SFQ
@@ -3717,45 +4109,46 @@
   packet scheduling algorithm for some of your network devices or as a
   leaf discipline for the CBQ scheduling algorithm (see the top of
   net/sched/sch_sfq.c for details and references about the SFQ
-  algorithm). This code is also available as a module called sch_sfq.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.
+  algorithm). 
+
+  This code is also available as a module called sch_sfq.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.
 
 auxiliary TBF queue
 CONFIG_NET_SCH_TBF
   Say Y here if you want to use the Simple Token Bucket Filter (TBF)
   packet scheduling algorithm for some of your network devices or as a
   leaf discipline for the CBQ scheduling algorithm (see the top of
-  net/sched/sch_tbf.c for a description of the TBF algorithm). This code
-  is also available as a module called sch_tbf.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.
+  net/sched/sch_tbf.c for a description of the TBF algorithm). 
+
+  This code is also available as a module called sch_tbf.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.
 
 auxiliary FIFO queue
 CONFIG_NET_SCH_PFIFO
   Say Y here if you want to use a simple FIFO (first in - first out)
   packet "scheduler" for some of your network devices or as a leaf
-  discipline for the CBQ scheduling algorithm. This code is also
-  available as a module called sch_fifo.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.
+  discipline for the CBQ scheduling algorithm. 
+
+  This code is also available as a module called sch_fifo.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.
 
 auxiliary PRIO queue
 CONFIG_NET_SCH_PRIO
   Say Y here if you want to use an n-band priority queue packet
   "scheduler" for some of your network devices or as a leaf discipline
-  for the CBQ scheduling algorithm. This code is also available as a
-  module called sch_prio.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.
-###
-### what user level programs are needed to administrate these packet 
-### schedulers?
-###
+  for the CBQ scheduling algorithm. 
+
+  This code is also available as a module called sch_prio.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.
 
 Network code profiler
 CONFIG_NET_PROFILE
@@ -3766,16 +4159,16 @@
 
 WAN Drivers
 CONFIG_WAN_DRIVERS
-  Say Y to this option if you are planning to use your Linux box as a
-  WAN ( = Wide Area Network) router ( = device used to interconnect
-  local area networks over wide area communication links, such as
-  leased lines and public data networks, e.g. X.25 and frame relay)
-  and you will be offered a list of WAN drivers currently available.
-  For more information, read
+  Say Y to this option if your Linux box contains a WAN card and you
+  are planning to use the box as a WAN ( = Wide Area Network) router (
+  = device used to interconnect local area networks over wide area
+  communication links, such as leased lines and public data networks,
+  e.g. X.25 and frame relay) and you will be offered a list of drivers
+  for WAN cards currently available. For more information, read
   Documentation/networking/wan-router.txt. Note that the answer to
   this question won't directly affect the kernel: saying N will just
   cause this configure script to skip all the questions about WAN
-  drivers. If unsure, say N.
+  card drivers. If unsure, say N.
 
 Sangoma WANPIPE(tm) multiprotocol cards
 CONFIG_VENDOR_SANGOMA
@@ -3788,11 +4181,12 @@
   Frame Relay, and PPP protocols. If you have one or more of these
   cards, say Y to this option and read
   Documentation/networking/wanpipe.txt.  The next questions will ask
-  you about the protocols you want the driver to support. 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 wanpipe.o.  For general information about modules read
-  Documentation/modules.txt.
+  you about the protocols you want the driver to support. 
+
+  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 wanpipe.o. For general information about
+  modules read Documentation/modules.txt.
 
 Maximum number of cards
 CONFIG_WANPIPE_CARDS
@@ -3826,93 +4220,117 @@
   you say N, the PPP support will not be included in the driver (saves
   about 16K of kernel memory).
 
+Ethernet (10 or 100Mbit)
+CONFIG_NET_ETHERNET
+  Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
+  type of Local Area Networks (LANs) in universities or
+  companies. 10-base-2 or Thinnet (10 Mbps over coaxial cable, linking
+  computers in a chain), 10-base-T (10 Mbps over twisted pair
+  telephone cable, linking computers to a central hub) and
+  100-base-<whatever> (100 Mbps) are common types of Ethernet. 
+
+  If your Linux machine will be connected to an Ethernet and you have
+  an Ethernet network card installed in your computer, say Y here and
+  read the Ethernet-HOWTO, available via ftp (user: anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+
+  Note that the answer to this question won't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the questions about Ethernet network cards. If unsure, say N.
+
 Sun LANCE Ethernet support
 CONFIG_SUN_LANCE
   This is support for lance Ethernet cards on Sun workstations such as
   the Sparcstation IPC (any Sparc with a network interface 'le0' under
-  SunOS basically). 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 lance.o. If you want
-  to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  SunOS basically). 
+
+  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 lance.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Sun Intel Ethernet support
 CONFIG_SUN_INTEL
   This is support for the Intel Ethernet cards on some Sun workstations
   (all those with a network interface 'ie0' under SunOS).
 
-Ethernet (10 or 100Mbit)
-CONFIG_NET_ETHERNET
-  Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
-  type of Local Area Networks (LANs) in universities or
-  companies. 10-base-2 or Thinnet (10 Mbps over coaxial cable, linking
-  computers in a chain), 10-base-T (10 Mbps over twisted pair
-  telephone cable, linking computers to a central hub) and
-  100-base-<whatever> (100 Mbps) are common types of Ethernet. If your
-  Linux machine will be connected to an Ethernet and you have an
-  Ethernet network card installed in your computer, say Y here and
-  read the Ethernet-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  Note that the answer to this
-  question won't directly affect the kernel: saying N will just cause
-  this configure script to skip all the questions about Ethernet
-  network cards. If unsure, say N.
-
 Western Digital/SMC cards
 CONFIG_NET_VENDOR_SMC
   If you have a network (Ethernet) card belonging to this class, say Y
   and read the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that the answer to this
-  question doesn't directly affect the kernel: saying N will just
-  cause this configure script to skip all the questions about Western
-  Digital cards. If you say Y, you will be asked for your specific
-  card in the following questions.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+
+  Note that the answer to this question doesn't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the questions about Western Digital cards. If you say Y, you will be
+  asked for your specific card in the following questions.
 
 WD80*3 support
 CONFIG_WD80x3
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  wd.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called wd.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
+
+SMC Ultra MCA support
+CONFIG_ULTRAMCA
+  If you have a network (Ethernet) card of this type and are running
+  an MCA based system (PS/2), say Y and read
+  the Ethernet-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.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).
+  The module will be called smc-mca.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 SMC Ultra support
 CONFIG_ULTRA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  smc-ultra.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt.
-  Important: There have been many reports that, with some motherboards 
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  
+  Important: There have been many reports that, with some motherboards
   mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
-  such as some BusLogic models) causes corruption problems with many 
-  operating systems. The linux smc-ultra driver has a work-around for this
-  but keep it in mind if you have such a SCSI card and have problems.
+  such as some BusLogic models) causes corruption problems with many
+  operating systems. The Linux smc-ultra driver has a work-around for
+  this but keep it in mind if you have such a SCSI card and have
+  problems.
+
+  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 smc-ultra.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt. 
 
 SMC Ultra32 EISA support
 CONFIG_ULTRA32
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  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 smc-ultra32.o. If you want to compile it as a module, say M
-  here and read Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. 
+  ftp://sunsite.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).
+  The module will be called smc-ultra32.o. If you want to compile it
+  as a module, say M here and read Documentation/modules.txt as well
+  as Documentation/networking/net-modules.txt.
 
 SMC 9194 Support
 CONFIG_SMC9194
-  This is support for the SMC9xxx based Ethernet cards.  Choose this
+  This is support for the SMC9xxx based Ethernet cards. Choose this
   option if you have a DELL laptop with the docking station, or
-  another SMC9192/9194 based chipset.  Say Y if you want it compiled
+  another SMC9192/9194 based chipset. Say Y if you want it compiled
   into the kernel, and read the the file
   Documentation/networking/smc9.txt and the Ethernet-HOWTO, available
-  via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  via ftp (user: anonymous) in
+  ftp://sunsite.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). The module will be called smc9194.o. If you want to compile
@@ -3924,7 +4342,8 @@
   If you have a network (Ethernet) card belonging to this class, such
   as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
   available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
   the questions about NI cards. If you say Y, you will be asked for
@@ -3934,76 +4353,82 @@
 CONFIG_NI5010
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that this is still
-  experimental code. 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
-  ni5010.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that this is still
+  experimental code. 
+
+  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 ni5010.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 NI5210 support
 CONFIG_NI52
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  ni52.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called ni52.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 NI6510 support
 CONFIG_NI65
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  ni65.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called ni65.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 AMD LANCE and PCnet (AT1500 and NE2100) support
 CONFIG_LANCE
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Some LinkSys cards are of
-  this type.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Some LinkSys cards are
+  of this type.
 
 3COM cards
 CONFIG_NET_VENDOR_3COM
   If you have a network (Ethernet) card belonging to this class, say Y
-  and read the Ethernet-HOWTO, available via ftp (user: anonymous)
-  in sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that the answer to
-  this question doesn't directly affect the kernel: saying N will just
-  cause this configure script to skip all the questions about 3COM
-  cards. If you say Y, you will be asked for your specific card in the
-  following questions.
+  and read the Ethernet-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  Note that the answer to this question doesn't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the questions about 3COM cards. If you say Y, you will be asked for
+  your specific card in the following questions.
 
 3c501 support
 CONFIG_EL1
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  Also, consider buying a new
-  card, since the 3c501 is slow, broken, and obsolete: you will have
-  problems. Some people suggest to ping ("man ping") a nearby machine
-  every minute ("man cron") when using this 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 3c501.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt as well as
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Also, consider buying a
+  new card, since the 3c501 is slow, broken, and obsolete: you will
+  have problems. Some people suggest to ping ("man ping") a nearby
+  machine every minute ("man cron") when using this 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 3c501.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 3c503 support
 CONFIG_EL2
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  3c503.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called 3c503.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 3c505 support
@@ -4011,10 +4436,11 @@
   Information about this network (Ethernet) card can be found in
   Documentation/networking/3c505.txt. If you have a card of this type,
   say Y and read the Ethernet-HOWTO, available via ftp (user:
-  anonymous) in 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 as well as
+  anonymous) in 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 as well as
   Documentation/networking/net-modules.txt. The module will be called
   3c505.o.
 
@@ -4022,48 +4448,56 @@
 CONFIG_EL16
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  3c507.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called 3c507.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 3c523 support 
 CONFIG_ELMC
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  3c523.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called 3c523.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 3c509/3c579 support
 CONFIG_EL3
   If you have a network (Ethernet) card belonging to the 3Com
   EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
-  via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  If your card is not working you may need to use the DOS
+  setup disk to disable Plug & Play mode, and to select the default
+  media type.
+
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt. The module will be called
-  3c509.o. If your card is not working you may need to use the DOS
-  setup disk to disable Plug & Play mode, and to select the default
-  media type.
+  3c509.o. 
 
 3c590 series (592/595/597) "Vortex" support
 CONFIG_VORTEX
-  If you have a network (Ethernet) card of this type, say Y and read
-  the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. More specific information is
-  in Documentation/networking/vortex.txt and in the comments at the
-  beginning of drivers/net/3c59x.c. If you want to compile this as a
-  module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), say M here and read
-  Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. 
+  If you have a 3Com "Vortex" or "Boomerang" series network (Ethernet)
+  card (Fast EtherLink 3c590/3c592/3c595/3c597 or the EtherLink XL
+  3c900 or 3c905), say Y and read the Ethernet-HOWTO, available via
+  ftp (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  More specific information is in Documentation/networking/vortex.txt
+  and in the comments at the beginning of drivers/net/3c59x.c.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
 
 Other ISA cards
 CONFIG_NET_ISA
@@ -4071,28 +4505,33 @@
   bus system (that's the way the components of the card talk to each
   other) is ISA (as opposed to EISA, VLB or PCI), say Y. Make sure you
   know the name of your card. Read the Ethernet-HOWTO, available via
-  ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. If
-  unsure, say Y.  Note that the answer to this question doesn't
-  directly affect the kernel: saying N will just cause this configure
-  script to skip all the remaining ISA network card questions.  If you
-  say Y, you will be asked for your specific card in the following
-  questions.
+  ftp (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  If unsure, say Y.
+
+  Note that the answer to this question doesn't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the remaining ISA network card questions. If you say Y, you will be
+  asked for your specific card in the following questions.
 
 Generic ARCnet support
 CONFIG_ARCNET
   If you have a network card of this type, say Y and check out the
   (arguably) beautiful poetry in Documentation/networking/arcnet.txt.
+
   You need both this driver, and the driver for the particular ARCnet
   chipset of your card. If you don't know, then it's probably a 
   COM90xx type card, so say Y (or M) to "ARCnet COM90xx chipset support"
   below.
+
   You might also want to have a look at the Ethernet-HOWTO, available
-  via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO
-  (even though ARCnet is not really Ethernet). 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 arcnet.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt as well as
+  via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO (even though ARCnet is
+  not really Ethernet).
+
+  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 arcnet.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 Enable arc0e (ARCnet "ether-encap" packet format)
@@ -4124,23 +4563,26 @@
 CONFIG_ARCNET_COM90xx
   This is the chipset driver for the standard COM90xx cards. If you
   have always used the old arcnet driver without knowing what type of
-  card you had, this is probably the one for you. 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 com90xx.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt as well as
+  card you had, this is probably the one for you. 
+
+  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 com90xx.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 ARCnet COM90xx (IO mapped) chipset driver
-CONFIG_ARCNET_COM90x
+CONFIG_ARCNET_COM90xxIO
   This is the chipset driver for the COM90xx cards, using them in
   IO-mapped mode instead of memory-mapped mode. This is slower than
   the normal driver.  Only use it if your card doesn't support shared
-  memory. 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 com90io.o. If you want to compile
-  it as a module, say M here and read Documentation/modules.txt as
-  well as Documentation/networking/net-modules.txt.
+  memory. 
+
+  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 com90io.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
 
 ARCnet COM90xx (RIM I) chipset driver
 CONFIG_ARCNET_RIM_I
@@ -4148,6 +4590,7 @@
   time only using memory-mapped mode, and no IO ports at all. This
   driver is completely untested, so if you have one of these cards,
   please mail dwmw2@cam.ac.uk, especially if it works!
+
   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 arc-rimi.o. If you want to compile
@@ -4158,34 +4601,37 @@
 CONFIG_ARCNET_COM20020
   This is the driver for the new COM20020 chipset. It supports such
   things as promiscuous mode, so packet sniffing is possible, and
-  extra diagnostic information. 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
-  com20020.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt as well as
+  extra diagnostic information. 
+
+  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 com20020.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 Cabletron E21xx support
 CONFIG_E2100
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  e2100.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called e2100.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 CS89x0 support
 CONFIG_CS89x0
-  Support for CS89x0 chipset based Ethernet cards.  If you have a
+  Support for CS89x0 chipset based Ethernet cards. If you have a
   network (Ethernet) card of this type, say Y and read the
   Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO as well as
-  Documentation/networking/cs89x0.txt.  If you want to compile this as
-  a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as
+  Documentation/networking/cs89x0.txt.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt. The module will be called
   cs89x.o.
 
@@ -4193,12 +4639,14 @@
 CONFIG_DEPCA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO as well as
-  drivers/net/depca.c.  If you want to compile this as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want), say M here and read Documentation/modules.txt as
-  well as Documentation/networking/net-modules.txt. The module will be
-  called depca.o.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as
+  drivers/net/depca.c.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt. The module will be called
+  depca.o.
 
 EtherWorks 3 support
 CONFIG_EWRK3
@@ -4206,10 +4654,11 @@
   cards. If this is for you, say Y and read
   Documentation/networking/ewrk3.txt in the kernel source as well as
   the Ethernet-HOWTO, available via ftp (user: anonymous) from
-  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 as well as
+  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 as well as
   Documentation/networking/net-modules.txt. The module will be called
   ewrk3.o.
 
@@ -4217,16 +4666,18 @@
 CONFIG_SEEQ8005
   This is a driver for the SEEQ 8005 network (Ethernet) card. If this
   is for you, read the Ethernet-HOWTO, available via ftp (user:
-  anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 AT1700 support
 CONFIG_AT1700
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. This driver is also available
-  as a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want). If you want to compile it as a
-  module, say M here and read Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt. The module will be called
   at1700.o.
 
@@ -4234,24 +4685,27 @@
 CONFIG_FMV18X
   If you have a Fujitsu FMV-181/182/183/184 network (Ethernet) card,
   say Y and read the Ethernet-HOWTO, available via ftp (user:
-  anonymous) in sunsite.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). The module will
-  be called fmv18x.o. If you want to compile it as a module, say M
-  here and read Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. If you use an FMV-183 or
-  FMV-184 and it is not working, you may need to disable Plug & Play
-  mode of the card.
+  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  If you use an FMV-183 or FMV-184 and it is not working, you may need
+  to disable Plug & Play mode of the 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 fmv18x.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt. 
 
 EtherExpressPro support
 CONFIG_EEXPRESS_PRO
   If you have a network (Ethernet) card of this type, say Y. Note
   however that the EtherExpressPro 100 Ethernet card has its own
   separate driver. Please read the Ethernet-HOWTO, available via ftp
-  (user: anonymous) in sunsite.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). The
-  module will be called eepro.o. If you want to compile it as a
+  (user: anonymous) in ftp://sunsite.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).
+  The module will be called eepro.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
@@ -4259,67 +4713,50 @@
 CONFIG_EEXPRESS
   If you have an EtherExpress16 network (Ethernet) card, say Y and
   read the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that the Intel
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that the Intel
   EtherExpress16 card used to be regarded as a very poor choice
   because the driver was very unreliable. We now have a new driver
-  that should do better. 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 as well as
+  that should do better.
+
+  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 as well as
   Documentation/networking/net-modules.txt. The module will be called
   eexpress.o.
 
-AT&T WaveLAN & DEC RoamAbout DS support
-CONFIG_WAVELAN
-  The Lucent Wavelan (formerly NCR and AT&T ; or DEC RoamAbout DS) is
-  a Radio LAN (wireless Ethernet-like Local Area Network) using the
-  radio frequencies 900 MHz and 2.4 GHz.
-  This driver support the ISA version of the Wavelan card. A driver
-  for the pcmcia hardware is available in David Hinds's pcmcia
-  package.
-  If you want to use a card of this type under Linux, say Y and read
-  the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Some more specific
-  information is contained in
-  Documentation/networking/wavelan.txt. You will also need the
-  wireless tools package available from
-  ftp://ftp.inka.de/pub/comp/Linux/networking/NetTools/contrib/.
-  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 wavelan.o. If you want to compile
-  it as a module, say M here and read Documentation/modules.txt as
-  well as Documentation/networking/net-modules.txt.
-
 HP PCLAN+ (27247B and 27252A) support
 CONFIG_HPLAN_PLUS
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  hp-plus.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called hp-plus.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 HP PCLAN (27245 and other 27xxx series) support
 CONFIG_HPLAN
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  hp.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called hp.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 HP 10/100VG PCLAN (ISA, EISA, PCI) support
 CONFIG_HP100
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to compile this
-  as a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), say M here and read
-  Documentation/modules.txt as well as
+  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 as well as
   Documentation/networking/net-modules.txt. The module will be called
   hp100.o.
 
@@ -4327,82 +4764,89 @@
 CONFIG_NE2000
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Many Ethernet cards without a
-  specific driver are compatible with NE2000. 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 ne.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt as well as
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Many Ethernet cards
+  without a specific driver are compatible with NE2000.
+
+  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 ne.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 SK_G16 support
 CONFIG_SK_G16
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 EISA, VLB, PCI and on board controllers
 CONFIG_NET_EISA
   This is another class of network cards which attach directly to the
   bus. If you have one of those, say Y and read the Ethernet-HOWTO,
   available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that the answer to this
-  question doesn't directly affect the kernel: saying N will just
-  cause this configure script to skip all the questions about this
-  class of network cards. If you say Y, you will be asked for your
-  specific card in the following questions. If you are unsure, say Y.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  Note that the answer to this question doesn't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the questions about this class of network cards. If you say Y, you
+  will be asked for your specific card in the following questions. If
+  you are unsure, say Y.
 
 AMD PCnet32 (VLB and PCI) support
 CONFIG_PCNET32
   If you have a PCnet32 or PCnetPCI based network (Ethernet) card, say
   Y here and read the Ethernet-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. 
+  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 Ansel Communications EISA 3200 support
 CONFIG_AC3200
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  ac3200.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called ac3200.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 Racal-Interlan EISA ES3210 support
 CONFIG_ES3210
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  es3210.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  ftp://sunsite.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).
+  The module will be called es3210.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 Apricot Xen-II on board Ethernet
 CONFIG_APRICOT
   If you have a network (Ethernet) controller of this type, say Y and
   read the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  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 as well as
+  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 as well as
   Documentation/networking/net-modules.txt. The module will be called
   apricot.o.
 
 Generic DECchip & DIGITAL EtherWORKS PCI/EISA
 CONFIG_DE4X5
-  This is support for the DIGITAL series of PCI/EISA Ethernet
-  cards. These include the DE425, DE434, DE435, DE450 and DE500
-  models. If you have a network card of this type, say Y and read the
+  This is support for the DIGITAL series of PCI/EISA Ethernet cards.
+  These include the DE425, DE434, DE435, DE450 and DE500 models. If
+  you have a network card of this type, say Y and read the
   Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  More specific information is
-  contained in Documentation/networking/de4x5.txt. 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 de4x5.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt as well as
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific
+  information is contained in Documentation/networking/de4x5.txt.
+
+  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 de4x5.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 DECchip Tulip (dc21x4x) PCI support
@@ -4414,59 +4858,83 @@
   (smc9332dst), you can also try the driver for "Generic DECchip"
   cards, above. However, most people with a network card of this type
   will say Y here.) Do read the Ethernet-HOWTO, available via ftp
-  (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. More
-  specific information is contained in
-  Documentation/networking/tulip.txt. 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
-  tulip.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
+  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  More specific information is contained in
+  Documentation/networking/tulip.txt.
+
+  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 tulip.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
 Digi Intl. RightSwitch support
 CONFIG_DGRS
   This is support for the Digi International RightSwitch series of
-  PCI/EISA Ethernet switch cards.  These include the SE-4 and the SE-6
+  PCI/EISA Ethernet switch cards. These include the SE-4 and the SE-6
   models. If you have a network card of this type, say Y and read the
   Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  More specific information is
-  contained in Documentation/networking/dgrs.txt. 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 dgrs.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. 
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific
+  information is contained in Documentation/networking/dgrs.txt.
+
+  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 dgrs.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
 
 EtherExpressPro/100 support
 CONFIG_EEXPRESS_PRO100
   If you have an Intel EtherExpressPro 100 PCI network (Ethernet)
   card, say Y and read the Ethernet-HOWTO, available via ftp (user:
-  anonymous) in sunsite.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). The module will
-  be called eepro100.o. If you want to compile it as a module, say M
-  here and read Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. 
+  anonymous) in ftp://sunsite.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).
+  The module will be called eepro100.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
 
 ICL EtherTeam 16i/32 support
 CONFIG_ETH16I
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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
-  eth16i.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. 
+  ftp://sunsite.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).
+  The module will be called eth16i.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
 
 TI ThunderLAN support (EXPERIMENTAL)
 CONFIG_TLAN
   If you have a TLAN based network card which is supported by this
-  driver, say Y and read the Ethernet-HOWTO.  Devices currently
-  supported are the Compaq Netelligent 10, Netelligent 10/100, and
-  Internal NetFlex 3.  This driver is also available as a module.  The
-  module will be called tlan.o. Please email feedback to
-  james.banks@caldera.com.
+  driver, say Y and read the Ethernet-HOWTO, available via ftp (user:
+  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Devices
+  currently supported are the Compaq Netelligent 10, Netelligent
+  10/100, and Internal NetFlex 3.
+
+  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 tlan.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
+
+  Please email feedback to james.banks@caldera.com.
+
+SMC EtherPower II (EXPERIMENTAL)
+CONFIG_EPIC100
+  If you have an SMC EtherPower II 9432 PCI ethernet network card
+  which is based on the SMC83c170, say Y and read the Ethernet-HOWTO,
+  available via ftp (user: anonymous) in
+  ftp://sunsite.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).
+  The module will be called epic100.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt as well as
+  Documentation/networking/net-modules.txt.
 
 Zenith Z-Note support
 CONFIG_ZNET
@@ -4474,35 +4942,38 @@
   (Ethernet) card, and this is the Linux driver for it. Note that the
   IBM Thinkpad 300 is compatible with the Z-Note and is also supported
   by this driver. Read the Ethernet-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 Pocket and portable adapters
 CONFIG_NET_POCKET
   Cute little network (Ethernet) devices which attach to the parallel
   port ("pocket adapters"), commonly used with laptops. If you have
   one of those, say Y and read the Ethernet-HOWTO, available via ftp
-  (user: anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you
-  want to plug a network card into the PCMCIA slot of your laptop
-  instead (PCMCIA is the standard for credit card size extension cards
-  used by all modern laptops), look on the ftp site (user: anonymous)
-  cb-iris.stanford.edu:/pub/pcmcia and say N here.  
+  (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  If you want to plug a network card into the PCMCIA slot of your
+  laptop instead (PCMCIA is the standard for credit card size
+  extension cards used by all modern laptops), look on the ftp site
+  (user: anonymous) ftp://cb-iris.stanford.edu/pub/pcmcia and say N
+  here.
+
   Laptop user want to read the Linux Laptop homepage at
   http://www.cs.utexas.edu/users/kharker/linux-laptop/ (to browse the
   WWW, you need to have access to a machine on the Internet that has a
-  program like lynx or netscape).
+  program like lynx or netscape). 
+
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
-  the questions about this class of network devices.  If you say Y,
-  you will be asked for your specific device in the following
-  questions.
+  the questions about this class of network devices. If you say Y, you
+  will be asked for your specific device in the following questions.
 
 AT-LAN-TEC/RealTek pocket adapter support
 CONFIG_ATP
   This is a network (Ethernet) device which attaches to your parallel
   port. Read drivers/net/atp.c as well as the Ethernet-HOWTO,
   available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO if you want to use this. If
-  you intend to use this driver, you should have said N to the
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
+  If you intend to use this driver, you should have said N to the
   Parallel Printer support, because the two drivers don't like each
   other.
 
@@ -4511,26 +4982,28 @@
   This is a network (Ethernet) device which attaches to your parallel
   port. Read Documentation/networking/DLINK.txt as well as the
   Ethernet-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO if you want to use this. It is
-  possible to have several devices share a single parallel port and it
-  is safe to compile the corresponding drivers into the kernel. If you
-  want to compile this driver as a module however ( = 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 de600.o.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
+  It is possible to have several devices share a single parallel port
+  and it is safe to compile the corresponding drivers into the kernel.
+
+  If you want to compile this driver as a module however ( = 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 de600.o.
 
 D-Link DE620 pocket adapter support
 CONFIG_DE620
   This is a network (Ethernet) device which attaches to your parallel
   port. Read Documentation/networking/DLINK.txt as well as the
   Ethernet-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO if you want to use this. It is
-  possible to have several devices share a single parallel port and it
-  is safe to compile the corresponding drivers into the kernel. If you
-  want to compile this driver as a module however ( = 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 de620.o.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
+  It is possible to have several devices share a single parallel port
+  and it is safe to compile the corresponding drivers into the kernel.
+
+  If you want to compile this driver as a module however ( = 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 de620.o.
 
 Token Ring driver support
 CONFIG_TR
@@ -4538,34 +5011,41 @@
   rest of the world uses Ethernet. To participate on a Token Ring
   network, you need a special Token ring network card. If you are
   connected to such a Token Ring network and want to use your Token
-  Ring card under Linux, say Y here and read the Token-Ring
-  mini-HOWTO, available via ftp (user:anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Most people can say N here.
+  Ring card under Linux, say Y here and to the driver for your
+  particular card below and read the Token-Ring mini-HOWTO, available
+  via ftp (user:anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Most people can say N
+  here.
 
 IBM Tropic chipset based adapter support
 CONFIG_IBMTR
   This is support for all IBM Token Ring cards that don't use DMA. If
   you have such a beast, say Y and read the Token-Ring mini-HOWTO,
   available via ftp (user:anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Warning: this driver will
-  almost definitely fail if more than one active Token Ring card is
-  present. 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 ibmtr.o. If you want to compile it
-  as a module, say M here and read Documentation/modules.txt.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  Warning: this driver will almost definitely fail if more than one
+  active Token Ring card is present. 
+
+  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 ibmtr.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Traffic Shaper (EXPERIMENTAL)
 CONFIG_SHAPER
   The traffic shaper is a virtual network device that allows you to
-  limit the rate of outgoing data flow over another network
+  limit the rate of outgoing data flow over some other network
   device. See Documentation/networking/shaper.txt for more
   information.  To set up and configure shaper devices, you need the
   shapecfg program, available via ftp (user: anonymous) from
-  shadow.cabi.net/pub/Linux in the shaper package.  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 shaper.o. If you want to compile it as a module, say M
-  here and read Documentation/modules.txt. If unsure, say N.
+  ftp://shadow.cabi.net/pub/Linux in the shaper package.  
+
+  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 shaper.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt. If unsure,
+  say N.
 
 FDDI driver support
 CONFIG_FDDI
@@ -4585,21 +5065,25 @@
 CONFIG_CD_NO_IDESCSI
   If you have a CDROM drive that is neither SCSI nor IDE/ATAPI, say Y
   here, otherwise N. Read the CDROM-HOWTO, available via ftp (user:
-  anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that the
-  answer to this question doesn't directly affect the kernel: saying N
-  will just cause this configure script to skip all the questions
-  about these CDROM drives. If you are unsure what you have, say Y and
-  find out whether you have one of the following drives.
+  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+
+  Note that the answer to this question doesn't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the questions about these CDROM drives. If you are unsure what you
+  have, say Y and find out whether you have one of the following
+  drives. 
+
   For each of these drivers, a file Documentation/cdrom/<driver_name>
   exists. Especially in cases where you do not know exactly which kind
-  of drive you have you should read there.
-  Most of these drivers use a file drivers/cdrom/<driver_name>.h
-  where you can define your interface parameters and switch some
-  internal goodies.
-  All these CDROM drivers are also usable as a module (= code which can
-  be inserted in and removed from the running kernel whenever you want).
-  If you want to compile them as module, say M instead of Y and read
-  Documentation/modules.txt.
+  of drive you have you should read there. Most of these drivers use a
+  file drivers/cdrom/<driver_name>.h where you can define your
+  interface parameters and switch some internal goodies. 
+
+  All these CDROM drivers are also usable as a module (= code which
+  can be inserted in and removed from the running kernel whenever you
+  want). If you want to compile them as module, say M instead of Y and
+  read Documentation/modules.txt. 
+
   If you want to use any of these CDROM drivers, you also have to say
   Y to "ISO9660 cdrom filesystem support" below (this answer will get
   "defaulted" for you if you enable any of the Linux CDROM drivers).
@@ -4614,34 +5098,41 @@
   parameters into drivers/cdrom/cdu31a.c. Try "man bootparam" or
   see the documentation of your boot loader (lilo or loadlin) about
   how to pass options to the kernel. The lilo procedure is also
-  explained in the SCSI-HOWTO. If you say Y here, you should also say
-  Y to "ISO9660 cdrom filesystem support" below, because that's the
-  filesystem used on CDROMs. 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 cdu31a.o. If
-  you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  explained in the SCSI-HOWTO. 
+
+  If you say Y here, you should also say Y to "ISO9660 cdrom
+  filesystem support" below, because that's the filesystem used on
+  CDROMs. 
+
+  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 cdu31a.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Standard Mitsumi [no XA/Multisession] CDROM support
 CONFIG_MCD
   This is the older of the two drivers for the older Mitsumi models
   LU-005, FX-001 and FX-001D. This is not the right driver for the
   FX-001DE and the triple or quad speed models (all these are
-  IDE/ATAPI models).
+  IDE/ATAPI models). Please also the file Documentation/cdrom/mcd.
+
   With the old LU-005 model, the whole drive chassis slides out for cd
   insertion.  The FX-xxx models use a motorized tray type mechanism.
   Note that this driver does not support XA or MultiSession CDs
   (PhotoCDs).  There is a new driver (next question) which can do
   this. If you want that one, say N here.
+
   If the driver doesn't work out of the box, you might want to have a
-  look at drivers/cdrom/mcd.h.  If you say Y here, you should
-  also say Y to "ISO9660 cdrom filesystem support" below, because
-  that's the filesystem used on CDROMs. Please also read the file
-  Documentation/cdrom/mcd. 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 mcd.o. If you want to
-  compile it as a module, say M here and read
-  Documentation/modules.txt.
+  look at drivers/cdrom/mcd.h.  
+
+  If you say Y here, you should also say Y to "ISO9660 cdrom
+  filesystem support" below, because that's the filesystem used on
+  CDROMs. 
+
+  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 mcd.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Mitsumi [XA/MultiSession] support
 CONFIG_MCDX
@@ -4650,51 +5141,58 @@
   FX-001 or FX-001D CDROM drive. In addition, this driver uses much less
   kernel memory than the old one, if that is a concern. This driver is
   able to support more than one drive, but each drive needs a separate
-  interface card.
+  interface card. Please read the file Documentation/cdrom/mcdx. 
+
   If you say Y here, you should also say Y to "ISO9660 cdrom
   filesystem support" below, because that's the filesystem used on
-  CDROMs. Please also read the file Documentation/cdrom/mcdx. 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 mcdx.o. If you want to compile it as a module,
-  say M here and read Documentation/modules.txt.
+  CDROMs. 
+
+  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 mcdx.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support
 CONFIG_SBPCD
   This driver supports most of the drives which use the Panasonic or
-  SoundBlaster interface.
+  SoundBlaster interface. Please read the file
+  Documentation/cdrom/sbpcd.
+
   The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
   (sometimes labeled "Creative"), the CreativeLabs CD200, the
   Longshine LCS-7260, the "IBM External ISA CDROM" (in fact a CR-56x
   model), the TEAC CD-55A fall under this category. Some other
   "electrically compatible" drives (Vertos, Genoa, some Funai models)
   are currently not supported; for the Sanyo H94A drive currently a
-  separate driver (asked later) is responsible.  Most drives have a
+  separate driver (asked later) is responsible. Most drives have a
   uniquely shaped faceplate, with a caddyless motorized drawer, but
   without external brand markings. The older CR-52x drives have a
-  caddy and manual loading/eject, but still no external markings.  The
+  caddy and manual loading/eject, but still no external markings. The
   driver is able to do an extended auto-probing for interface
   addresses and drive types; this can help to find facts in cases you
   are not sure, but can consume some time during the boot process if
-  none of the supported drives gets found.
-  Once your drive got found, you should enter the reported parameters 
-  into drivers/cdrom/sbpcd.h and set "DISTRIBUTION 0" there.
-  This driver can support up to four CDROM interface cards, and each
+  none of the supported drives gets found. Once your drive got found,
+  you should enter the reported parameters into drivers/cdrom/sbpcd.h
+  and set "DISTRIBUTION 0" there.
+
+  This driver can support up to four CDROM controller cards, and each
   card can support up to four CDROM drives; if you say Y here, you
-  will be asked how many controllers you have. If compiled as a
-  module, only one interface card (but with up to four drives) is
-  usable. 
+  will be asked how many controller cards you have. If compiled as a
+  module, only one controller card (but with up to four drives) is
+  usable.
+
   If you say Y here, you should also say Y to "ISO9660 cdrom
   filesystem support" below, because that's the filesystem used on
-  CDROMs. Please also read the file Documentation/cdrom/sbpcd. 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 sbpcd.o. If you want to compile it as a
+  CDROMs. 
+
+  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 sbpcd.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
 Matsushita/Panasonic, ... second CDROM controller support
 CONFIG_SBPCD2
-  Say Y here only if you have two CDROM controller boards of this type
+  Say Y here only if you have two CDROM controller cards of this type
   (usually only if you have more than four drives). You should enter
   the parameters for the second, third and fourth interface card into
   linux/include/linux/sbpcd.h before compiling the new kernel. Read
@@ -4706,49 +5204,61 @@
   CD-3110, Okano or Wearnes CDD110, Conrad TXC, or CyCDROM CR520 or
   CR540 CDROM drive.  This driver - just like all these CDROM drivers
   - is NOT for CDROM drives with IDE/ATAPI interfaces, such as Aztech
-  CDA269-031SE. If you say Y here, you should also say Y to "ISO9660
-  cdrom filesystem support" below, because that's the filesystem used
-  on CDROMs. Please also read the file Documentation/cdrom/aztcd. 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 aztcd.o. If you want to compile it as a
+  CDA269-031SE. Please read the file Documentation/cdrom/aztcd. 
+
+  If you say Y here, you should also say Y to "ISO9660 cdrom
+  filesystem support" below, because that's the filesystem used on
+  CDROMs.
+
+  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 aztcd.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
 Sony CDU535 CDROM support
 CONFIG_CDU535
   This is the driver for the older Sony CDU-535 and CDU-531 CDROM
-  drives.  If you say Y here, you should also say Y to "ISO9660 cdrom
+  drives. Please read the file Documentation/cdrom/sonycd535.
+
+  If you say Y here, you should also say Y to "ISO9660 cdrom
   filesystem support" below, because that's the filesystem used on
-  CDROMs. Please also read the file Documentation/cdrom/sonycd535. 
+  CDROMs.
+
   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 sonycd535.o. If you want to compile
-  it as a module, say M here and read Documentation/modules.txt.
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called sonycd535.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
 
 Goldstar R420 CDROM support
 CONFIG_GSCD
   If this is your CDROM drive, say Y here.  As described in
   linux/Documentation/cdrom/gscd, you might have to change a setting
   in the file linux/drivers/cdrom/gscd.h before compiling the
-  kernel. Please read the file Documentation/cdrom/gscd. If you say Y
-  here, you should also say Y to "ISO9660 cdrom filesystem support"
-  below, because that's the filesystem used on CDROMs. 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 gscd.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  kernel. Please read the file Documentation/cdrom/gscd. 
+
+  If you say Y here, you should also say Y to "ISO9660 cdrom
+  filesystem support" below, because that's the filesystem used on
+  CDROMs. 
+
+  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 gscd.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Philips/LMS CM206 CDROM support
 CONFIG_CM206
   If you have a Philips/LMS CDROM drive cm206 in combination with a
   cm260 host adapter card, say Y here.  Please also read the file
-  Documentation/cdrom/cm206. If you say Y here, you should also say Y
-  to "ISO9660 cdrom filesystem support" below, because that's the
-  filesystem used on CDROMs. 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 cm206.o. If you
-  want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  Documentation/cdrom/cm206. 
+
+  If you say Y here, you should also say Y to "ISO9660 cdrom
+  filesystem support" below, because that's the filesystem used on
+  CDROMs. 
+
+  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 cm206.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Optics Storage DOLPHIN 8000AT CDROM support
 CONFIG_OPTCD
@@ -4757,31 +5267,38 @@
   you have one of those, say Y. This driver does not work for the
   Optics Storage 8001 drive; use the IDE-ATAPI CDROM driver for that
   one. Please read the file Documentation/cdrom/optcd. 
+
   If you say Y here, you should also say Y to "ISO9660 cdrom
   filesystem support" below, because that's the filesystem used on
-  CDROMs. 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 optcd.o. If you want to compile it
-  as a module, say M here and read Documentation/modules.txt.
+  CDROMs. 
+
+  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 optcd.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Sanyo CDR-H94A CDROM support
 CONFIG_SJCD
   If this is your CDROM drive, say Y here and read the file
   Documentation/cdrom/sjcd. You should then also say Y to "ISO9660
   cdrom filesystem support" below, because that's the filesystem used
-  on CDROMs. 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 sjcd.o. If you want to compile it
-  as a module, say M here and read Documentation/modules.txt.
+  on CDROMs. 
+
+  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 sjcd.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Soft configurable cdrom interface card support
 CONFIG_CDI_INIT
   If you want to include boot-time initialization of any cdrom
   interface card that is software configurable, say Y here.  Currently
   only the ISP16/MAD16/Mozart sound cards with built-in cdrom
-  interfaces are supported.  Note that the answer to this question
-  doesn't directly affect the kernel: saying N will just cause this
-  configure script to skip all the questions about these CDROM drives.
+  interfaces are supported.  
+
+  Note that the answer to this question doesn't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the questions about these CDROM drives.
 
 ISP16/MAD16/Mozart soft configurable cdrom interface support
 CONFIG_ISP16_CDI
@@ -4789,20 +5306,23 @@
   OPTi 82C928 or 82C929 chips. Say Y here to have them detected and
   possibly configured at boot time. In addition, You'll have to say Y
   to a driver for the particular cdrom drive you have attached to the
-  card. Read Documentation/cdrom/isp16 for details.  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 isp16.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  card. Read Documentation/cdrom/isp16 for details.  
+
+  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 isp16.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Preload dcache
 CONFIG_DCACHE_PRELOAD
   Preloading will create dcache entries when a directory is scanned
-  (e.g. with ls) for the *first* time. This should speed up successive
-  lookups of information about files in that directory, but can also
-  consume large amounts of memory.  
+  (e.g. because the ls command was used) for the *first* time. This
+  should speed up successive lookups of information about files in
+  that directory, but can also consume large amounts of memory.
+
   Please report speedups (or slowdowns due to the memory usage if they
   occur) to schoebel@informatik.uni-stuttgart.de .
+
   If unsure, say N.
 
 Quota support
@@ -4812,24 +5332,30 @@
   ext2 filesystem. You need additional software in order to use quota
   support; for details, read the Quota mini-HOWTO, available via ftp
   (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. Probably the quota
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. Probably the quota
   support is only useful for multi user systems. If unsure, say N.
 
 Online mirror support
 CONFIG_OMIRR
   omirr is a package for _symmetric_ mirroring of files over the
-  Internet. In contrast to rdist, the online mirror daemon (omirrd)
-  is running all the time and transfers any changes on the file system
-  as soon as possible to all other servers. Symmetric means that all
+  Internet. In contrast to rdist, the online mirror daemon (omirrd) is
+  running all the time and transfers any changes on the file system as
+  soon as possible to all other servers. Symmetric means that all
   servers have equal rights in changing a file: the last changer of a
   file will win. This is the same behaviour as multiple processes
   operating on a global file system. In effect, omirr can do the same
-  as nfs mounts, but will have better performance since the data is
+  as NFS mounts, but will have better performance since the data is
   stored on local disks. In contrast to a cache filesystem which has a
-  dedicated master copy, broken connections and/or servers are no problem
-  for continuing work on the remaining ones, because there is no master
-  copy. You must say Y if you want to use omirrd, but you should (but
-  need not) say N if you don't (for performance reasons).
+  dedicated master copy, broken connections and/or servers are no
+  problem for continuing work on the remaining ones, because there is
+  no master copy. Every computer that wants to participate in the
+  mirroring needs to run the daemon omirrd, contained in the omirr
+  package which is available via ftp (user: anonymous) from
+  ftp://ftp.isa.de/pub/home/luik. You must say Y if you want to use
+  in.omirrd, but you should (but need not) say N if you don't (for
+  performance reasons).
+
+  Note that this is experimental code; use at your own risk.
 
 Filename translation support
 CONFIG_TRANS_NAMES
@@ -4840,6 +5366,7 @@
   minimum when used for configuration files. The kernel running on the
   clients should have this option enabled. If you don't administer a
   pool of Linux clients, say N here, otherwise read on:
+
   When you say Y here, filenames, directory names etc become
   context-sensitive.  If you have a file named
   "/etc/config#host=banana#", it will appear (by default) as
@@ -4848,19 +5375,26 @@
   hardlinked to "/etc/config".
   This default behaviour can be changed by setting the _first_
   environment variable NAMETRANS to a colon-separated list of suffixes
-  which are tried in the specified order. For example, in 'env -
-  NAMETRANS=#host=mango#:#ktype=diskless# "`env`" command ...' the
-  command will see the same files as if it had been executed on host
-  "mango" with a diskless kernel.
+  which are tried in the specified order. For example, in 
+ 
+  'env - NAMETRANS=#host=mango#:#ktype=diskless# "`env`" command ...'
+   
+  the command will see the same files as if it had been executed on
+  host "mango" with a diskless kernel.
+
   Using NAMETRANS supersedes _all_ default translations. Thus
   translations can be completely switched off with an empty list,
-  e.g. 'env - NAMETRANS= "`env`" command ...'.  Note that some system
-  utilities like tar, dump, restore should be used with translation
-  switched off, in order to avoid doubled space in archive files and
-  when extracting from them. Also, make sure that nfsd, mountd (and
-  similar ones like samba daemons) run without translation, in order
-  to avoid doubled (or even wrong) translation at the server and at
-  the client.
+  e.g. 
+
+  'env - NAMETRANS= "`env`" command ...'  
+
+  Note that some system utilities like tar, dump, restore should be
+  used with translation switched off, in order to avoid doubled space
+  in archive files and when extracting from them. Also, make sure that
+  nfsd, mountd (and similar ones like samba daemons) run without
+  translation, in order to avoid doubled (or even wrong) translation
+  at the server and at the client.
+
   You can automatically force the creation of context-dependent
   filenames if there exists a template filename like
   "/etc/mtab#host=CREATE#". As soon as a process running on "mango"
@@ -4873,6 +5407,7 @@
   otherwise try to create one shared /etc/mtab which would result in a
   clash. Also one should execute "touch /etc/nologin#host=CREATE#" to
   prevent global side effects from shutdown resp. runlevel.
+
   Please read Documentation/transname.txt if you intend to say Y here.
 
 Restrict translation to gid
@@ -4886,9 +5421,11 @@
   context-dependent files to some special group like "adm" (group id
   4) and enable this option. As a result, users will not notice any
   performance degradation resulting from filename translation.
+
   Note that translations resulting from the first environment variable
   "NAMETRANS=..." are always carried out regardless of the gid of
   directories.
+
   Beware: before turning on this option make sure that all directories
   containing context-dependent files belong to the special group, or
   system initialization may fail. If unsure, select N.
@@ -4915,7 +5452,7 @@
   the hostname at boot time, and there is no way to tell the hostname
   by lilo or bootp. Please avoid using this option and prefer
   "Nodename (hostname) translation" (CONFIG_TR_NODENAME) wherever
-  possible. When mounting the root over nfs, the own hostname must be
+  possible. When mounting the root over NFS, the own hostname must be
   known at boot time anyway; this option is just for special use.
   Note that the default translations are tried in the order as
   occurring in the configuration, that is 1) host 2) kname 3) ktype 4)
@@ -4975,12 +5512,13 @@
   leaner. You don't want to use it on your hard disk because of certain
   built-in restrictions. This option will enlarge your kernel by about
   25 kB. Everyone should say Y or M so that they are able to read this
-  common floppy format.  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 minix.o. Note
-  that the filesystem of your root partition cannot be compiled as a
-  module.
+  common floppy format.  
+
+  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 minix.o. Note that the filesystem of your root partition
+  cannot be compiled as a module.
 
 Second extended fs support
 CONFIG_EXT2_FS
@@ -4997,32 +5535,41 @@
   transition to a *real* Linux partition later. Another (rare) case
   which doesn't require ext2fs is a diskless Linux box which mounts
   all files over the network using NFS (in this case it's sufficient
-  to say Y to "NFS filesystem support" below). There is a short
-  ext2fs-FAQ, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/faqs. This option will enlarge your
-  kernel by about 41 kB. If you want to compile this filesystem 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 ext2.o. Be
-  aware however that the filesystem of your root partition cannot be
-  compiled as a module, and so this could be dangerous. Most everyone
-  wants to say Y here.
+  to say Y to "NFS filesystem support" below). Saying Y here will
+  enlarge your kernel by about 41 kB.
+
+  The Ext2fs-Undeletion mini-HOWTO, available via ftp (user:
+  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini,
+  gives information about how to retrieve deleted files on ext2fs
+  filesystems.
+
+  To change the behavior of ext2fs filesystems, you can use the
+  tune2fs utility ("man tune2fs"). 
+
+  If you want to compile this filesystem 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 ext2.o. Be aware however that the filesystem of your
+  root partition cannot be compiled as a module, and so this could be
+  dangerous. Most everyone wants to say Y here.
 
 ISO9660 cdrom filesystem support
 CONFIG_ISO9660_FS
   This is the standard filesystem used on CDROMs. It was previously
   known as "High Sierra Filesystem" and is called "hsfs" on other Unix
   systems. The so-called Rock-Ridge extensions which allow for long
-  Unix filenames and symbolic links are also supported by this
-  driver. If you have a CDROM drive and want to do more with it than
-  just listen to audio CDs and watch its LEDs, say Y (and read
+  Unix filenames and symbolic links are also supported by this driver.
+  If you have a CDROM drive and want to do more with it than just
+  listen to audio CDs and watch its LEDs, say Y (and read
   Documentation/filesystems/isofs.txt and the CDROM-HOWTO, available
   via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO), thereby enlarging your
-  kernel by about 27 kB; otherwise say N.  If you want to compile this
-  as a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), say M here and read
-  Documentation/modules.txt. The module will be called isofs.o.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO), thereby enlarging your
+  kernel by about 27 kB; otherwise say N.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called isofs.o.
 
 Microsoft Joliet cdrom extensions
 CONFIG_JOLIET
@@ -5044,15 +5591,16 @@
   foundation for the other filesystems. It is now also becoming
   possible to read and write compressed FAT filesystems; read
   Documentation/filesystems/fat_cvf.txt for details. This option will
-  enlarge your kernel by about 24 kB. If unsure, say Y. If you want to
-  compile this as a module however ( = 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 fat.o.
-  Note that if you compile the FAT support as a module, you cannot
-  compile any of the FAT-based filesystems into the kernel - they will
-  have to be modules as well. The filesystem of your root partition
-  cannot be a module, so don't say M here if you intend to use UMSDOS
-  as your root filesystem.
+  enlarge your kernel by about 24 kB. If unsure, say Y. 
+
+  If you want to compile this as a module however ( = 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 fat.o. Note that if you compile the FAT support as a
+  module, you cannot compile any of the FAT-based filesystems into the
+  kernel - they will have to be modules as well. The filesystem of
+  your root partition cannot be a module, so don't say M here if you
+  intend to use UMSDOS as your root filesystem.
 
 msdos fs support
 CONFIG_MSDOS_FS
@@ -5060,26 +5608,30 @@
   they are compressed; to access compressed MSDOS partitions under
   Linux, you can either use the DOS emulator DOSEMU, described in the
   DOSEMU-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO, or try dmsdosfs in
-  sunsite.unc.edu:/pub/Linux/system/filesystems/dosfs. If you intend
-  to use dosemu with a non-compressed MSDOS partition, say Y here) and
-  MSDOS floppies. This means that file access becomes transparent,
-  i.e. the MSDOS files look and behave just like all other Unix files.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, or try dmsdosfs in
+  ftp://sunsite.unc.edu/pub/Linux/system/filesystems/dosfs. If you
+  intend to use dosemu with a non-compressed MSDOS partition, say Y
+  here) and MSDOS floppies. This means that file access becomes
+  transparent, i.e. the MSDOS files look and behave just like all
+  other Unix files.
+
   Another way to read and write MSDOS floppies from within Linux (but
   not transparently) is with the mtools ("man mtools") program suite,
-  which doesn't require the msdos filesystem support.  If you want to
-  use umsdos, the Unix-like filesystem on top of DOS, which allows you
-  to run Linux from within a DOS partition without repartitioning,
-  you'll have to say Y or M here. If you have Windows 95 or Windows
-  NT installed on your MSDOS partitions, you should use the VFAT
-  filesystem instead, or you will not be able to see the long
-  filenames generated by Windows 95 / Windows NT. This option will
-  enlarge your kernel by about 7 kB. If unsure, say Y. This will only
-  work if you said Y to "fat fs support" as well. If you want to
-  compile this as a module however ( = 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
-  msdos.o.
+  which doesn't require the msdos filesystem support.  
+
+  If you want to use umsdos, the Unix-like filesystem on top of DOS,
+  which allows you to run Linux from within a DOS partition without
+  repartitioning, you'll have to say Y or M here. If you have Windows
+  95 or Windows NT installed on your MSDOS partitions, you should use
+  the VFAT filesystem instead, or you will not be able to see the long
+  filenames generated by Windows 95 / Windows NT. 
+
+  This option will enlarge your kernel by about 7 kB. If unsure, say
+  Y. This will only work if you said Y to "fat fs support" as well. If
+  you want to compile this as a module however ( = 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 msdos.o.
 
 vfat fs support
 CONFIG_VFAT_FS
@@ -5091,10 +5643,12 @@
   UMSDOS instead. This option enlarges your kernel by about 10 kB and
   it only works if you said Y to the "fat fs support" above. Please read
   the file Documentation/filesystems/vfat.txt for details.
-  If unsure, say N. 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 vfat.o.
+  If unsure, say N. 
+
+  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 vfat.o.
 
 umsdos: Unix like fs on top of std MSDOS fs
 CONFIG_UMSDOS_FS
@@ -5108,12 +5662,13 @@
   is to write files with long unix filenames to MSDOS floppies; it
   also allows unix style softlinks and owner/permissions of files on
   MSDOS floppies. You will need a program called umssync in order to
-  make use of umsdos; read Documentation/filesystems/umsdos.txt. This
-  option enlarges your kernel by about 25 kB and it only works if you
-  said Y to both "fat fs support" and "msdos fs support" above. 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
+  make use of umsdos; read Documentation/filesystems/umsdos.txt. 
+
+  This option enlarges your kernel by about 25 kB and it only works if
+  you said Y to both "fat fs support" and "msdos fs support" above. 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
   umsdos.o. Note that the filesystem of your root partition cannot be
   a module, so this could be dangerous. If unsure, say N.
 
@@ -5121,21 +5676,23 @@
 CONFIG_PROC_FS
   This is a virtual filesystem providing information about the status
   of the system. "Virtual" means that it doesn't take up any space on
-  your hard disk: the files are created on the fly when you 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
+  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").  This option will enlarge your kernel by
-  about 18 kB. 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). Several programs depend on this, so
-  everyone should say Y here.
+  manpage ("man 8 proc").
+
+  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.
 
 NFS filesystem support
 CONFIG_NFS_FS
@@ -5146,29 +5703,39 @@
   the files with usual UNIX commands as if they were sitting on the
   client's hard disk. For this to work, the server must run the
   programs nfsd and mountd (but does not need to have NFS filesystem
-  support enabled). NFS is explained in the Network Administrator's
-  Guide, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/LDP, on its man page: "man nfs", and
-  in the NFS-HOWTO. If you say Y here, you should have said Y to
-  TCP/IP networking also. This option would enlarge your kernel by
-  about 27 kB. This filesystem is also available as a module ( = code
-  which can be inserted in and removed from the running kernel
-  whenever you want). The module is called nfs.o. If you want to
-  compile it as a module, say M here and read
-  Documentation/modules.txt. If you configure a diskless machine which
-  will mount its root filesystem over nfs (in order to do that, check
-  out the netboot package, available via ftp (user: anonymous) from
-  sunsite.unc.edu in /pub/Linux/system/boot/ethernet/, extract with
-  "tar xzvf filename", and say Y to "Root file system on NFS" below),
-  then you cannot compile this driver as a module. If you don't know
-  what all this is about, say N.
+  support enabled in its kernel). NFS is explained in the Network
+  Administrator's Guide, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/LDP, on its man page: "man
+  nfs", and in the NFS-HOWTO.
+
+  If you say Y here, you should have said Y to TCP/IP networking also.
+  This option would enlarge your kernel by about 27 kB. 
+
+  This filesystem is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called nfs.o. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. 
+
+  If you are configuring a diskless machine which will mount its root
+  filesystem over NFS (in order to do that, check out the netboot
+  package, available via ftp (user: anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/system/boot/ethernet/, extract with
+  "tar xzvf filename", and say Y to "Root file system on NFS" and to
+  "IP: kernel level autoconfiguration"), then you cannot compile this
+  driver as a module.
+
+  If you don't know what all this is about, say N.
 
 Root file system on NFS
 CONFIG_ROOT_NFS
   If you want your Linux box to mount its whole root filesystem from
   some other computer over the net via NFS (presumably because your
   box doesn't have a hard disk), say Y. Read Documentation/nfsroot.txt
-  for details. Most people say N here. 
+  for details. It is likely that in this case, you also want to say Y
+  to "IP: kernel level autoconfiguration" so that your box can
+  discover its network address at boot time. 
+  
+  Most people say N here. 
 
 NFS server support
 CONFIG_NFSD
@@ -5182,34 +5749,12 @@
   You will need the support software from the linux-nfs package
   available at ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/.
   Please read the NFS-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. The nfs server is also
-  available as a module ( = code which can be inserted in and removed
-  from the running kernel whenever you want). The module is called
-  nfsd.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt. If unsure, say N.
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 
 
-BOOTP support
-CONFIG_RNFS_BOOTP
-  If you want your Linux box to mount its whole root filesystem from
-  some other computer over the net via NFS and you want the IP address
-  of your computer to be discovered automatically at boot time using
-  the BOOTP protocol (a special protocol designed for doing this job),
-  say Y here. In case the boot ROM of your network card was designed
-  for booting Linux and does BOOTP itself, providing all necessary
-  information on the kernel command line, you can say N here.  If
-  unsure, say Y. Note that in case you want to use BOOTP, a BOOTP
-  server must be operating on your network. Read
-  Documentation/nfsroot.txt for details.
-
-RARP support
-CONFIG_RNFS_RARP
-  If you want your Linux box to mount its whole root filesystem from
-  some other computer over the net via NFS and you want the IP address
-  of your computer to be discovered automatically at boot time using
-  the RARP protocol (an older protocol which is being obsoleted by
-  BOOTP and DHCP), say Y here. Note that in case you want to use RARP,
-  a RARP server must be operating on your network. Read
-  Documentation/nfsroot.txt for details.
+  The NFS server is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called nfsd.o. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. If unsure, say N.
 
 OS/2 HPFS filesystem support (read only)
 CONFIG_HPFS_FS
@@ -5218,24 +5763,25 @@
   partitions. Say Y if you want to be able to read files from an OS/2
   HPFS partition of your hard drive. OS/2 floppies however are in
   regular MSDOS format, so you don't need this option in order to be
-  able to read them. Read Documentation/filesystems/hpfs.txt. This
-  filesystem is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you
-  want). The module is called hpfs.o. If you want to compile it as a
-  module, say M here and read Documentation/modules.txt. If unsure,
-  say N.
+  able to read them. Read Documentation/filesystems/hpfs.txt. 
+
+  This filesystem is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called hpfs.o. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. If unsure, say N.
 
 Windows NT NTFS support (read only)
 CONFIG_NTFS_FS
   NTFS is the file system of Microsoft Windows NT. Say Y if you want
-  to access partitions using this file system. The Linux NTFS driver
-  supports most of the mount options of the VFAT driver, see
-  Documentation/filesystems/ntfs.txt. Saying Y here will give you
-  read-only access to NTFS partitions. This code 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 ntfs.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  to get read access to files on NTFS partitions of your hard drive.
+  The Linux NTFS driver supports most of the mount options of the VFAT
+  driver, see Documentation/filesystems/ntfs.txt. Saying Y here will
+  give you read-only access to NTFS partitions.
+
+  This code 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 ntfs.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 NTFS read-write support (experimental)
 CONFIG_NTFS_RW
@@ -5249,99 +5795,126 @@
 CONFIG_SYSV_FS
   SCO, Xenix and Coherent are commercial Unix systems for Intel
   machines. Saying Y here would allow you to read and write to and
-  from their floppies and hard disk partitions. If you have a floppy or
-  hard disk partition like that, it is probable that they contain
-  binaries from those other Unix systems; in order to run these
-  binaries, you will want to install iBCS2 (iBCS2 [Intel Binary
-  Compatibility Standard] is a kernel module which lets you run SCO,
-  Xenix, Wyse, UnixWare, Dell Unix and System V programs under Linux
-  and is often needed to run commercial software, most prominently
-  WordPerfect. It's in tsx-11.mit.edu:/pub/linux/BETA). If you only
-  intend to mount files from some other Unix over the network using
-  NFS, you don't need the System V filesystem support (but you need
-  nfs filesystem support obviously). Note that this option is
-  generally not needed for floppies, since 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").  Note also that this option has nothing
+  from their floppies and hard disk partitions. 
+
+  If you have a floppy or hard disk partition like that, it is likely
+  that they contain binaries from those other Unix systems; in order
+  to run these binaries, you will want to install iBCS2 (iBCS2 [Intel
+  Binary Compatibility Standard] is a kernel module which lets you run
+  SCO, Xenix, Wyse, UnixWare, Dell Unix and System V programs under
+  Linux and is often needed to run commercial software that's only
+  available for those systems. It's available via ftp (user:
+  anonymous) from ftp://tsx-11.mit.edu/pub/linux/BETA).
+
+  If you only intend to mount files from some other Unix over the
+  network using NFS, you don't need the System V filesystem support
+  (but you need NFS filesystem support obviously). Note that this
+  option is generally not needed for floppies, since 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"). 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. This
-  option 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), say M here and
-  read Documentation/modules.txt. The module will be called sysv.o. If
-  you haven't heard about all of this before, it's safe to say N.
+  option 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),
+  say M here and read Documentation/modules.txt. The module will be
+  called sysv.o. If you haven't heard about all of this before, it's
+  safe to say N.
 
 Amiga FFS filesystem support
 CONFIG_AFFS_FS
-  If you say Y here, you will be able to mount floppies and hard drive
-  partitions which were formatted with the Amiga FFS filesystem. Full
-  read-write support is available for most versions of FFS, see
-  Documentation/filesystems/affs.txt for details. This filesystem
-  support is also available as a module ( = code which can be inserted
-  in and removed from the running kernel whenever you want). The
-  module is called affs.o. If you want to compile it as a module, say M
-  here and read Documentation/modules.txt.
+  The Fast File System (FFS) is the common filesystem used on hard
+  disks by Amiga(tm) Systems since AmigaOS Version 1.3 (34.20). With
+  this driver you can also mount diskfiles used by Bernd Schmidt's
+  Un*X Amiga Emulator (http://www.freiburg.linux.de/~uae/; 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 want to do the latter,
+  you will also need to say Y to "Loop device support", above. Say Y
+  if you want to be able to read and write files from and to an Amiga
+  FFS partition on your hard drive. Amiga floppies however cannot be
+  read with this driver due to an incompatibility of the floppy
+  controller used in an Amiga and the standard floppy controller in
+  PCs and workstations. Read Documentation/filesystems/affs.txt and
+  fs/affs/Changes. 
+
+  This filesystem is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called affs.o. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. If unsure, say N.
 
 Apple Macintosh filesystem support (experimental)
 CONFIG_HFS_FS
   If you say Y here, you will be able to mount Macintosh-formatted
   floppy disks and hard drive partitions with full read-write access.
   Please read fs/hfs/HFS.txt to learn about the available mount
-  options. This filesystem support is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). The module is called hfs.o. If you want to
-  compile it as a module, say M here and read
-  Documentation/modules.txt.
+  options. 
+
+  This filesystem support is also available as a module ( = code which
+  can be inserted in and removed from the running kernel whenever you
+  want). The module is called hfs.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 ROM filesystem support
 CONFIG_ROMFS_FS
   This is a very small read-only filesystem mainly intended for
   initial ram disks of installation disks, but it could be used for
   other read-only media as well. Read
-  Documentation/filesystems/romfs.txt for details. This filesystem
-  support is also available as a module ( = code which can be inserted
-  in and removed from the running kernel whenever you want). The
-  module is called romfs.o. If you want to compile it as a module, say
-  M here and read Documentation/modules.txt. If you don't know whether
-  you need it, then you don't need it: say N.
+  Documentation/filesystems/romfs.txt for details. 
+
+  This filesystem support is also available as a module ( = code which
+  can be inserted in and removed from the running kernel whenever you
+  want). The module is called romfs.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt. 
+
+  If you don't know whether you need it, then you don't need it: say
+  N.
 
 Kernel automounter support
 CONFIG_AUTOFS_FS
   The automounter is a tool to automatically mount remote filesystems
   on demand.  This implementation is partially kernel-based to reduce
   overhead in the already-mounted case; this is unlike the BSD
-  automounter (amd), which is only in user space.  To use the
-  automounter you need the user-space tools from
-  ftp.kernel.org:/pub/linux/daemons/autofs; you also want to say Y to
-  "NFS filesystem support", above.  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 autofs.o.
+  automounter (amd), which is only in user space.  
+
+  To use the automounter you need the user-space tools from
+  ftp://ftp.kernel.org/pub/linux/daemons/autofs; you also want to say Y to
+  "NFS filesystem support", above. 
+
+  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 autofs.o. 
+
   If you are not a part of a fairly large, distributed network, you
   probably do not need an automounter, and can say N here.
 
 BSD UFS filesystem support (read only)
 CONFIG_UFS_FS
-  BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD
-  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 allows you to mount these
-  partitions and diskettes read-only. 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 you need nfs filesystem support
-  obviously). Note that this option is generally not needed for
-  floppies, since 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"). When
-  accessing NeXTstep files, you may need to convert them from the NeXT
-  character set to the Latin1 character set; use the program recode
-  for this purpose.  Say Y to build UFS read support into your
-  kernel. 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 ufs.o. If you haven't heard about all of this before,
-  it's safe to say N.
+  BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
+  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 allows you to mount these
+  partitions and diskettes read-only.
+
+  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
+  you need NFS filesystem support obviously). Note that this option is
+  generally not needed for floppies, since 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"). 
+
+  When accessing NeXTstep files, you may need to convert them from the
+  NeXT character set to the Latin1 character set; use the program
+  recode ("info recode") for this purpose. 
+
+  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 ufs.o. If you haven't heard about all of this before, it's
+  safe to say N.
 
 BSD disklabel (FreeBSD partition tables) support
 CONFIG_BSD_DISKLABEL
@@ -5370,27 +5943,41 @@
 
 Solaris (x86) partition table support
 CONFIG_SOLARIS_X86_PARTITION
-  Say Y here if you have a hard drive that will be accessed from Linux
-  and from Solaris x86. This is NOT for Solaris on the sparc
-  architecture. 
+  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 "BSD ufs
+  filesystem support", above.
 
 ADFS filesystem support (read only) (EXPERIMENTAL)
 CONFIG_ADFS_FS
   Acorn Disc Filing System is the standard filesystem of the Risc OS
-  operating system which runs on Acorn's StrongARM Risc PC computers.
+  operating system which runs on Acorn's ARM based Risc PC computers.
   If you say Y here, Linux will be able to read from ADFS partitions
-  on hard drives and from ADFS-formatted floppy disks. This code is
-  also available as a module called adfs.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
+  on hard drives and from ADFS-formatted floppy disks. 
+
+  This code is also available as a module called adfs.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.
 
-/dev/pts filesystem
+/dev/pts filesystem (experimental)
 CONFIG_DEVPTS_FS
-  A filesystem which when mounted on /dev/pts and used in conjunction
-  with the /dev/ptmx multiplexing pty device, should allow full
-  support for Unix98 pty's without requiring setuid or daemons.  glibc
-  2.1 contains the requisite support for this mode of operation.
+  If you say Y here, you'll get a virtual filesystem which can be
+  mounted on /dev/pts with "mount -t devpts". This, together with the
+  pseudo terminal master multiplexer /dev/ptmx is used for pseudo
+  terminal support as described in the Open Group's Unix98 standard:
+  in order 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.
+
+  This code is also available as a module called devpts.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.
 
 Macintosh partition map support
 CONFIG_MAC_PARTITION
@@ -5408,47 +5995,55 @@
   if the Windows machines use TCP/IP as the underlying transport
   protocol, and not Netbeui. For details, read
   Documentation/filesystems/smbfs.txt and the SMB-HOWTO, available via
-  ftp (user: anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  ftp (user: anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
   Note: if you just want your box to act as an SMB *server* and make
   files and printing services available to Windows clients (which need
   to have a TCP/IP stack), you don't need to say Y here; you can use
   the program samba (available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/system/network/samba) for that. General
-  information about how to connect Linux, Windows machines and Macs is
-  on the WWW at http://eats.com/linux_mac_win.html (to browse the WWW,
-  you need to have access to a machine on the Internet that has a
-  program like lynx or netscape). If you want to compile the SMB
-  support 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 smbfs.o. Most
-  people say N, however.
+  ftp://sunsite.unc.edu/pub/Linux/system/network/samba) for that.
+
+  General information about how to connect Linux, Windows machines and
+  Macs is on the WWW at http://www.eats.com/linux_mac_win.html (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 want to compile the SMB support 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 smbfs.o. Most people say N, however.
+
+SMB Win95 bug work-around
+CONFIG_SMB_WIN95
+  If you want to connect to a share exported by Windows 95, you should
+  say Y here. The Windows 95 server contains a bug that makes listing
+  directories unreliable. This option slows down the listing of
+  directories. This makes the Windows 95 server a bit more stable.
 
 Coda filesystem support
 CONFIG_CODA_FS
-  CODA is an advanced network filesystem, similar to NFS in that it
+  Coda is an advanced network filesystem, similar to NFS in that it
   enables you to mount filesystems of a remote server and access them
   with regular Unix commands as if they were sitting on your hard
-  disk. It has support for disconnected operation for laptops,
-  read/write server replication, persistent client caches and write
-  back caching. By saying Y here you are compiling kernel support for
-  Coda clients into the Linux kernel. You will need user level code as
-  well, both for the client and server. Servers are currently user
-  level, i.e. need no kernel support. For technical information, read
-  Documentation/filesystems/coda.txt. 
-  If you want to compile the coda client support 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 coda.o. For further information see
+  disk. Coda has several advantages over NFS: support for disconnected
+  operation for laptops, read/write server replication, security model
+  for authentication and encryption, persistent client caches and
+  write back caching.
+
+  If you say Y here, your Linux box will be able to act as a Coda
+  *client*. You will need user level code as well, both for the client
+  and server. Servers are currently user level, i.e. need no kernel
+  support. For technical information, read
+  Documentation/filesystems/coda.txt. For further information see
   http://www.coda.cs.cmu.edu (to browse the WWW, you need to have
   access to a machine on the Internet that has a program like lynx or
   netscape) or contact Peter Braam <braam@cs.cmu.edu>.
 
-SMB Win95 bug work-around
-CONFIG_SMB_WIN95
-  If you want to connect to a share exported by Windows 95, you should
-  say Y here. The Windows 95 server contains a bug that makes listing
-  directories unreliable. This option slows down the listing of
-  directories. This makes the Windows 95 server a bit more stable.
+  If you want to compile the coda client support 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 coda.o. 
 
 NCP filesystem support (to mount NetWare volumes)
 CONFIG_NCP_FS
@@ -5458,11 +6053,20 @@
   mount NetWare file server volumes and to access them just like any
   other Unix directory. For details, please read the file
   Documentation/filesystems/ncpfs.txt in the kernel source and the
-  IPX-HOWTO on sunsite.unc.edu:/pub/Linux/docs/howto.  If you want to
-  compile this as a module ( = code which can be inserted in and
-  removed from the running kernel whenever you want), say M here and
-  read Documentation/modules.txt. The module will be called
-  ncpfs.o. Say N unless you are connected to a Novell network.
+  IPX-HOWTO on sunsite.unc.edu:/pub/Linux/docs/howto.
+
+  You do not have to say Y here if you want your Linux box to act as a
+  file *server* for Novell NetWare clients.
+
+  General information about how to connect Linux, Windows machines and
+  Macs is on the WWW at http://www.eats.com/linux_mac_win.html (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 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 ncpfs.o. Say N unless you are connected to a Novell network.
 
 Packet signatures
 CONFIG_NCPFS_PACKET_SIGNING
@@ -5501,6 +6105,7 @@
   also subdirectories from a volume. It can be used to reexport data
   and so on. There is no reason to say N, so Y is recommended unless
   you count every byte.
+
   To utilize this feature you must use ncpfs-2.0.12 or newer.
 
 NDS interserver authentication domains
@@ -5512,44 +6117,28 @@
   servers. Do not say Y if security is primary for you because root
   can read your session key (from /proc/kcore).
 
-Amiga FFS filesystem support
-CONFIG_AFFS_FS
-  The Fast File System (FFS) is the common filesystem used on hard
-  disks by Amiga(tm) Systems since AmigaOS Version 1.3 (34.20). With
-  this driver you can also mount diskfiles used by Bernd Schmidt's
-  Un*X Amiga Emulator (http://www.freiburg.linux.de/~uae/; 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 want to do the latter,
-  you will also need to say Y to "Loop device support", above. Say Y
-  if you want to be able to read and write files from and to an Amiga
-  FFS partition on your hard drive. Amiga floppies however cannot be
-  read with this driver due to an incompatibility of the floppy
-  controller used in an Amiga and the standard floppy controller in
-  PCs and workstations. Read Documentation/filesystems/affs.txt and
-  fs/affs/Changes. This filesystem is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). The module is called affs.o. If you want to
-  compile it as a module, say M here and read
-  Documentation/modules.txt. If unsure, say N.
-
 nls: Native language codepages and Unicode support
 CONFIG_NLS
   This is required by the FAT and NTFS filesystems and by the ISO9660
-  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 do a translation of the FAT filenames, not
-  the contents of the files.
+  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
@@ -5855,83 +6444,99 @@
 Standard/generic serial support
 CONFIG_SERIAL
   This selects whether you want to include the driver for the standard
-  serial ports.  People who might say N here are those that are
-  setting up dedicated Ethernet WWW/ftp servers, or users that have
-  one of the various bus mice instead of a serial mouse.  (Note that
-  the Cyclades and Stallion multi serial port drivers do not need this
-  driver built in for them to work.)  If you want to compile this
-  driver as a module, say M here and read
-  Documentation/modules.txt. The module will be called
-  serial.o. [WARNING: Do not compile this driver as a module if you
-  are using non-standard serial ports, since the configuration
-  information will be lost when kerneld automatically unloads the
-  driver.  This limitation may be lifted in the future.] BTW: If you
-  have a mouseman serial mouse which is not recognized by the X window
-  system, try running gpm first.  Most people will say Y or M here, so
-  that they can use serial mice, modems and similar devices connecting
-  to the standard serial ports.
+  serial ports. The standard answer is Y. People who might say N here
+  are those that are setting up dedicated Ethernet WWW/ftp servers, or
+  users that have one of the various bus mice instead of a serial
+  mouse and don't intend to use their machine's standard serial port
+  for anything. (Note that the Cyclades and Stallion multi serial port
+  drivers do not need this driver built in for them to work.)
+
+  If you want to compile this driver as a module, say M here and read
+  Documentation/modules.txt. The module will be called serial.o.
+  [WARNING: Do not compile this driver as a module if you are using
+  non-standard serial ports, since the configuration information will
+  be lost when kerneld automatically unloads the driver. This
+  limitation may be lifted in the future.] 
+
+  BTW: If you have a mouseman serial mouse which is not recognized by
+  the X window system, try running gpm first. 
+
+  Most people will say Y or M here, so that they can use serial mice,
+  modems and similar devices connecting to the standard serial ports.
 
 Support for console on serial port
 CONFIG_SERIAL_CONSOLE
   If you say Y here, it is possible to use a serial port as the
   console. By default still the currently visible virtual console will
   be used as the system console but you can alter that using a kernel
-  command line option. If you don't have a VGA card installed and you
-  say Y here, the kernel will automatically use /dev/ttyS0 as system
-  console.
+  command line option such as "console=ttyS1". (Try "man bootparam" or
+  see the documentation of your boot loader (lilo or loadlin) about
+  how to pass options to the kernel at boot time. The lilo procedure
+  is also explained in the SCSI-HOWTO, available via ftp (user:
+  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) If you
+  don't have a VGA card installed and you say Y here, the kernel will
+  automatically use /dev/ttyS0 as system console.
 
 Comtrol Rocketport support
 CONFIG_ROCKETPORT
   This is a driver for the Comtrol Rocketport cards which provide
   multiple serial ports.  You would need something like this to
-  connect more than two modems to your linux box, for instance in
-  order to become a BBS.If you want to compile this driver as a
-  module, say M here and read Documentation/modules.txt. The module
-  will be called rocket.o.
+  connect more than two modems to your Linux box, for instance in
+  order to become a BBS. 
+
+  If you want to compile this driver as a module, say M here and read
+  Documentation/modules.txt. The module will be called rocket.o.
 
 Digiboard Intelligent async support
 CONFIG_DIGIEPCA
   This is a driver for Digi International's Xx, Xeve, and Xem series
   of cards which provide multiple serial ports.  You would need
-  something like this to connect more than two modems to your linux
+  something like this to connect more than two modems to your Linux
   box, for instance in order to become a BBS. This driver supports the
   original PC (ISA) boards as well as PCI, and EISA.  If you have a
   card like this, say Y here and read the file
-  Documentation/digiepca.txt.  NOTE: There is another, separate driver
-  for the Digiboard PC boards: "Digiboard PC/Xx Support" below. You
-  should (and can) only select one of the two drivers. If you want to
-  compile this driver as a module, say M here and read
+  Documentation/digiepca.txt.  
+
+  NOTE: There is another, separate driver for the Digiboard PC boards:
+  "Digiboard PC/Xx Support" below. You should (and can) only select
+  one of the two drivers. 
+
+  If you want to compile this driver as a module, say M here and read
   Documentation/modules.txt. The module will be called epca.o.
 
 Digiboard PC/Xx Support
 CONFIG_DIGI
   This is a driver for the Digiboard PC/Xe, PC/Xi, and PC/Xeve cards
   that give you many serial ports. You would need something like this
-  to connect more than two modems to your linux box, for instance in
+  to connect more than two modems to your Linux box, for instance in
   order to become a BBS. If you have a card like that, say Y here and
-  read the file Documentation/digiboard.txt. If you want to compile
-  this driver as a module, say M here and read
+  read the file Documentation/digiboard.txt. 
+
+  If you want to compile this driver as a module, say M here and read
   Documentation/modules.txt. The module will be called pcxx.o.
 
 SDL RISCom/8 card support
 CONFIG_RISCOM8
   This is a driver for the SDL Communications RISCom/8 multiport card,
   which gives you many serial ports. You would need something like
-  this to connect more than two modems to your linux box, for instance
+  this to connect more than two modems to your Linux box, for instance
   in order to become a BBS. If you have a card like that, say Y here
-  and read the file Documentation/riscom8.txt. Also it's possible to
-  say M here and compile this driver as kernel loadable module; the
-  module will be called riscom8.o.
+  and read the file Documentation/riscom8.txt. 
+
+  Also it's possible to say M here and compile this driver as kernel
+  loadable module; the module will be called riscom8.o.
 
 Specialix IO8+ card support
 CONFIG_SPECIALIX
   This is a driver for the Specialix IO8+ multiport card, that give 
   you many serial ports. You would need something like this to 
-  connect more than two modems to your linux box, for instance in
-  order to become a BBS. If you have a card like that, say Y here and
-  read the file Documentation/specialix.txt. Also it's possible to say
-  M here and compile this driver as kernel loadable module which will
-  be called specialix.o.
+  connect more than two modems to your Linux box, for instance in
+  order to become a BBS. 
+
+  If you have a card like that, say Y here and read the file
+  Documentation/specialix.txt. Also it's possible to say M here and
+  compile this driver as kernel loadable module which will be called
+  specialix.o.
 
 Specialix DTR/RTS pin is RTS
 CONFIG_SPECIALIX_RTSCTS
@@ -5945,19 +6550,24 @@
 CONFIG_CYCLADES
   This is a driver for a card that gives you many serial ports. You
   would need something like this to connect more than two modems to
-  your linux box, for instance in order to become a BBS. For
+  your Linux box, for instance in order to become a BBS. For
   information about the Cyclades-Z card, read
-  drivers/char/README.cycladesZ. 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 cyclades.o. If
-  you haven't heard about it, it's safe to say N. (As of 1.3.9x
-  kernels, this driver's minor numbers start at 0 instead of 32.)
+  drivers/char/README.cycladesZ. 
+
+  As of 1.3.9x kernels, this driver's minor numbers start at 0 instead
+  of 32.
+
+  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 cyclades.o. 
+
+  If you haven't heard about it, it's safe to say N.
 
 Stallion multiport serial support 
 CONFIG_STALDRV
   Stallion cards give you many serial ports. You would need something
-  like this to connect more than two modems to your linux box, for
+  like this to connect more than two modems to your Linux box, for
   instance in order to become a BBS. If you say Y here, you will be
   asked for your specific card model in the next questions. Make sure
   to read drivers/char/README.stallion in this case. If you have never
@@ -5967,28 +6577,33 @@
 CONFIG_STALLION
   If you have an EasyIO or EasyConnection 8/32 multiport Stallion
   card, then this is for you; say Y. Make sure to read
-  Documentation/stallion.txt. 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 stallion.o.
+  Documentation/stallion.txt. 
+
+  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 stallion.o.
 
 Stallion EC8/64, ONboard, Brumby support
 CONFIG_ISTALLION
   If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
   serial multiport card, say Y here. Make sure to read
-  Documentation/stallion.txt. To compile it as a module ( = code
-  which can be inserted in and removed from the running kernel
-  whenever you want), say M here and read
-  Documentation/modules.txt. The module will be called istallion.o.
+  Documentation/stallion.txt. 
+
+  To compile it as a module ( = code which can be inserted in and
+  removed from the running kernel whenever you want), say M here and
+  read Documentation/modules.txt. The module will be called
+  istallion.o.
 
 Hayes ESP serial port support
 CONFIG_ESPSERIAL
   This is a driver which supports Hayes ESP serial ports.  It uses DMA
   to transfer data to and from the host.  Make sure to read
-  Documentation/hayes-esp.txt. 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 esp.o.
+  Documentation/hayes-esp.txt. 
+
+  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 esp.o.
   If unsure, say N.
 
 Hayes ESP serial port DMA channel
@@ -5999,16 +6614,17 @@
 
 Hayes ESP serial port receive trigger level
 CONFIG_ESPSERIAL_RX_TRIGGER
-  This is the trigger level (in bytes) of the receive FIFO.  Larger
-  values may result in fewer interrupts; however, a value too high
-  could result in data loss.  Valid values are 1 through 1023.
+  This is the trigger level (in bytes) of the receive FIFO. Larger
+  values may result in fewer interrupts and hence better performance;
+  however, a value too high could result in data loss. Valid values
+  are 1 through 1023.
 
 Hayes ESP serial port transmit trigger level
 CONFIG_ESPSERIAL_TX_TRIGGER
-  This is the trigger level (in bytes) of the transmit FIFO.  Larger
-  values may result in fewer interrupts; however, a value too high
-  could result in degraded transmit performance.  Valid values are 1
-  through 1023.
+  This is the trigger level (in bytes) of the transmit FIFO. Larger
+  values may result in fewer interrupts and hence better performance;
+  however, a value too high could result in degraded transmit
+  performance. Valid values are 1 through 1023.
 
 Hayes ESP serial port flow off level
 CONFIG_ESPSERIAL_FLOW_OFF
@@ -6038,23 +6654,29 @@
   box (as opposed to using a serial printer; if the connector at the
   printer has 9 or 25 holes ["female"], then it's serial), say Y. Also
   read the Printing-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  It is possible to share one
-  parallel port among several devices (e.g. printer and ZIP drive) and
-  it is safe to compile the corresponding drivers into the kernel. If
-  you want to compile this driver as a module however ( = 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 lp.o.  If you have several parallel ports, you should
-  specify the base address for the port to be used by the printer with
-  the "lp" kernel command line option. (Try "man bootparam" or see the
-  documentation of your boot loader (lilo or loadlin) about how to
-  pass options to the kernel at boot time. The lilo procedure is also
-  explained in the SCSI-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.) The standard base addresses
-  as well as the syntax of the "lp" command line option can be found
-  in drivers/char/lp.c. If you have more than 3 printers, you need to
-  increase the LP_NO variable in lp.c.
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  It is possible to share one parallel port among several devices
+  (e.g. printer and ZIP drive) and it is safe to compile the
+  corresponding drivers into the kernel. If you want to compile this
+  driver as a module however ( = 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 lp.o. 
+
+  If you have several parallel ports, you should specify the base
+  address for the port to be used by the printer with the "lp" kernel
+  command line option. (Try "man bootparam" or see the documentation
+  of your boot loader (lilo or loadlin) about how to pass options to
+  the kernel at boot time. The lilo procedure is also explained in the
+  SCSI-HOWTO, available via ftp (user: anonymous) in
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) The standard base
+  addresses as well as the syntax of the "lp" command line option can
+  be found in drivers/char/lp.c.
+
+  If you have more than 3 printers, you need to increase the LP_NO
+  variable in lp.c.
 
+Support IEEE1284 status readback
 CONFIG_PRINTER_READBACK
   If your printer conforms to IEEE 1284, it may be able to provide a
   status indication when you read from it (for example, with `cat
@@ -6067,13 +6689,16 @@
   Microsoft mouse (made by Logitech) that plugs into a COM port
   (rectangular with 9 or 25 pins). These people say N here. If you
   have something else, read the Busmouse-HOWTO, available via ftp
-  (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO and say Y
-  here. If you have a laptop, you either have to check the
-  documentation or experiment a bit to find out whether the trackball
-  is a serial mouse or not; it's best to say Y here for you. Note that
-  the answer to this question won't directly affect the kernel: saying
-  N will just cause this configure script to skip all the questions
-  about non-serial mice.  If unsure, say Y.
+  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and
+  say Y here.
+
+  If you have a laptop, you either have to check the documentation or
+  experiment a bit to find out whether the trackball is a serial mouse
+  or not; it's best to say Y here for you. 
+
+  Note that the answer to this question won't directly affect the
+  kernel: saying N will just cause this configure script to skip all
+  the questions about non-serial mice. If unsure, say Y.
 
 Logitech busmouse support
 CONFIG_BUSMOUSE
@@ -6082,12 +6707,13 @@
   made by Logitech don't use the Logitech protocol anymore; for those,
   you don't need this option. You want to read the Busmouse-HOWTO,
   available via ftp (user: anonymous) in
-  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 busmouse.o. If
-  you are unsure, say N and read the HOWTO nevertheless: it will tell
-  you what you have.
+  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 busmouse.o. If you are unsure, say N and read the HOWTO
+  nevertheless: it will tell you what you have.
 
 PS/2 mouse (aka "auxiliary device") support
 CONFIG_PSMOUSE
@@ -6097,15 +6723,16 @@
   for other input devices like light pens, tablets, keypads. Compaq,
   AST and IBM all use this as their mouse port on currently shipping
   machines. The trackballs of some laptops are PS/2 mice also. In
-  particular, the C&T 82C710 mouse on TI Travelmates is a PS/2
-  mouse. Although PS/2 mice are not technically bus mice, they are
-  explained in detail in the Busmouse-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.  When using a
-  PS/2 mouse, you can get problems if you want to use the mouse both
-  on the Linux console and under X. Using the "-R" option of the Linux
-  mouse managing program gpm (available from
+  particular, the C&T 82C710 mouse on TI Travelmates is a PS/2 mouse.
+  Although PS/2 mice are not technically bus mice, they are explained
+  in detail in the Busmouse-HOWTO, available via ftp (user: anonymous)
+  in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. When using a PS/2
+  mouse, you can get problems if you want to use the mouse both on the
+  Linux console and under X. Using the "-R" option of the Linux mouse
+  managing program gpm (available from
   sunsite.unc.edu:/pub/Linux/system/Daemons) solves this problem, or
   you can get the "mconv" utility also from sunsite.
+
   If you want to compile this mouse 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
@@ -6117,7 +6744,7 @@
   This is a certain kind of PS/2 mouse used on the TI Travelmate. If
   you are unsure, try first to say N here and come back if the mouse
   doesn't work. Read the Busmouse-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 PC110 digitizer pad support
 CONFIG_PC110_PAD
@@ -6125,36 +6752,44 @@
   http://toy.cabi.net; to browse the WWW, you need to have access to a
   machine on the Internet that has a program like lynx or
   netscape). It can turn the digitizer pad into a PS/2 mouse emulation
-  with tap gestures or into an absolute pad.  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 pc110pad.o.
+  with tap gestures or into an absolute pad.  
+
+  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 pc110pad.o.
 
 Microsoft busmouse support
 CONFIG_MS_BUSMOUSE
   These animals (also called Inport mice) are connected to an
   expansion board using a round connector with 9 pins. If this is what
   you have, say Y and read the Busmouse-HOWTO, available via ftp
-  (user: anonymous) in 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
-  msbusmouse.o. If you are unsure, say N and read the HOWTO
-  nevertheless: it will tell you what you have. Also be aware that
-  several vendors talk about 'Microsoft busmouse' and actually mean
-  PS/2 busmouse - so count the pins on the connector.
+  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+
+  If you are unsure, say N and read the HOWTO nevertheless: it will
+  tell you what you have. Also be aware that several vendors talk
+  about 'Microsoft busmouse' and actually mean PS/2 busmouse - so
+  count the pins on the connector.
+
+  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 msbusmouse.o. 
 
 ATIXL busmouse support
 CONFIG_ATIXL_BUSMOUSE
   This is a rare type of busmouse that is connected to the back of an
   ATI video card. Note that most ATI mice are actually Microsoft
   busmice. Read the Busmouse-HOWTO, available via ftp (user:
-  anonymous) in 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
-  atixlmouse.o. If you are unsure, say N and read the HOWTO
-  nevertheless: it will tell you what you have.
+  anonymous) in 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 atixlmouse.o. 
+
+  If you are unsure, say N and read the HOWTO nevertheless: it will
+  tell you what you have.
 
 Support for user miscellaneous modules
 CONFIG_UMISC
@@ -6180,29 +6815,36 @@
   to configure this driver during runtime. The program to do this is
   called 'qic02conf' and it is part of the 'tpqic02-support-X.Y.tar.gz'
   support package.
+
   If you want to use the qic02conf program, say Y.
 
 Floppy tape drive (QIC-80/40/3010/3020/TR-1/TR-2/TR-3) support
 CONFIG_FTAPE
   If you have a tape drive that is connected to your floppy
-  controller, say Y here. Some tape drives (like the Seagate "Tape
-  Store 3200" or the Iomega "Ditto 3200" or the Exabyte "Eagle TR-3")
-  come with a "high speed" controller of their own. These drives (and
-  their companion controllers) are also supported if you say Y here.
+  controller, say Y here. 
+
+  Some tape drives (like the Seagate "Tape Store 3200" or the Iomega
+  "Ditto 3200" or the Exabyte "Eagle TR-3") come with a "high speed"
+  controller of their own. These drives (and their companion
+  controllers) are also supported if you say Y here. 
+
   If you have a special controller (such as the CMS FC-10, FC-20,
   Mountain Mach-II, or any controller that is based on the Intel 82078
   FDC like the high speed controllers by Seagate and Exabyte and
   Iomega's "Ditto Dash") you must configure it by selecting the
   appropriate entries from the "Floppy tape controllers" sub-menu
   below and possibly modify the default values for the IRQ and DMA
-  channel and the IO base in ftape's configuration menu. If you want
-  to use your floppy tape drive on a PCI-bus based system, please read
-  the file drivers/char/ftape/README.PCI.
+  channel and the IO base in ftape's configuration menu. 
+
+  If you want to use your floppy tape drive on a PCI-bus based system,
+  please read the file drivers/char/ftape/README.PCI. 
+
   The ftape kernel driver is also available as a runtime loadable
   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 ftape.o.
+  will be called ftape.o. 
+
   Note that the Ftape-HOWTO is out of date (sorry) and documents the
   older version 2.08 of this software but still contains useful
   information. There is a web page with more recent documentation at
@@ -6218,15 +6860,18 @@
 CONFIG_ZFTAPE
   Normally, you want to say Y or M. DON'T say N here or you
   WON'T BE ABLE TO USE YOUR FLOPPY TAPE DRIVE.
+
   The ftape module itself no longer contains the routines necessary
   to interface with the kernel VFS layer (i.e. to actually write data
   to and read data from the tape drive). Instead the file system
   interface (i.e. the hardware independent part of the driver) has
   been moved to a separate module.
+
   If you say M zftape will be compiled as a runtime loadable
   module ( = code which can be inserted in and removed from the
   running kernel whenever you want). In this case you should read
   Documentation/modules.txt. The module will be called zftape.o.
+
   Regardless of whether you say Y or M here, an additional runtime
   loadable module called `zft-compressor.o' which contains code to
   support user transparent on-the-fly compression based on Ross
@@ -6234,6 +6879,7 @@
   kernel module loader (i.e. have said Y to "Kernel module loader
   support", above) then `zft-compressor.o' will be loaded
   automatically by zftape when needed.
+
   Despite its name, zftape does NOT use compression by default. The
   file Documentation/ftape.txt contains a short description of the
   most important changes in the file system interface compared to
@@ -6241,6 +6887,7 @@
   http://www-math.math.rwth-aachen.de/~LBFM/claus/ftape/ contains
   further information (to browse the WWW, you need to have access to a
   machine on the Internet that has a program like lynx or netscape).
+
   IMPORTANT NOTE: zftape can read archives created by previous
   versions of ftape and provide file mark support (i.e. fast skipping
   between tape archives) but previous version of ftape will lack file
@@ -6253,6 +6900,7 @@
   changed at run time using the MTSETBLK tape operation with the
   MTIOCTOP ioctl (i.e. with "mt -f /dev/qft0 setblk #BLKSZ" from the
   shell command line).
+
   The probably most striking difference between zftape and previous
   versions of ftape is the fact that all data must be written or read
   in multiples of a fixed block size. The block size defaults to
@@ -6260,6 +6908,7 @@
   should be either 1 or multiples of 1024 up to a maximum value of
   63488 (i.e. 62k). If you specify `1' then zftape's builtin
   compression will be disabled.
+
   Reasonable values are `10240' (GNU tar's default block size),
   `5120' (afio's default block size), `32768' (default block size some
   backup programs assume for SCSI tape drives) or `1' (no restriction
@@ -6277,15 +6926,16 @@
 
 Procfs entry for ftape
 CONFIG_FT_PROC_FS
-  Optional. Saying `Y' will result in creation of a directory
+  Optional. Saying Y will result in creation of a directory
   `/proc/ftape' under the proc file system. The files can be viewed
   with your favorite pager (i.e. use "more /proc/ftape/history" or
   "less /proc/ftape/history" or simply "cat /proc/ftape/history"). The
   file will contain some status information about the inserted
   cartridge, the kernel driver, your tape drive, the floppy disk
   controller and the error history for the most recent use of the
-  kernel driver. Saying `Y' will enlarge the size of the ftape driver
+  kernel driver. Saying Y will enlarge the size of the ftape driver
   by approximately 2k.
+
   WARNING: When compiling ftape as a module (i.e. saying `M' to
   "Floppy tape drive") it is dangerous to use ftape's proc file system
   interface. Accessing `/proc/ftape' while the module is unloaded will
@@ -6297,10 +6947,12 @@
   is ABLE to produce; it does not increase or diminish the debugging
   level itself. If unsure, leave this at its default setting,
   i.e. choose "Normal".
+
   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
   be a good idea to use "None" for emergency boot floppies.
+
   If you want to save memory then the following strategy is
   recommended: leave this option at its default setting "Normal" until
   you know that the driver works as expected, afterwards reconfigure
@@ -6309,6 +6961,7 @@
   debugging output does not increase the amount of debugging output
   printed to the console but only makes it possible to produce
   "Excessive" debugging output.
+
   Please read Documentation/ftape.txt for a short description
   how to control the amount of debugging output.
 
@@ -6319,6 +6972,7 @@
   plugged the floppy tape cable into the already existing floppy drive
   controller then you don't want to change the default setting,
   i.e. choose "Standard".
+
   Choose "MACH-2" if you have a Mountain Mach-2 controller.
   Choose "FC-10/FC-20" if you have a Colorado FC-10 or FC-20
   controller.
@@ -6329,19 +6983,23 @@
   `2'. This is necessary for any controller card that is based on
   Intel's 82078 FDC such as Seagate's, Exabyte's and Iomega's "high
   speed" controllers.
+
   If you choose something other than "Standard" then please make
   sure that the settings for the IO base address and the IRQ and DMA
   channel in the configuration menus below are correct. Use the manual
   of your tape drive to determine the correct settings!
+
   If you are already successfully using your tape drive with another
   operating system then you definitely should use the same settings
   for the IO base, the IRQ and DMA channel that have proven to work
   with that other OS.
+
   Note that this menu lets you specify only the default setting for
   the hardware setup. The hardware configuration can be changed at
   boot time (when ftape is compiled into the kernel, i.e. if you
   have said Y to "Floppy tape drive") or module load time (i.e. if you
   have said M to "Floppy tape drive").
+
   Please read also the file Documentation/ftape.txt which
   contains a short description of the parameters that can be set at
   boot or load time. If you want to use your floppy tape drive on a
@@ -6363,11 +7021,13 @@
   successfully using the tape drive with another operating system then
   you definitely should use the same settings for the IO base that has
   proven to work with that other OS.
+
   Note that this menu lets you specify only the default setting for
   the IO base. The hardware configuration can be changed at boot time
   (when ftape is compiled into the kernel, i.e. if you specified Y to
   "Floppy tape drive") or module load time (i.e. if you have said M to
   "Floppy tape drive").
+
   Please read also the file Documentation/ftape.txt which contains a
   short description of the parameters that can be set at boot or load
   time.
@@ -6387,11 +7047,13 @@
   successfully using the tape drive with another operating system then
   you definitely should use the same settings for the IO base that has
   proven to work with that other OS.
+
   Note that this menu lets you specify only the default setting for
   the IRQ channel. The hardware configuration can be changed at boot
   time (when ftape is compiled into the kernel, i.e. if you specified
   Y to "Floppy tape drive") or module load time (i.e. if you have said M
   to "Floppy tape drive").
+
   Please read also the file Documentation/ftape.txt which contains a
   short description of the parameters that can be set at boot or load
   time.
@@ -6411,11 +7073,13 @@
   successfully using the tape drive with another operating system then
   you definitely should use the same settings for the IO base that has
   proven to work with that other OS.
+
   Note that this menu lets you specify only the default setting for
   the DMA channel. The hardware configuration can be changed at boot
   time (when ftape is compiled into the kernel, i.e. if you specified
   Y to "Floppy tape drive") or module load time (i.e. if you have said M
   to "Floppy tape drive").
+
   Please read also the file Documentation/ftape.txt which contains a
   short description of the parameters that can be set at boot or load
   time.
@@ -6428,6 +7092,7 @@
   You may try to tune this if ftape annoys you with "reduced data
   rate because of excessive overrun errors" messages. However, this
   doesn't seem to have too much effect.
+
   If unsure, don't touch the initial value, i.e. leave it at "8".
 
 FDC maximum data rate
@@ -6437,6 +7102,7 @@
   speed. If this is the case you'll encounter "reduced data rate
   because of excessive overrun errors" messages and lots of retries
   before ftape finally decides to reduce the data rate.
+
   In this case it might be desirable to tell ftape beforehand that
   it need not try to run the tape drive at the highest available
   speed. If unsure, leave this disabled, i.e. leave it at 2000
@@ -6444,13 +7110,13 @@
 
 MTRR control and configuration
 CONFIG_MTRR
-  On Intel Pentium Pro systems the Memory Type Range Registers (MTRRs)
-  may be used to control processor access to memory ranges. This is
-  most useful when you have a video (VGA) card on the PCI
-  bus. Enabling write-combining allows PCI write transfers to be
-  combined into a larger transfer before bursting over the PCI
-  bus. This can increase performance of image write operations 2.5
-  times or more.
+  On Intel Pentium Pro/Pentium II systems the Memory Type Range
+  Registers (MTRRs) may be used to control processor access to memory
+  ranges. This is most useful when you have a video (VGA) card on a
+  PCI or AGP bus. Enabling write-combining allows bus write transfers
+  to be combined into a larger transfer before bursting over the
+  PCI/AGP bus. This can increase performance of image write operations
+  2.5 times or more.
   This option creates a /proc/mtrr file which may be used to manipulate
   your MTRRs. Typically the X server should use this. This should have
   a reasonably generic interface so that similar control registers on
@@ -6458,10 +7124,9 @@
   This option also fixes a problem with buggy SMP BIOSes which only
   set the MTRRs for the boot CPU and not the secondary CPUs. This can
   lead to all sorts of problems.
-  In general you should compile this into the kernel, rather than as a
-  loadable module, because the BIOS fix needs to be done early in the
-  boot sequence. If you compile this as a module, the BIOS fix will be
-  delayed until when you load the module. You do this at your own risk.
+  Compiling this as a module is not available because the BIOS fix
+  needs to be done early in the boot sequence, otherwise your machine
+  could lock up.
   See Documentation/mtrr.txt for more information.
 
 Main CPU frequency, only for DEC alpha machine
@@ -6478,34 +7143,44 @@
 Advanced Power Management
 CONFIG_APM
   APM is a BIOS specification for saving power using several different
-  techniques.  This is mostly useful for battery powered laptops with
-  APM compliant BIOSes.  Specifically, the time will be reset after a
-  USER RESUME operation, the /proc/apm device will provide battery
-  status information, and user-space programs will receive
-  notification of APM "events" (e.g., battery status
-  change). Supporting software is available; for more information,
-  read the Battery Powered Linux mini-HOWTO available via ftp (user:
-  anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.  This
-  driver does not spin down disk drives (see the hdparm(8) manpage
-  ("man 8 hdparm") for that), and it doesn't turn off VESA-compliant
-  "green" monitors.  This driver does not support the TI 4000M
-  TravelMate and the ACER 486/DX4/75 because they don't have compliant
-  BIOSes.  Many "green" desktop machines also don't have compliant
-  BIOSes, and this driver will cause those machines to panic during
-  the boot phase (typically, these machines are using a data segment
-  of 0040, which is reserved for the Linux kernel).
+  techniques. This is mostly useful for battery powered laptops with
+  APM compliant BIOSes. If you say Y here, the system time will be
+  reset after a USER RESUME operation, the /proc/apm device will
+  provide battery status information, and user-space programs will
+  receive notification of APM "events" (e.g., battery status change).
+
+  Supporting software is available; for more information, read the
+  Battery Powered Linux mini-HOWTO, available via ftp (user:
+  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini.
+
+  This driver does not spin down disk drives (see the hdparm(8)
+  manpage ("man 8 hdparm") for that), and it doesn't turn off
+  VESA-compliant "green" monitors. 
+
+  This driver does not support the TI 4000M TravelMate and the ACER
+  486/DX4/75 because they don't have compliant BIOSes. Many "green"
+  desktop machines also don't have compliant BIOSes, and this driver
+  will cause those machines to panic during the boot phase (typically,
+  these machines are using a data segment of 0040, which is reserved
+  for the Linux kernel). 
+
   If you are running Linux on a laptop, you may also want to read the
   Linux Laptop homepage on the WWW at
   http://www.cs.utexas.edu/users/kharker/linux-laptop/ (to browse the
   WWW, you need to have access to a machine on the Internet that has a
-  program like lynx or netscape).
+  program like lynx or netscape). 
+
   Generally, if you don't have a battery in your machine, there isn't
-  much point in using this driver and you should say N.  If you get
+  much point in using this driver and you should say N. If you get
   random kernel OOPSes or reboots that don't seem to be related to
-  anything, try disabling/enabling this option. Some other things to
-  try when experiencing seemingly random, "weird" problems:
+  anything, try disabling/enabling this option (or disabling/enabling
+  APM in your BIOS). 
+
+  Some other things to try when experiencing seemingly random, "weird"
+  problems:
    1) passing the "no-hlt" option to the kernel 
-   2) passing the "no-387" option to the kernel 
+   2) switching on floating point emulation in the kernel and passing
+      the "no387" option to the kernel
    3) passing the "floppy=nodma" option to the kernel
    4) passing the "mem=4M" option to the kernel (thereby disabling 
       all but the first 4M of RAM)
@@ -6583,20 +7258,22 @@
   If you say Y here (and to one of the following options) and create a
   character special file /dev/watchdog with major number 10 and minor
   number 130 using mknod ("man mknod"), you will get a watchdog, i.e.:
-  subsequently opening the file and failing to write to it for longer
-  than 1 minute will result in rebooting the machine. This could be
-  useful for a networked machine that needs to come back online as
-  fast as possible after a lock-up. There's both a watchdog
+  subsequently opening the file and then failing to write to it for
+  longer than 1 minute will result in rebooting the machine. This
+  could be useful for a networked machine that needs to come back
+  online as fast as possible after a lock-up. There's both a watchdog
   implementation entirely in software (which can sometimes fail to
   reboot the machine) and a driver for hardware watchdog boards, which
   are more robust and can also keep track of the temperature inside
   your computer. For details, read Documentation/watchdog.txt in the
   kernel source.
+
   The watchdog is usually used together with the watchdog daemon which
   is available via ftp (user: anonymous) from
-  tsx-11.mit.edu/pub/linux/sources/sbin/. This daemon can also monitor
-  NFS connections and can reboot the machine when the process table is
-  full.
+  ftp://tsx-11.mit.edu/pub/linux/sources/sbin/. This daemon can also
+  monitor NFS connections and can reboot the machine when the process
+  table is full.
+
   If unsure, say N.
 
 Disable watchdog shutdown on close
@@ -6612,10 +7289,12 @@
   If you have a WDT500P or WDT501P watchdog board, say Y here,
   otherwise N. It is not possible to probe for this board, which means
   that you have to set the IO port and IRQ it uses in the kernel
-  source at the top of drivers/char/wdt.c. If you want to compile this
-  as a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), say M here and read
-  Documentation/modules.txt. The module will be called wdt.o.
+  source at the top of drivers/char/wdt.c. 
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called wdt.o.
 
 WDT501 features
 CONFIG_WDT_501
@@ -6635,32 +7314,36 @@
 CONFIG_SOFT_WATCHDOG
   A software monitoring watchdog. This will fail to reboot your system
   from some situations that the hardware watchdog will recover
-  from. Equally it's a lot cheaper to install. This driver is also
-  available as a module ( = code which can be inserted in and removed
-  from the running kernel whenever you want). If you want to compile
-  it as a module, say M here and read Documentation/modules.txt. The
-  module will be called softdog.o.
+  from. Equally it's a lot cheaper to install. 
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The module will be called softdog.o.
 
 Berkshire Products PC Watchdog
 CONFIG_PCWATCHDOG
   This is the driver for the Berkshire Products PC Watchdog card.
   This card simply watches your kernel to make sure it doesn't freeze,
-  and if it does, it resets your computer after a certain amount of
+  and if it does, it reboots your computer after a certain amount of
   time.  This driver is like the WDT501 driver but for different
   hardware. Please read Documentation/pcwd-watchdog.txt. The PC
   watchdog cards can be ordered from http://www.berkprod.com. Some
-  example rc.local files are available from ftp.bitgate.com. 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 is called pcwd.o. If you want to compile it as a module, say
-  M here and read Documentation/modules.txt.  Most people will say N.
+  example rc.local files are available from ftp://ftp.bitgate.com. 
+
+  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 is called pcwd.o. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. Most people will say
+  N.
 
 Acquire SBC Watchdog Timer
 CONFIG_ACQUIRE_WDT
   This is the driver for the hardware watchdog on the PSC-6x86 Single
   Board Computer produced by Acquire Inc (and others). This watchdog
   simply watches your kernel to make sure it doesn't freeze, and if
-  it does, it resets your computer after a certain amount of time.
+  it does, it reboots your computer after a certain amount of time.
+
   This driver is like the WDT501 driver but for different hardware.
   This driver is also available as a module ( = code which can be 
   inserted in and removed from the running kernel whenever you want).
@@ -6677,13 +7360,15 @@
   used as a 24 hour alarm.  It reports status information via the file
   /proc/rtc and its behaviour is set by various ioctls on
   /dev/rtc. 
+
   People running SMP (= multiprocessor) versions of Linux should say Y
   here to read and set the RTC clock in a SMP compatible
-  fashion. (They should also Documentation/smp and
+  fashion. (They should also read Documentation/smp and
   Documentation/IO-APIC.txt and 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 think you have a use for such a device (such as periodic data
   sampling), then say Y here, and go read the file
   Documentation/rtc.txt for details.
@@ -6707,11 +7392,12 @@
   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. On Atari machines, /dev/nvram is always configured and
-  does not need to be selected.  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
-  nvram.o. If you want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  does not need to be selected.  
+
+  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 nvram.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 PC joystick support
 CONFIG_JOYSTICK
@@ -6721,11 +7407,12 @@
   using mknod ("man mknod"), you can read the status of the buttons
   and the x and y coordinates from that file. Please read the file
   Documentation/joystick.txt which contains more information and the
-  location of the joystick package that you'll need.  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 joystick.o. If you want to compile it as a module, say M
-  here and read Documentation/modules.txt.
+  location of the joystick package that you'll need.  
+
+  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 joystick.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Sound card support
 CONFIG_SOUND
@@ -6734,10 +7421,11 @@
   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 sunsite.unc.edu:/pub/Linux/docs/HOWTO. There is also some
+  from ftp://sunsite.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.
+
   If you have a PnP sound card and you want to configure it at boot
   time using the ISA PnP tools (read
   http://www.roestock.demon.co.uk/isapnptools/ (to browse the WWW, you
@@ -6748,11 +7436,11 @@
   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.
+
   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.
-  Kernel patches and programs to do that are at
-  sunsite.unc.edu:/pub/Linux/kernel/patches/console/pcsndrv-X.X.tar.gz,
-  to be extracted with "tar xzvf filename".
+  Kernel patches and programs to do that are in the pcsndrv package on
+  sunsite.unc.edu:/pub/Linux/kernel/patches/console/.
 
 ProAudioSpectrum 16 support
 CONFIG_PAS
@@ -6769,7 +7457,11 @@
   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
-  SoundBlaster compatible. If you have an SB AWE 32 or SB AWE 64, say
+  SoundBlaster compatible. 
+
+  Please read Documentation/sound/Soundblaster.
+
+  If you have an SB AWE 32 or SB AWE 64, say
   Y here and to "Additional lowlevel drivers" and to "SB32/AWE
   support" below.
 
@@ -6778,20 +7470,8 @@
   The IBM Mwave can do what's loosely describable as emulation of an
   8bit SoundBlaster card if you load the right firmware from DOS warm
   boot and pray and your machine happens to like you. Say Y if you are
-  doing this as the IRQ test normally fails on the Mwave emulation. If
-  you'd like real MWAVE support phone IBM (425-556-8822) and ask them
-  why they still haven't released any documentation.
-  [http://204.200.238.31/cgi-bin/link.pl?co=i&cl=/ts/ibm/contact.html]
-
-Are you using the IBM Mwave "emulation" of SB ?
-CONFIG_SB_MWAVE
-  The IBM Mwave can do whats loosely describable as emulation of an 8bit
-  soundblaster if you load the right firmware from DOS warm boot and pray
-  and your machine happens to like you. Say Y if you are doing this as the
-  IRQ test normally fails on the mwave emulation. If you'd like real MWAVE
-  support phone IBM (425-556-8822) and ask them why they still haven't 
-  released any documentation.
-  [http://204.200.238.31/cgi-bin/link.pl?co=i&cl=/ts/ibm/contact.html]
+  doing this as the IRQ test normally fails on the Mwave emulation.
+  Please read Documentation/sound/mwave.
 
 Generic OPL2/OPL3 FM synthesizer support
 CONFIG_ADLIB
@@ -6801,16 +7481,17 @@
   these cards may cause trouble (I don't currently know of any such
   cards, however). If unsure, say Y.
 
-Loopback MIDI device support
-CONFIG_VMIDI
+#Loopback MIDI device support
+#CONFIG_VMIDI
 ###
 ### somebody please fill this in.
 ###
-
+#
 Gravis Ultrasound support
 CONFIG_GUS
   Say Y here for any type of Gravis Ultrasound card, including
-  the GUS or GUS MAX.
+  the GUS or GUS MAX. Please read Documentation/sound/ultrasound for
+  more information.
 
 MPU-401 support (NOT for SB16)
 CONFIG_MPU401
@@ -6829,12 +7510,18 @@
   UART chip. This interface is rarely found on sound cards.  It's safe
   to answer N to this question.
 
-PSS (ECHO-ADI2111) support
+PSS (AD1848, ADSP-2115, ESC614) support
 CONFIG_PSS
   Answer Y only if you have Orchid SW32, Cardinal DSP16 or some other
   card based on the PSS chipset (AD1848 codec + ADSP-2115 DSP chip +
   Echo ESC614 ASIC CHIP).
 
+#Enable PSS mixer (Beethoven ADSP-16 and other compatible)
+#CONFIG_PSS_MIXER
+###
+### Don't know what this is
+###
+#
 16 bit sampling option of GUS (_NOT_ GUS MAX)
 CONFIG_GUS16
   Answer Y if you have installed the 16 bit sampling daughtercard on
@@ -6851,6 +7538,7 @@
   safe to answer Y if you have the original Windows Sound System card
   made by Microsoft or Aztech SG 16 Pro (or NX16 Pro).  Also you may
   answer Y in case your card is NOT among these:
+
      ATI Stereo F/X, AdLib, Audio Excell DSP16, Cardinal DSP16,
      Ensoniq SoundScape (and compatibles made by Reveal and Spea),
      Gravis Ultrasound, Gravis Ultrasound ACE, Gravis Ultrasound Max,
@@ -6864,6 +7552,7 @@
      Blaster 2.0, Sound Blaster AWE32, Sound Blaster Pro, TI TM4000M
      notebook, ThunderBoard, Turtle Beach Tropez, Yamaha FM
      synthesizers (OPL2, OPL3 and OPL4), 6850 UART MIDI Interface.
+
   For cards having native support in VoxWare, consult the card
   specific instructions in drivers/sound/Readme.cards. Some drivers
   have their own MSS support and saying Y to this option will cause a
@@ -6883,26 +7572,25 @@
 Support for OPTi MAD16 and/or Mozart based cards
 CONFIG_MAD16
   Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi
-  82C928 or 82C929 or 82C931) audio interface chip. For the 82C931,
-  please read drivers/sound/README.C931. These chips are currently
-  quite common so it's possible that many no-name cards have one of
-  them. In addition the MAD16 chip is used in some cards made by known
-  manufacturers such as Turtle Beach (Tropez), Reveal (some models)
-  and Diamond (latest ones).
+  82C928 or 82C929 or 82C931) audio interface chip. Please read
+  Documentation/sound/MAD16. Please read Documentation/sound/Opti. For
+  the 82C931, additional information is in drivers/sound/README.C931.
+  These chips are currently quite common so it's possible that many
+  no-name cards have one of them. In addition the MAD16 chip is used
+  in some cards made by known manufacturers such as Turtle Beach
+  (Tropez), Reveal (some models) and Diamond (latest ones).
 
 Support MIDI in older MAD16 based cards (requires SB)
 CONFIG_MAD16_OLDCARD
-  Answer Y (or M) if you have an older card based on the C928
-  or Mozart chipset and you want to have  MIDI support. If you
-  enable this option you also need to enable support for SoundBlaster.
-
- If you answer Y here you will
-  also need to enable the SoundBlaster driver.
+  Answer Y (or M) if you have an older card based on the C928 or
+  Mozart chipset and you want to have MIDI support. If you enable this
+  option you also need to enable support for SoundBlaster.
 
 Support for Crystal CS4232 based (PnP) cards
 CONFIG_CS4232
   Say Y here if you have a card based on the Crystal CS4232 chip set,
-  which use the Plug and Play protocol.
+  which use the Plug and Play protocol. Please read
+  Documentation/sound/CS4232 for more info.
 
 Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers
 CONFIG_MAUI
@@ -6923,7 +7611,8 @@
 
 FM synthesizer (YM3812/OPL-3) support
 CONFIG_YM3812
-  Answer Y here, unless you know you will not need the option.
+  Answer Y here, unless you know you will not need the option. For
+  OPL-3 cards, you may want to read Documentation/sound/OPL3.
 
 Sun Audio support
 CONFIG_SUN_AUDIO
@@ -6951,9 +7640,10 @@
 SB32/AWE support
 CONFIG_AWE32_SYNTH
   Say Y here if you have a SoundBlaster SB32, AWE32-PnP, SB AWE64 or
-  similar sound card. See drivers/sound/lowlevel/README.awe and the
-  Soundblaster-AWE mini-HOWTO, available via ftp (user: anonymous)
-  from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini for more info.
+  similar sound card. See drivers/sound/lowlevel/README.awe,
+  Documentation/sound/AWE32 and the Soundblaster-AWE mini-HOWTO,
+  available via ftp (user: anonymous) from
+  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini for more info.
 
 Gallant's Audio Excel DSP 16 support (SC-6000 and SC-6600)
 CONFIG_AEDSP16
@@ -6993,10 +7683,11 @@
   This is for kernel hackers who want to know how much time the kernel
   spends in the various procedures. The information is stored in
   /proc/profile (say Y to "/proc filesystem support"!) and in order to
-  read it, you need the readprofile package from sunsite.unc.edu. Its
-  manpage gives information regarding the format of profiling data. To
-  become a kernel hacker, you can start with the Kernel Hacker's Guide
-  at http://www.redhat.com:8080/HyperNews/get/khg.html (to browse the
+  read it, you need the readprofile package from
+  sunsite.unc.edu:/pub/Linux/kernel. Its manpage gives information
+  regarding the format of profiling data. To become a kernel hacker,
+  you can start with the Kernel Hacker's Guide at
+  http://www.redhat.com:8080/HyperNews/get/khg.html (to browse the
   WWW, you need to have access to a machine on the Internet that has a
   program like lynx or netscape). Mere mortals say N.
 
@@ -7009,14 +7700,13 @@
 
 Magic System Request Key support
 CONFIG_MAGIC_SYSRQ
-  This is for kernel hackers who want to have some control over the
-  system even if the system crashes during kernel debugging (e.g., to
-  flush the disks, reboot the system immediately or dump some status
-  information). This is accomplished by pressing various keys while
-  holding SysRq (Alt+PrintScreen). As you are expected to be a kernel
-  hacker to use this, the simple rule about learning what the keys
-  mean is "Use the source, Luke!" -- read drivers/char/sysrq.c.  
-  Don't say Y unless you really know what this hack does.
+  If you say Y here, you will have some control over the system even
+  if the system crashes for example during kernel debugging (e.g., you
+  will be able to flush the disks, reboot the system immediately or
+  dump some status information). This is accomplished by pressing
+  various keys while holding SysRq (Alt+PrintScreen). The keys are
+  documented in Documentation/sysrq.txt. Don't say Y unless you really
+  know what this hack does.
 
 ISDN subsystem
 CONFIG_ISDN
@@ -7030,31 +7720,33 @@
   provider purchased an ISDN line from the phone company.  For
   details, read http://alumni.caltech.edu/~dank/isdn/ 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.)  This driver allows you
-  to use an ISDN-card for networking connections and as dialin/out
-  device. The isdn-tty's have a built in AT-compatible modem
-  emulator. Network devices support autodial, channel-bundling,
-  callback and caller-authentication without having a daemon
-  running. A reduced T.70 protocol is supported with tty's suitable
-  for German BTX. On D-Channel, the protocols EDSS1 (Euro-ISDN) and
-  1TR6 (German style) are supported. See Documentation/isdn/README for
-  more information.  If you want to compile the ISDN code 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 isdn.o.  If
-  unsure, say N.
+  that has a program like lynx or netscape.)  
+
+  This driver allows you to use an ISDN-card for networking
+  connections and as dialin/out device. The isdn-tty's have a built in
+  AT-compatible modem emulator. Network devices support autodial,
+  channel-bundling, callback and caller-authentication without having
+  a daemon running. A reduced T.70 protocol is supported with tty's
+  suitable for German BTX. On D-Channel, the protocols EDSS1
+  (Euro-ISDN) and 1TR6 (German style) are supported. See
+  Documentation/isdn/README for more information. 
+
+  If you want to compile the ISDN code 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 isdn.o. If unsure, say N.
 
 Support synchronous PPP
 CONFIG_ISDN_PPP
   Over digital connections such as ISDN, there is no need to
   synchronize sender and recipient's clocks with start and stop bits
-  as is done over telephone lines. Instead, one can use "synchronous
-  PPP". Saying Y here will include this protocol. This protocol is
-  used by Cisco and Sun for example. So you want to say Y here if the
-  other end of your ISDN connection supports it. You will need a
-  special version of pppd (called ipppd) for using this feature. See
-  Documentation/isdn/README.syncppp and Documentation/isdn/syncPPP.FAQ
-  for more information.
+  as is done over analog telephone lines. Instead, one can use
+  "synchronous PPP". Saying Y here will include this protocol. This
+  protocol is used by Cisco and Sun for example. So you want to say Y
+  here if the other end of your ISDN connection supports it. You will
+  need a special version of pppd (called ipppd) for using this
+  feature. See Documentation/isdn/README.syncppp and
+  Documentation/isdn/syncPPP.FAQ for more information.
 
 Support generic MP (RFC 1717)
 CONFIG_ISDN_MPP
@@ -7065,6 +7757,7 @@
 Use VJ-compression with synchronous PPP
 CONFIG_ISDN_PPP_VJ
   This enables Van Jacobson header compression for synchronous PPP.
+  Say Y if the other end of the connection supports it.
 
 Support audio via ISDN
 CONFIG_ISDN_AUDIO
@@ -7079,9 +7772,9 @@
 
 X.25 PLP on top of ISDN (EXPERIMENTAL)
 CONFIG_ISDN_X25
-  This experimental feature provides X.25 over ISDN. See
-  Documentation/isdn/README.x25 for more information about how to
-  configure and what other options must be enabled for using X.25.
+  This experimental feature provides the X.25 protocol over ISDN
+  connections. See Documentation/isdn/README.x25 for more information
+  if you are thinking about using this.
 
 ICN 2B and 4B support
 CONFIG_ISDN_DRV_ICN
@@ -7091,14 +7784,16 @@
   this card, additional firmware is necessary, which has to be
   downloaded into the card using a utility which is distributed
   separately.  See Documentation/isdn/README and README.icn for more
-  information. 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 icn.o.
+  information. 
+
+  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 icn.o.
 
 isdnloop support
 CONFIG_ISDN_DRV_LOOP
-  This driver provides a virtual ISDN card. It's primary purpose is
+  This driver provides a virtual ISDN card. Its primary purpose is
   testing of linklevel features or configuration without getting
   charged by your service-provider for lots of phone calls.
   You need will need the loopctrl utility from the latest isdn4k-utils
@@ -7109,11 +7804,19 @@
   This is a driver supporting the Siemens chipset on various
   ISDN-cards (like AVM A1, Elsa ISDN cards, Teles S0-16.0, Teles
   S0-16.3, Teles S0-8, Teles/Creatix PnP, ITK micro ix1 and many
-  compatibles). 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 hisax.o.  See Documentation/isdn/README.HiSax for
-  further informations on using this driver.
+  compatibles). 
+
+  HiSax is just the name of this driver, not the name of any hardware.
+  
+  If you have a card with such a chipset, you should say Y here and
+  also to the configuration option of the driver for your particular
+  card, below.
+
+  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 hisax.o. See Documentation/isdn/README.HiSax for more
+  information on using this driver.
 
 HiSax Support for Teles 16.0/8.0
 CONFIG_HISAX_16_0
@@ -7129,21 +7832,21 @@
   the Teles/Creatix PnP and the Teles PCMCIA.
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for Teles 16.3c
 CONFIG_HISAX_TELES3C
   This enables HiSax support for the Teles ISDN-cards 16.3c.
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for AVM A1 (Fritz)
 CONFIG_HISAX_AVM_A1
   This enables HiSax support for the AVM A1 (aka "Fritz").
   See Documentation/isdn/README.HiSax on how to configure it
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for Elsa ISA cards
 CONFIG_HISAX_ELSA
@@ -7151,68 +7854,71 @@
   for the Elsa Quickstep series cards and Elsa PCMCIA.
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for ITK ix1-micro Revision 2
 CONFIG_HISAX_IX1MICROR2
   This enables HiSax support for the ITK ix1-micro Revision 2 card.
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for Eicon.Diehl Diva cards
 CONFIG_HISAX_DIEHLDIVA
   This enables HiSax support for the Eicon.Diehl Diva none PRO versions
   passive ISDN cards.
+
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for ASUSCOM cards
 CONFIG_HISAX_ASUSCOM
   This enables HiSax support for the AsusCom and their OEM versions
   passive ISDN cards.
+
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for TELEINT cards
 CONFIG_HISAX_TELEINT
   This enables HiSax support for the TELEINT SA1 semiactiv ISDN card.
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for Sedlbauer speed card/win-star
 CONFIG_HISAX_SEDLBAUER
   This enables HiSax support for the Sedlbauer passive ISDN cards.
   See Documentation/isdn/README.HiSax on how to configure it 
   using the different cards, a different D-channel protocol, or
-  non-standard irq/port settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for USR Sportster internal TA
 CONFIG_HISAX_SPORTSTER
   This enables HiSax support for the USR Sportster internal TA card.
-  See Documentation/isdn/README.HiSax on how to configure it 
-  using a different D-channel protocol, or non-standard irq/port settings.
+  See Documentation/isdn/README.HiSax on how to configure it using a
+  different D-channel protocol, or non-standard IRQ/port settings.
 
 HiSax Support for MIC card
 CONFIG_HISAX_MIC
-  This enables HiSax support for the ITH MIC card.
-  See Documentation/isdn/README.HiSax on how to configure it 
-  using a different D-channel protocol, or non-standard irq/port settings.
+  This enables HiSax support for the ITH MIC card. See
+  Documentation/isdn/README.HiSax on how to configure it using a
+  different D-channel protocol, or non-standard IRQ/port settings.
 
 HiSax Support for NETjet card
 CONFIG_HISAX_NETJET
-  This enables HiSax support for the NetJet from Traverse Technologies.
-  See Documentation/isdn/README.HiSax on how to configure it 
-  using a different D-channel protocol, or non-standard irq/port settings.
+  This enables HiSax support for the NetJet from Traverse
+  Technologies. See Documentation/isdn/README.HiSax on how to
+  configure it using a different D-channel protocol, or non-standard
+  IRQ/port settings.
 
 HiSax Support for Niccy PnP/PCI card
 CONFIG_HISAX_NICCY
-  This enables HiSax support for the Dr. Neuhaus Niccy PnP or PCI.
-  See Documentation/isdn/README.HiSax on how to configure it 
-  using a different D-channel protocol, or non-standard irq/port settings.
+  This enables HiSax support for the Dr. Neuhaus Niccy PnP or PCI. See
+  Documentation/isdn/README.HiSax on how to configure it using a
+  different D-channel protocol, or non-standard IRQ/port settings.
 
 HiSax Support for Am7930 (EXPERIMENTAL)
 CONFIG_HISAX_AMD7930
@@ -7221,45 +7927,57 @@
 
 HiSax Support for EURO/DSS1
 CONFIG_HISAX_EURO
-  You should choose the D-channel protocol your local
-  telephone service provider uses here by saying Y or N.
-  NOTE: This is mutually exclusive with HiSax Support for
-  German 1TR6 if you have only one ISDN card installed.
+  Say Y or N according to the D-channel protocol which your local
+  telephone service company provides.
+
+  NOTE: If you say Y here and you have only one ISDN card installed,
+  you cannot say Y to "HiSax Support for German 1TR6", below. And vice
+  versa.
 
-Support for german tarifinfo
+Support for German tariff info
 CONFIG_DE_AOC
-  If you want, that HiSax send messages to the linklevel on each
-  AOCD/AOCE, enable this. This works only in Germany.
+  If you want that the HiSax hardware driver sends messages to the
+  upper level of the isdn code on each AOCD (Advice Of Charge, During
+  the call - transmission of the fee information during a call) and on
+  each AOCE (Advice Of Charge, at the End of the call - transmission
+  of fee information at the end of the call), say Y here. This works
+  only in Germany.
 
-Support for australian Microlink service (not for std. EURO)
+Support for Australian Microlink service (not for std. EURO)
 CONFIG_HISAX_ML
-  If you are in Australia and connected on the Microlink telephone
-  network enable this, because here are little differences in protocol.
+  If you are in Australia and connected to the Microlink telephone
+  network, enable this, because there are little differences in
+  protocol.
+  
   Please don't enable this in other countries.
 
 HiSax Support for US/NI-1 (not released yet)
 CONFIG_HISAX_NI1
-  You should choose the D-channel protocol your local
-  telephone service provider uses here by saying Y or N.
+  Say Y or N according to the D-channel protocol which your local
+  telephone service company provides.
 
 HiSax Support for German 1TR6
 CONFIG_HISAX_1TR6
-  You should choose the D-channel protocol your local
-  telephone service provider uses here by saying Y or N.
-  NOTE: This is mutually exclusive with HiSax Support for
-  EURO/DSS1 if you have only one ISDN card installed.
+  Say Y or N according to the D-channel protocol which your local
+  telephone service company provides.
+
+  NOTE: If you say Y here and you have only one ISDN card installed,
+  you cannot say Y to "HiSax Support for EURO/DSS1", above. And vice
+  versa.
 
 PCBIT-D support
 CONFIG_ISDN_DRV_PCBIT
-  This enables support for the PCBIT ISDN-cards. This card is
+  This enables support for the PCBIT ISDN-card. This card is
   manufactured in Portugal by Octal. For running this card, additional
   firmware is necessary, which has to be downloaded into the card
   using a utility which is distributed separately.  See
   Documentation/isdn/README and Documentation/isdn/README.pcbit for
-  more information. 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 pcbit.o.
+  more information. 
+
+  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 pcbit.o.
 
 Spellcaster support (EXPERIMENTAL)
 CONFIG_ISDN_DRV_SC
@@ -7282,11 +8000,12 @@
   interface for this card is provided. In order to use this card,
   additional firmware is necessary, which has to be downloaded into
   the card using a utility which is distributed separately. Please
-  read the file Documentation/isdn/README.avmb1.  This code 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 avmb1.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  read the file Documentation/isdn/README.avmb1.  
+
+  This code 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 avmb1.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Verbose reason code reporting (kernel size +=7K)
 CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
@@ -7296,7 +8015,7 @@
 
 IBM Active 2000 support (EXPERIMENTAL)
 CONFIG_ISDN_DRV_ACT2000
-  This enables support for IBM Active 2000 ISDN card. In order to use
+  Say Y here if you have an IBM Active 2000 ISDN card. In order to use
   this card, additional firmware is necessary, which has to be loaded
   into the card using a utility which is part of the latest isdn4k-utils
   package. Please read the file Documentation/isdn/README.act2000 for
@@ -7319,23 +8038,24 @@
 CONFIG_SUN_OPENPROMIO
   This driver provides user programs with an interface to the Sparc
   PROM device tree. The driver implements a SunOS-compatible
-  interface and a NetBSD-compatible interface. 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 and read
-  Documentation/modules.txt. If unsure, say Y.
+  interface and a NetBSD-compatible interface. 
 
-Mostek real time clock support
-CONFIG_SUN_MOSTEK_RTC
+  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 and read Documentation/modules.txt. If unsure, say Y.
 
-Siemens SAB82532 serial support
-CONFIG_SAB82532
+#Mostek real time clock support
+#CONFIG_SUN_MOSTEK_RTC
+#
+#Siemens SAB82532 serial support
+#CONFIG_SAB82532
 ###
 ### Please someone fill these in.
 ###
-
+#
 # m68k-specific kernel options
 # Documented by Chris Lawrence <quango@themall.net> et al.
-
+#
 Amiga support
 CONFIG_AMIGA
   This option enables support for the Amiga series of computers.  If
@@ -7425,6 +8145,7 @@
   it will enlarge your kernel by about 10KB. The identification
   information is also available through /proc/zorro (say Y to
   "/proc filesystem support"!).
+
   Note that even if you say N here, you can still use your expansion
   cards. If in doubt, say Y.
 
@@ -7494,10 +8215,11 @@
   driver is also the basis for certain other drivers for devices
   attached to the ACSI bus: Atari SLM laser printer, BioNet-100
   Ethernet, and PAMsNet Ethernet. If you want to use one of these
-  devices, you need ACSI support, too. 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 acsi.o.
+  devices, you need ACSI support, too. 
+
+  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 acsi.o.
 
 Probe all LUNs on each ACSI device
 CONFIG_ACSI_MULTI_LUN
@@ -7541,6 +8263,7 @@
   (such as the GVP A4008 or a Combo board).  Otherwise, say N.
   This driver does NOT work for the T-Rex series of accelerators from
   TekMagic and GVP-M.
+
   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 gvp11.o. If you want to compile it
@@ -7598,6 +8321,7 @@
 CONFIG_ARIADNE
   If you have a VillageTronics Ariadne Ethernet adapter, say Y.
   Otherwise, say N.
+
   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 is called ariadne.o. If you want to compile it as
@@ -7607,6 +8331,7 @@
 CONFIG_A2065
   If you have a Commodore A2065 Ethernet adapter, say Y.  Otherwise,
   say N.
+
   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 is called a2065.o. If you want to compile it as a
@@ -7615,6 +8340,7 @@
 Hydra support
 CONFIG_HYDRA
   If you have a Hydra Ethernet adapter, say Y.  Otherwise, say N.
+
   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 is called hydra.o. If you want to compile it as a
@@ -7641,18 +8367,20 @@
 Multiface Card III parallel support
 CONFIG_MULTIFACE_III_LP
   If you have a Multiface III card for your Amiga, and want to use its
-  parallel port in Linux, say Y.  Otherwise, say N.  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 is
-  called lp_m68k.o. If you want to compile it as a module, say M here
-  and read Documentation/modules.txt.
+  parallel port in Linux, say Y.  Otherwise, say N.  
+
+  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 is called lp_m68k.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
 
 Amiga mouse support
 CONFIG_AMIGAMOUSE
-  If you want to be able to use an Amiga mouse in Linux, say Y.  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 is called amigamouse.o. If you want to compile it as a
+  If you want to be able to use an Amiga mouse in Linux, say Y.  
+
+  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 is called amigamouse.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
 Amiga Copper Console
@@ -7664,21 +8392,24 @@
 
 Atari mouse support
 CONFIG_ATARIMOUSE
-  If you want to be able to use an Atari mouse in Linux, say Y.  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 is called atarimouse.o. If you want to compile it as a
+  If you want to be able to use an Atari mouse in Linux, say Y.  
+
+  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 is called atarimouse.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
 Atari MFP serial support
 CONFIG_ATARI_MFPSER
   If you like to use the MFP serial ports ("Modem1", "Serial1") under
   Linux, say Y. The driver equally supports all kinds of MFP serial
-  ports and automatically detects whether Serial1 is available. This
-  driver is also available as a module ( = code which can be inserted
-  in and removed from the running kernel whenever you want).  If you
-  want to compile it as a module, say M here and read
-  Documentation/modules.txt.
+  ports and automatically detects whether Serial1 is available. 
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. 
+
   Note for Falcon users: You also have an MFP port, it's just not
   wired to the outside... But you could use the port under Linux.
 
@@ -7688,10 +8419,12 @@
   LAN) and like to use them under Linux, say Y. All built-in SCC's are
   supported (TT, MegaSTE, Falcon), and also the ST-ESCC. If you have
   two connectors for channel A (Serial2 and LAN), they are visible as
-  two separate devices. This driver is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). If you want to compile it as a module, say M
-  here and read Documentation/modules.txt.
+  two separate devices. 
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.
 
 Atari SCC serial DMA support
 CONFIG_ATARI_SCC_DMA
@@ -7704,6 +8437,7 @@
 Atari MIDI serial support
 CONFIG_ATARI_MIDI
   If you want to use your Atari's MIDI port in Linux, say Y.
+
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you
   want). If you want to compile it as a module, say M here and read
@@ -7714,6 +8448,7 @@
   If you want to be able to use the DSP56001 in Falcons, say Y.
   This driver is still experimental, and if you don't know what it is,
   or if you don't have this processor, just say N.
+
   This driver is also available as a module ( = code which can be inserted
   in and removed from the running kernel whenever you want). If you
   want to compile it as a module, say M here and read
@@ -7723,6 +8458,7 @@
 CONFIG_AMIGA_BUILTIN_SERIAL
   If you want to use your Amiga's built-in serial port in Linux, say
   Y.
+
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you
   want). If you want to compile it as a module, say M here and read
@@ -7737,9 +8473,10 @@
 CONFIG_MULTIFACE_III_TTY
   If you want to use a Multiface III card's serial port in Linux, say
   Y.
-  This driver is also available as a module ( = code which can be inserted
-  in and removed from the running kernel whenever you want). If you
-  want to compile it as a module, say M here and read
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
   Documentation/modules.txt.
 
 Amiga or Atari DMA sound support
@@ -7748,6 +8485,7 @@
   Linux, answer Y to this question.  This will provide a Sun-like
   /dev/audio, compatible with the Linux/i386 sound system.  Otherwise,
   say N.
+
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you
   want). If you want to compile it as a module, say M here and read
@@ -7826,11 +8564,12 @@
   On Power Macintoshes (and clones) with two SCSI buses, the external
   SCSI bus is usually controlled by a 53C94 SCSI bus adaptor.  Older
   machines which only have one SCSI bus, such as the 7200, also use
-  the 53C94.  Say Y to include support for the 53C94.  This driver is
-  also available as a module called mac53c94.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.
+  the 53C94.  Say Y to include support for the 53C94.  
+
+  This driver is also available as a module called mac53c94.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.
 
 MACE (Power Mac Ethernet) support
 CONFIG_MACE
@@ -7842,34 +8581,42 @@
 CONFIG_VIDEO_DEV
   Support for audio/video capture and overlay devices. The exact
   capabilities of each device vary. User tools for this are available
-  from ftp://ftp.uk.linux.org/pub/linux/video4linux.  This driver is
-  also available as a module called videodev.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.
+  from ftp://ftp.uk.linux.org/pub/linux/video4linux.  
+
+  This driver is also available as a module called videodev.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.
 
 BT848 Video For Linux
 CONFIG_VIDEO_BT848
   Support for BT848 based frame grabber/overlay boards. This includes
-  the Miro, Hauppauge and STB boards. This driver is
-  also available as a module called bttv.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.
+  the Miro, Hauppauge and STB boards. 
+
+  This driver is also available as a module called bttv.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.
 
 SAA5249 Teletext processor
 CONFIG_VIDEO_SAA5249
-  Support for I2C bus based teletext using the SAA5249 chip. At the moment
-  this is only useful on some european WinTV cards.
+  Support for I2C bus based teletext using the SAA5249 chip. At the
+  moment this is only useful on some European WinTV cards.
+
+  This driver is also available as a module called saa5249.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.
 
 Quickcam BW Video For Linux
 CONFIG_VIDEO_BWQCAM
   Say Y have if you the black and white version of the QuickCam
-  camera. See the next option for the color version. This driver is
-  also available as a module called bw-qcam.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.
+  camera. See the next option for the color version. 
+
+  This driver is also available as a module called bw-qcam.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.
 
 Colour QuickCam Video For Linux
 CONFIG_VIDEO_CQCAM
@@ -7886,14 +8633,13 @@
   from the running kernel whenever you want). If you want to compile
   it as a module, say M here and read Documentation/modules.txt.
 
-# need an empty line after last entry, for sed script in Configure.
 #
 # A couple of things I keep forgetting:
-#   capitalize: Internet, Intel, SCSI, NetWare, PCI, IRQ, DMA
+#   capitalize: DMA, Internet, Intel, IRQ, Linux, NetWare, NFS, PCI, SCSI
 #   two words: hard drive, hard disk, sound card
-#   other: it's safe to save.
+#   other: it's safe to save; daemon
 #
-# This is used by ispell.el:
+# This is used by Emacs' spell checker ispell.el:
 #
 # LocalWords:  CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp sunsite
 # LocalWords:  unc edu docs emu README kB BLK DEV FD Thinkpad fd MFM RLL IDE gz
@@ -8053,7 +8799,13 @@
 # LocalWords:  dstr EPAT EPEZ epat EPIA epia FreeCom FRPW frpw KingByte KBIC HW
 # LocalWords:  KingByte's kbic OnSpec ValuStore FASTROUTE fastroute FLOWCONTROL
 # LocalWords:  struct APIC realtime OSs LynxOS CNC tmp cvf HFS hfs ADFS Risc os
-# LocalWords:  StrongARM adfs ncpmount namespace SUBDIR reexport NDS kcore FT
+# LocalWords:  adfs ncpmount namespace SUBDIR reexport NDS kcore FT SPX spx DAT
 # LocalWords:  interserver BLKSZ NUMBUFFERS apmd Tadpole ANA roestock QuickCam
 # LocalWords:  isapnptools Colour CQCAM colour Connectix QuickClip prive mentre
 # LocalWords:  KMOD kmod conformant utexas kharker UnixWare Mwave cgi cl ts ibm
+# LocalWords:  eXchange threepio oakland simtel pre ULTRAMCA EtherLink isa luik
+# LocalWords:  EtherLink OpenBSD pts DEVPTS devpts ptmx ttyp glibc readback SA
+# LocalWords:  mwave OLDCARD isdnloop linklevel loopctrl Eicon Diehl DIEHLDIVA
+# LocalWords:  ASUSCOM AsusCom TELEINT semiactiv Sedlbauer Sportster TA MIC ITH
+# LocalWords:  NETjet NetJet Niccy Neuhaus sparcs AOC AOCD AOCE Microlink SAA
+# LocalWords:  teletext WinTV saa iproute tc
diff -u --recursive --new-file v2.1.99/linux/Documentation/filesystems/vfs.txt linux/Documentation/filesystems/vfs.txt
--- v2.1.99/linux/Documentation/filesystems/vfs.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/filesystems/vfs.txt	Sat May  2 14:35:51 1998
@@ -10,7 +10,6 @@
 Hopefully this helps anyone attempting such a feat, as well as clearing up
 a few important points/dependencies.
 
-
 register_filesystem (struct file_system_type *fstype)
 =====================================================
 
@@ -133,10 +132,12 @@
 
 	int (*follow_link) (struct inode *,struct inode *,int,int,struct inode **);
 	[optional]
-		The follow_link function is only necessary if a filesystem uses a really
-		twisted form of symbolic links - namely if the symbolic link comes from a
-		foreign filesystem that makes no sense....
-		I threw this one out - too much redundant code!
+		follow_link must be implemented if readlink is implemented.
+		Note that follow_link can return a different inode than a
+		lookup_dentry() on the result of readlink() would return.
+		The proc filesystem, in particular, uses this feature heavily.
+		For most user filesystems, however, follow_link() and readlink()
+		should return consistent results.
 
 	int (*readpage) (struct inode *, struct page *);	[optional]
 	int (*writepage) (struct inode *, struct page *);	[mandatory with readpage]
diff -u --recursive --new-file v2.1.99/linux/Documentation/mtrr.txt linux/Documentation/mtrr.txt
--- v2.1.99/linux/Documentation/mtrr.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/mtrr.txt	Sat May  2 17:42:08 1998
@@ -1,15 +1,15 @@
 MTRR (Memory Type Range Register) control
-17 Dec 1997
+2 May 1998
 Richard Gooch
 <rgooch@atnf.csiro.au>
 
-  On Intel Pentium Pro systems the Memory Type Range Registers (MTRRs)
-  may be used to control processor access to memory ranges. This is
-  most useful when you have a video (VGA) card on the PCI
-  bus. Enabling write-combining allows PCI write transfers to be
-  combined into a larger transfer before bursting over the PCI
-  bus. This can increase performance of image write operations 2.5
-  times or more.
+  On Intel Pentium Pro/Pentium II systems the Memory Type Range
+  Registers (MTRRs) may be used to control processor access to memory
+  ranges. This is most useful when you have a video (VGA) card on a
+  PCI or AGP bus. Enabling write-combining allows bus write transfers
+  to be combined into a larger transfer before bursting over the
+  PCI/AGP bus. This can increase performance of image write operations
+  2.5 times or more.
 
   The CONFIG_MTRR option creates a /proc/mtrr file which may be used
   to manipulate your MTRRs. Typically the X server should use
@@ -30,13 +30,40 @@
 % cat /proc/mtrr
 reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
 reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
-reg05: base=0x80000000 (2048MB), size=   4MB: write-combining, count=1
 ===============================================================================
 Creating MTRRs from the shell:
-% echo "base=0x80000000 size=0x400000 type=write-combining" >! /proc/mtrr
+# echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr
+
+And the result thereof:
+% cat /proc/mtrr
+reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
+reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
+reg02: base=0xf8000000 (3968MB), size=   4MB: write-combining, count=1
+
+This is for videoram at base address 0xf8000000 and size 4 MBytes. To
+find out your base address, you need to look at the output of your X
+server, which tells you where the linear framebuffer address is. A
+typical line that you may get is:
+
+(--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000
+
+Note that you should only use the value from the X server, as it may
+move the framebuffer base address, so the only value you can trust is
+that reported by the X server.
+
+To find out the size of your framebuffer (what, you don't actually
+know?), the following line will tell you:
+
+(--) S3: videoram:  4096k
+
+That's 4 MBytes, which is 0x400000 bytes (in hexadecimal).
+A patch is being written for XFree86 which will make this automatic:
+in other words the X server will manipulate /proc/mtrr using the
+ioctl() interface, so users won't have to do anything. If you use a
+commercial X server, lobby your vendor to add support for MTRRs.
 ===============================================================================
 Removing MTRRs from the shell:
-% echo "disable=5" >! /proc/mtrr
+% echo "disable=2" >! /proc/mtrr
 ===============================================================================
 Reading MTRRs from a C programme using ioctl()'s:
 
@@ -44,7 +71,7 @@
 
     Source file for mtrr-show (example programme to show MTRRs using ioctl()'s)
 
-    Copyright (C) 1997  Richard Gooch
+    Copyright (C) 1997-1998  Richard Gooch
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -72,7 +99,7 @@
 
     Written by      Richard Gooch   17-DEC-1997
 
-    Last updated by Richard Gooch   17-DEC-1997
+    Last updated by Richard Gooch   2-MAY-1998
 
 
 */
@@ -84,7 +111,7 @@
 #include <sys/ioctl.h>
 #include <errno.h>
 #define MTRR_NEED_STRINGS
-#include <linux/mtrr.h>
+#include <asm/mtrr.h>
 
 #define TRUE 1
 #define FALSE 0
@@ -130,7 +157,7 @@
 
     Source file for mtrr-add (example programme to add an MTRRs using ioctl())
 
-    Copyright (C) 1997  Richard Gooch
+    Copyright (C) 1997-1998  Richard Gooch
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -158,7 +185,7 @@
 
     Written by      Richard Gooch   17-DEC-1997
 
-    Last updated by Richard Gooch   17-DEC-1997
+    Last updated by Richard Gooch   2-MAY-1998
 
 
 */
@@ -172,7 +199,7 @@
 #include <sys/ioctl.h>
 #include <errno.h>
 #define MTRR_NEED_STRINGS
-#include <linux/mtrr.h>
+#include <asm/mtrr.h>
 
 #define TRUE 1
 #define FALSE 0
diff -u --recursive --new-file v2.1.99/linux/Documentation/sysctl/vm.txt linux/Documentation/sysctl/vm.txt
--- v2.1.99/linux/Documentation/sysctl/vm.txt	Sat May  2 14:19:52 1998
+++ linux/Documentation/sysctl/vm.txt	Sat May  2 17:45:03 1998
@@ -18,6 +18,7 @@
 - bdflush
 - buffermem
 - freepages
+- kswapd
 - overcommit_memory
 - pagecache
 - swapctl
@@ -112,9 +113,58 @@
 This file contains the values in the struct freepages. That
 struct contains three members: min, low and high.
 
-These variables are currently unused (?), but they're
-very likely to be abused for something else in the near
-future, so don't yet remove it from the source...
+Although the goal of the Linux memory management subsystem
+is to avoid fragmentation and make large chunks of free
+memory (so that we can hand out DMA buffers and such), there
+still are some page-based limits in the system, mainly to
+make sure we don't waste too much memory trying to get large
+free area's.
+
+The meaning of the numbers is:
+
+freepages.min	When the number of free pages in the system
+		reaches this number, only the kernel can
+		allocate more memory.
+freepages.low	If memory is too fragmented, the swapout
+		daemon is started, except when the number
+		of free pages is larger than freepages.low.
+freepages.high	The swapping daemon exits when memory is
+		sufficiently defragmented, when the number
+		of free pages reaches freepages.high or when
+		it has tried the maximum number of times. 
+
+==============================================================
+
+kswapd:
+
+Kswapd is the kernel swapout daemon. That is, kswapd is that
+piece of the kernel that frees memory when it get's fragmented
+or full. Since every system is different, you'll probably want
+some control over this piece of the system.
+
+The numbers in this page correspond to the numbers in the
+struct pager_daemon {tries_base, tries_min, swap_cluster
+}; The tries_base and swap_cluster probably have the
+largest influence on system performance.
+
+tries_base	The maximum number of pages kswapd tries to
+		free in one round is calculated from this
+		number. Usually this number will be divided
+		by 4 or 8 (see mm/vmscan.c), so it isn't as
+		big as it looks.
+		When you need to increase the bandwith to/from
+		swap, you'll want to increase this number.
+tries_min	This is the minimum number of times kswapd
+		tries to free a page each time it is called.
+		Basically it's just there to make sure that
+		kswapd frees some pages even when it's being
+		called with minimum priority.
+swap_cluster	This is the number of pages kswapd writes in
+		one turn. You want this large so that kswapd
+		does it's I/O in large chunks and the disk
+		doesn't have to seek often, but you don't want
+		it to be too large since that would flood the
+		request queue.
 
 ==============================================================
 
diff -u --recursive --new-file v2.1.99/linux/Makefile linux/Makefile
--- v2.1.99/linux/Makefile	Sat May  2 14:19:52 1998
+++ linux/Makefile	Fri May  1 11:20:31 1998
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 99
+SUBLEVEL = 100
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
diff -u --recursive --new-file v2.1.99/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- v2.1.99/linux/arch/alpha/kernel/bios32.c	Tue Apr 14 14:29:19 1998
+++ linux/arch/alpha/kernel/bios32.c	Wed May  6 10:56:01 1998
@@ -2041,7 +2041,7 @@
 	unsigned int uint;
 	long err = 0;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	lock_kernel();
@@ -2082,7 +2082,7 @@
 	unsigned int uint;
 	long err = 0;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	lock_kernel();
diff -u --recursive --new-file v2.1.99/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c
--- v2.1.99/linux/arch/alpha/kernel/ptrace.c	Sun Nov 30 10:59:02 1997
+++ linux/arch/alpha/kernel/ptrace.c	Wed May  6 10:56:01 1998
@@ -506,7 +506,7 @@
 		     (current->uid != child->uid) ||
 		     (current->gid != child->egid) ||
 		     (current->gid != child->sgid) ||
-		     (current->gid != child->gid)) && !suser())
+		     (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
 			goto out;
 		/* the same process cannot be attached many times */
 		if (child->flags & PF_PTRACED)
diff -u --recursive --new-file v2.1.99/linux/arch/arm/kernel/ioport.c linux/arch/arm/kernel/ioport.c
--- v2.1.99/linux/arch/arm/kernel/ioport.c	Tue Jan 20 16:39:41 1998
+++ linux/arch/arm/kernel/ioport.c	Wed May  6 10:56:01 1998
@@ -58,7 +58,7 @@
 	if (from + num > IO_BITMAP_SIZE*32)
 		return -EINVAL;
 #endif
-	if (!suser())
+	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
 
 #ifdef IODEBUG
@@ -91,7 +91,7 @@
 
 	if (level > 3)
 		return -EINVAL;
-	if (!suser())
+	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
 	*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
 	return 0;
diff -u --recursive --new-file v2.1.99/linux/arch/arm/kernel/ptrace.c linux/arch/arm/kernel/ptrace.c
--- v2.1.99/linux/arch/arm/kernel/ptrace.c	Tue Apr 14 14:29:19 1998
+++ linux/arch/arm/kernel/ptrace.c	Wed May  6 10:56:01 1998
@@ -581,7 +581,7 @@
 		    (current->uid != child->uid) ||
 	 	    (current->gid != child->egid) ||
 	 	    (current->gid != child->sgid) ||
-	 	    (current->gid != child->gid)) && !suser())
+	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
 			goto out;
 		/* the same process cannot be attached many times */
 		if (child->flags & PF_PTRACED)
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.1.99/linux/arch/i386/kernel/bios32.c	Thu Apr 23 20:21:28 1998
+++ linux/arch/i386/kernel/bios32.c	Sun May  3 11:30:02 1998
@@ -1,7 +1,7 @@
 /*
  * bios32.c - Low-Level PCI Access
  *
- * $Id: bios32.c,v 1.29 1998/04/17 16:31:15 mj Exp $
+ * $Id: bios32.c,v 1.32 1998/05/02 12:03:05 davem Exp $
  *
  * Sponsored by
  *	iX Multiuser Multitasking Magazine
@@ -66,6 +66,8 @@
  *	and cleaned it up...     Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  *
  * Feb 6,  1998 : No longer using BIOS to find devices and device classes. [mj]
+ *
+ * May 1,  1998 : Support for peer host bridges. [mj]
  */
 
 #include <linux/config.h>
@@ -74,6 +76,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/malloc.h>
 
 #include <asm/page.h>
 #include <asm/segment.h>
@@ -832,7 +835,10 @@
 }
 
 /*
- * Sort the device list according to PCI BIOS.
+ * Sort the device list according to PCI BIOS. Nasty hack, but since some
+ * fool forgot to define the `correct' device order in the PCI BIOS specs
+ * and we want to be (possibly bug-to-bug ;-]) compatible with older kernels
+ * which used BIOS ordering, we are bound to do this...
  */
 
 __initfunc(void pcibios_sort(void))
@@ -924,11 +930,41 @@
 }
 
 /*
- * Arch-dependent fixups. We need to fix here base addresses, I/O
- * and memory enables and IRQ's as the PCI BIOS'es are buggy as hell.
+ * In case there are peer host bridges, scan bus behind each of them.
+ * Although several sources claim that the host bridges should have
+ * header type 1 and be assigned a bus number as for PCI2PCI bridges,
+ * the reality doesn't pass this test and the bus number is usually
+ * hard-wired to 1.
  */
+__initfunc(void pcibios_fixup_peer_bridges(void))
+{
+	struct pci_dev *dev;
+	int cnt = 0;
 
-__initfunc(void pcibios_fixup(void))
+	for(dev=pci_root.devices; dev; dev=dev->sibling)
+		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
+			DBG("PCI: Host bridge at %02x\n", dev->devfn);
+			if (cnt) {
+				struct pci_bus *b = kmalloc(sizeof(struct pci_bus), GFP_KERNEL);
+				memset(b, 0, sizeof(*b));
+				b->parent = &pci_root;
+				b->next = pci_root.next;
+				pci_root.next = b;
+				b->self = dev;
+				b->number = b->secondary = cnt;
+				b->subordinate = 0xff;
+				b->subordinate = pci_scan_bus(b);
+			}
+			cnt++;
+		}
+}
+
+/*
+ * Fix base addresses, I/O and memory enables and IRQ's (mostly work-arounds
+ * for buggy PCI BIOS'es :-[).
+ */
+
+__initfunc(void pcibios_fixup_devices(void))
 {
 	struct pci_dev *dev;
 	int i, has_io, has_mem;
@@ -991,6 +1027,16 @@
 		if (dev->irq >= NR_IRQS)
 			dev->irq = 0;
 	}
+}
+
+/*
+ * Arch-dependent fixups.
+ */
+
+__initfunc(void pcibios_fixup(void))
+{
+	pcibios_fixup_peer_bridges();
+	pcibios_fixup_devices();
 
 #ifdef CONFIG_PCI_BIOS
 	if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.1.99/linux/arch/i386/kernel/entry.S	Sat May  2 14:19:52 1998
+++ linux/arch/i386/kernel/entry.S	Wed May  6 11:01:45 1998
@@ -544,7 +544,9 @@
 	.long SYMBOL_NAME(sys_pwrite)
 	.long SYMBOL_NAME(sys_chown)
 	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
 	
-	.rept NR_syscalls-182
+	.rept NR_syscalls-184
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.1.99/linux/arch/i386/kernel/io_apic.c	Mon Apr  6 17:40:59 1998
+++ linux/arch/i386/kernel/io_apic.c	Tue May  5 16:10:32 1998
@@ -1,7 +1,7 @@
 /*
  *	Intel IO-APIC support for multi-pentium hosts.
  *
- *	(c) 1997 Ingo Molnar, Hajnalka Szabo
+ *	Copyright (C) 1997, 1998 Ingo Molnar, Hajnalka Szabo
  *
  *	Many thanks to Stig Venaas for trying out countless experimental
  *	patches and reporting/debugging problems patiently!
@@ -34,6 +34,19 @@
  */
 #define IO_APIC_BASE ((volatile int *)0xfec00000)
 
+enum mp_irq_source_types {
+    mp_INT = 0,
+    mp_NMI = 1,
+    mp_SMI = 2,
+    mp_ExtINT = 3
+};
+
+enum ioapic_irq_destination_types {
+    dest_Fixed = 0,
+    dest_LowestPrio = 1,
+    dest_ExtINT = 7
+};
+
 /*
  * The structure of the IO-APIC:
  */
@@ -60,7 +73,7 @@
 	__u32	vector		:  8,
 		delivery_mode	:  3,	/* 000: FIXED
 					 * 001: lowest prio
-					 * 111: ExtInt
+					 * 111: ExtINT
 					 */
 		dest_mode	:  1,	/* 0: physical, 1: logical */
 		delivery_status	:  1,
@@ -137,7 +150,7 @@
 	io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
 }
 
-void clear_IO_APIC_irq (unsigned int irq)
+void clear_IO_APIC_pin (unsigned int pin)
 {
 	struct IO_APIC_route_entry entry;
 
@@ -146,12 +159,12 @@
 	 */
 	memset(&entry, 0, sizeof(entry));
 	entry.mask = 1;
-	io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
-	io_apic_write(0x11+2*irq, *(((int *)&entry)+1));
+	io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
+	io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
 }
 
 /*
- * support for broken MP BIOSes, enables hand-redirection of PIRQ0-3 to
+ * support for broken MP BIOSes, enables hand-redirection of PIRQ0-7 to
  * specific CPU-side IRQs.
  */
 
@@ -159,7 +172,7 @@
 int pirq_entries [MAX_PIRQS];
 int pirqs_enabled;
 
-void ioapic_pirq_setup(char *str, int *ints)
+__initfunc(void ioapic_pirq_setup(char *str, int *ints))
 {
 	int i, max;
 
@@ -187,12 +200,15 @@
 	}
 }
 
-int find_irq_entry(int pin)
+/*
+ * Find the irq entry nr of a certain pin.
+ */
+__initfunc(static int find_irq_entry(int pin, int type))
 {
 	int i;
 
 	for (i=0; i<mp_irq_entries; i++)
-		if ( (mp_irqs[i].mpc_irqtype == 0x00) &&
+		if ( (mp_irqs[i].mpc_irqtype == type) &&
 			(mp_irqs[i].mpc_dstirq == pin))
 
 			return i;
@@ -200,7 +216,227 @@
 	return -1;
 }
 
-void setup_IO_APIC_irqs (void)
+/*
+ * Find the pin to which IRQ0 (ISA) is connected
+ */
+__initfunc(int find_timer_pin (int type))
+{
+	int i;
+
+	for (i=0; i<mp_irq_entries; i++) {
+		int lbus = mp_irqs[i].mpc_srcbus;
+
+		if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA) &&
+		    (mp_irqs[i].mpc_irqtype == type) &&
+		    (mp_irqs[i].mpc_srcbusirq == 0x00))
+
+			return mp_irqs[i].mpc_dstirq;
+	}
+	return -1;
+}
+
+/*
+ * Find a specific PCI IRQ entry.
+ * Not an initfunc, possibly needed by modules
+ */
+int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
+{
+	int i;
+
+	for (i=0; i<mp_irq_entries; i++) {
+		int lbus = mp_irqs[i].mpc_srcbus;
+
+		if (IO_APIC_IRQ(mp_irqs[i].mpc_dstirq) &&
+		    (mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
+		    !mp_irqs[i].mpc_irqtype &&
+		    (bus == mp_bus_id_to_pci_bus[mp_irqs[i].mpc_srcbus]) &&
+		    (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f)) &&
+		    (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3)))
+
+			return mp_irqs[i].mpc_dstirq;
+	}
+	return -1;
+}
+
+static int irq_trigger(int idx)
+{
+	int bus = mp_irqs[idx].mpc_srcbus;
+	int trigger;
+
+	/*
+	 * Determine IRQ trigger mode (edge or level sensitive):
+	 */
+	switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
+	{
+		case 0: /* conforms, ie. bus-type dependent */
+		{
+			switch (mp_bus_id_to_type[bus])
+			{
+				case MP_BUS_ISA: /* ISA pin, edge */
+				{
+					trigger = 0;
+					break;
+				}
+				case MP_BUS_PCI: /* PCI pin, level */
+				{
+					trigger = 1;
+					break;
+				}
+				default:
+				{
+					printk("broken BIOS!!\n");
+					trigger = 1;
+					break;
+				}
+			}
+			break;
+		}
+		case 1: /* edge */
+		{
+			trigger = 0;
+			break;
+		}
+		case 2: /* reserved */
+		{
+			printk("broken BIOS!!\n");
+			trigger = 1;
+			break;
+		}
+		case 3: /* level */
+		{
+			trigger = 1;
+			break;
+		}
+		default: /* invalid */
+		{
+			printk("broken BIOS!!\n");
+			trigger = 0;
+			break;
+		}
+	}
+	return trigger;
+}
+
+__initfunc(static int irq_polarity(int idx))
+{
+	int bus = mp_irqs[idx].mpc_srcbus;
+	int polarity;
+
+	/*
+	 * Determine IRQ line polarity (high active or low active):
+	 */
+	switch (mp_irqs[idx].mpc_irqflag & 3)
+	{
+		case 0: /* conforms, ie. bus-type dependent polarity */
+		{
+			switch (mp_bus_id_to_type[bus])
+			{
+				case MP_BUS_ISA: /* ISA pin */
+				{
+					polarity = 0;
+					break;
+				}
+				case MP_BUS_PCI: /* PCI pin */
+				{
+					polarity = 1;
+					break;
+				}
+				default:
+				{
+					printk("broken BIOS!!\n");
+					polarity = 1;
+					break;
+				}
+			}
+			break;
+		}
+		case 1: /* high active */
+		{
+			polarity = 0;
+			break;
+		}
+		case 2: /* reserved */
+		{
+			printk("broken BIOS!!\n");
+			polarity = 1;
+			break;
+		}
+		case 3: /* low active */
+		{
+			polarity = 1;
+			break;
+		}
+		default: /* invalid */
+		{
+			printk("broken BIOS!!\n");
+			polarity = 1;
+			break;
+		}
+	}
+	return polarity;
+}
+
+__initfunc(static int pin_2_irq (int idx, int pin))
+{
+	int irq;
+	int bus = mp_irqs[idx].mpc_srcbus;
+
+	switch (mp_bus_id_to_type[bus])
+	{
+		case MP_BUS_ISA: /* ISA pin */
+		{
+			irq = mp_irqs[idx].mpc_srcbusirq;
+			break;
+		}
+		case MP_BUS_PCI: /* PCI pin */
+		{
+			/*
+			 * PCI IRQs are 'directly mapped'
+			 */
+			irq = pin;
+			break;
+		}
+		default:
+		{
+			printk("unknown bus type %d.\n",bus); 
+			irq = 0;
+			break;
+		}
+	}
+
+	/*
+	 * PCI IRQ command line redirection. Yes, limits are hardcoded.
+	 */
+	if ((pin>=16) && (pin<=23)) {
+		if (pirq_entries[pin-16] != -1) {
+			if (!pirq_entries[pin-16]) {
+				printk("disabling PIRQ%d\n", pin-16);
+			} else {
+				irq = pirq_entries[pin-16];
+				printk("using PIRQ%d -> IRQ %d\n",
+						pin-16, irq);
+			}
+		}
+	}
+	return irq;
+}
+
+int IO_APIC_irq_trigger (int irq)
+{
+	int idx, i;
+
+	for (i=0; i<nr_ioapic_registers; i++) {
+		idx = find_irq_entry(i,mp_INT);
+		if (irq == pin_2_irq(idx,i))
+			return irq_trigger(idx);
+	}
+	/*
+	 * nonexistant IRQs are edge default
+	 */
+	return 0;
+}
+
+__initfunc(void setup_IO_APIC_irqs (void))
 {
 	struct IO_APIC_route_entry entry;
 	int i, idx, bus, irq, first_notcon=1;
@@ -214,12 +450,12 @@
 		 */
 		memset(&entry,0,sizeof(entry));
 
-		entry.delivery_mode = 1;		/* lowest prio */
+		entry.delivery_mode = dest_LowestPrio;
 		entry.dest_mode = 1;			/* logical delivery */
 		entry.mask = 0;				/* enable IRQ */
 		entry.dest.logical.logical_dest = 0xff;	/* all CPUs */
 
-		idx = find_irq_entry(i);
+		idx = find_irq_entry(i,mp_INT);
 		if (idx == -1) {
 			if (first_notcon) {
 				printk(" IO-APIC pin %d", i);
@@ -228,137 +464,32 @@
 				printk(", %d", i);
 			continue;
 		}
-		bus = mp_irqs[idx].mpc_srcbus;
 
-		switch (mp_bus_id_to_type[bus])
-		{
-			case MP_BUS_ISA: /* ISA pin */
-			{
-				irq = mp_irqs[idx].mpc_srcbusirq;
-				break;
-			}
-			case MP_BUS_PCI: /* PCI pin */
-			{
-				/*
-				 * PCI IRQs are 'directly mapped'
-				 */
-				irq = i;
-				break;
-			}
-			default:
-			{
-				printk("unknown bus type %d.\n",bus); 
-				irq = 0;
-				break;
-			}
-		}
+		entry.trigger = irq_trigger(idx);
+		entry.polarity = irq_polarity(idx);
 
-		/*
-		 * PCI IRQ redirection. Yes, limits are hardcoded.
-		 */
-		if ((i>=16) && (i<=23)) {
-			if (pirq_entries[i-16] != -1) {
-				if (!pirq_entries[i-16]) {
-					printk("disabling PIRQ%d\n", i-16);
-				} else {
-					irq = pirq_entries[i-16];
-					printk("using PIRQ%d -> IRQ %d\n",
-							i-16, irq);
-				}
-			}
-		}
+		irq = pin_2_irq(idx,i);
 
 		if (!IO_APIC_IRQ(irq))
 			continue;
 
 		entry.vector = IO_APIC_VECTOR(irq);
 
-		/*
-		 * Determine IRQ line polarity (high active or low active):
-		 */
-		switch (mp_irqs[idx].mpc_irqflag & 3)
-		{
-			case 0: /* conforms, ie. bus-type dependent polarity */
-			{
-				switch (mp_bus_id_to_type[bus])
-				{
-					case MP_BUS_ISA: /* ISA pin */
-					{
-						entry.polarity = 0;
-						break;
-					}
-					case MP_BUS_PCI: /* PCI pin */
-					{
-						entry.polarity = 1;
-						break;
-					}
-					default:
-					{
-						printk("broken BIOS!!\n");
-						break;
-					}
-				}
-				break;
-			}
-			case 1: /* high active */
-			{
-				entry.polarity = 0;
-				break;
-			}
-			case 2: /* reserved */
-			{
-				printk("broken BIOS!!\n");
-				break;
-			}
-			case 3: /* low active */
-			{
-				entry.polarity = 1;
-				break;
-			}
-		}
+	/*
+	 * There are broken mptables which register ISA+high-active+level IRQs,
+	 * these are illegal and are converted here to ISA+high-active+edge
+	 * IRQ sources. Careful, ISA+low-active+level is another broken entry
+	 * type, it represents PCI IRQs 'embedded into an ISA bus', they have
+	 * to be accepted. Yes, ugh.
+	 */
+		bus = mp_irqs[idx].mpc_srcbus;
 
-		/*
-		 * Determine IRQ trigger mode (edge or level sensitive):
-		 */
-		switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
+		if ( (mp_bus_id_to_type[bus] == MP_BUS_ISA) &&
+			(entry.polarity == 0) /* active-high */ &&
+			(entry.trigger == 1) /* level */ )
 		{
-			case 0: /* conforms, ie. bus-type dependent */
-			{
-				switch (mp_bus_id_to_type[bus])
-				{
-					case MP_BUS_ISA: /* ISA pin, edge */
-					{
-						entry.trigger = 0;
-						break;
-					}
-					case MP_BUS_PCI: /* PCI pin, level */
-					{
-						entry.trigger = 1;
-						break;
-					}
-					default:
-					{
-						printk("broken BIOS!!\n");
-						break;
-					}
-				}
-				break;
-			}
-			case 1: /* edge */
-			{
-				entry.trigger = 0;
-				break;
-			}
-			case 2: /* reserved */
-			{
-				printk("broken BIOS!!\n");
-				break;
-			}
-			case 3: /* level */
-			{
-				entry.trigger = 1;
-				break;
-			}
+			printk("broken BIOS, changing pin %d to edge\n", i);
+			entry.trigger = 0;
 		}
 
 		io_apic_write(0x10+2*i, *(((int *)&entry)+0));
@@ -369,7 +500,7 @@
 		printk(" not connected.\n");
 }
 
-void setup_IO_APIC_irq_ISA_default (unsigned int irq)
+__initfunc(void setup_IO_APIC_irq_ISA_default (unsigned int irq))
 {
 	struct IO_APIC_route_entry entry;
 
@@ -378,9 +509,9 @@
 	 */
 	memset(&entry,0,sizeof(entry));
 
-	entry.delivery_mode = 1;			/* lowest prio */
+	entry.delivery_mode = dest_LowestPrio;		/* lowest prio */
 	entry.dest_mode = 1;				/* logical delivery */
-	entry.mask = 1;					/* unmask IRQ now */
+	entry.mask = 0;					/* unmask IRQ now */
 	entry.dest.logical.logical_dest = 0xff;		/* all CPUs */
 
 	entry.vector = IO_APIC_VECTOR(irq);
@@ -392,56 +523,42 @@
 	io_apic_write(0x11+2*irq, *(((int *)&entry)+1));
 }
 
-int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
-{
-	int i;
-
-	for (i=0; i<mp_irq_entries; i++) {
-		int lbus = mp_irqs[i].mpc_srcbus;
-
-		if (IO_APIC_IRQ(mp_irqs[i].mpc_dstirq) &&
-		    (mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
-		    !mp_irqs[i].mpc_irqtype &&
-		    (bus == mp_bus_id_to_pci_bus[mp_irqs[i].mpc_srcbus]) &&
-		    (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f)) &&
-		    (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3)))
-
-			return mp_irqs[i].mpc_dstirq;
-	}
-	return -1;
-}
-
 /*
- * There is a nasty bug in some older SMP boards, their mptable lies
- * about the timer IRQ. We do the following to work around the situation:
- *
- *	- timer IRQ defaults to IO-APIC IRQ
- *	- if this function detects that timer IRQs are defunct, then we fall
- *	  back to ISA timer IRQs
+ * Set up a certain pin as ExtINT delivered interrupt
  */
-static int timer_irq_works (void)
+__initfunc(void setup_ExtINT_pin (unsigned int pin))
 {
-	unsigned int t1=jiffies;
-	unsigned long flags;
+	struct IO_APIC_route_entry entry;
 
-	save_flags(flags);
-	sti();
+	/*
+	 * add it to the IO-APIC irq-routing table:
+	 */
+	memset(&entry,0,sizeof(entry));
 
-	udelay(100*1000);
+	entry.delivery_mode = dest_ExtINT;
+	entry.dest_mode = 1;				/* logical delivery */
+	entry.mask = 0;					/* unmask IRQ now */
+	entry.dest.logical.logical_dest = 0xff;		/* all CPUs */
 
-	if (jiffies-t1>1)
-		return 1;
+	entry.vector = IO_APIC_VECTOR(pin);		/* it's ignored */
 
-	return 0;
+	entry.polarity=0;
+	entry.trigger=0;
+
+	io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
+	io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
 }
 
-void print_IO_APIC (void)
+__initfunc(void print_IO_APIC (void))
 {
 	int i;
 	struct IO_APIC_reg_00 reg_00;
 	struct IO_APIC_reg_01 reg_01;
 	struct IO_APIC_reg_02 reg_02;
 
+ 	printk("nr of MP irq sources: %d.\n", mp_irq_entries);
+ 	printk("nr of IO-APIC registers: %d.\n", nr_ioapic_registers);
+
 	*(int *)&reg_00 = io_apic_read(0);
 	*(int *)&reg_01 = io_apic_read(1);
 	*(int *)&reg_02 = io_apic_read(2);
@@ -513,14 +630,41 @@
 	return;
 }
 
-static void init_sym_mode (void)
+__initfunc(static void init_sym_mode (void))
 {
+	int i;
+
+	if (!pirqs_enabled)
+		for (i=0; i<MAX_PIRQS; i++)
+			pirq_entries[i]=-1;
+
 	printk("enabling Symmetric IO mode ... ");
-		outb_p (0x70, 0x22);
-		outb_p (0x01, 0x23);
+
+	outb(0x70, 0x22);
+	outb(0x01, 0x23);
+
 	printk("...done.\n");
+
+	/*
+	 * The number of IO-APIC irq-registers (== #pins):
+	 */
+	{
+		struct IO_APIC_reg_01 reg_01;
+
+		*(int *)&reg_01 = io_apic_read(1);
+		nr_ioapic_registers = reg_01.entries+1;
+	}
+
+	/*
+	 * Do not trust the IO-APIC being empty at bootup
+	 */
+	for (i=0; i<nr_ioapic_registers; i++)
+		clear_IO_APIC_pin (i);
 }
 
+/*
+ * Not an initfunc, needed by the reboot code
+ */
 void init_pic_mode (void)
 {
 	printk("disabling Symmetric IO mode ... ");
@@ -551,8 +695,7 @@
 	{ 0		,	0		}
 };
 
-
-static int in_ioapic_list (struct ioapic_list_entry * table)
+__initfunc(static int in_ioapic_list (struct ioapic_list_entry * table))
 {
 	for (;table->oem_id; table++)
 		if ((!strcmp(table->oem_id,ioapic_OEM_ID)) &&
@@ -561,7 +704,7 @@
 	return 0;
 }
 
-static int ioapic_whitelisted (void)
+__initfunc(static int ioapic_whitelisted (void))
 {
 /*
  * Right now, whitelist everything to see whether the new parsing
@@ -574,12 +717,12 @@
 #endif
 }
 
-static int ioapic_blacklisted (void)
+__initfunc(static int ioapic_blacklisted (void))
 {
 	return in_ioapic_list(ioapic_blacklist);
 }
 
-static void setup_ioapic_id (void)
+__initfunc(static void setup_ioapic_id (void))
 {
 	struct IO_APIC_reg_00 reg_00;
 
@@ -598,7 +741,7 @@
 		panic("APIC ID 2 already used");
 
 	/*
-	 * set the ID
+	 * Set the ID
 	 */
 	*(int *)&reg_00 = io_apic_read(0);
 	printk("... changing IO-APIC physical APIC ID to 2 ...\n");
@@ -613,7 +756,7 @@
 		panic("could not set ID");
 }
 
-static void construct_default_ISA_mptable (void)
+__initfunc(static void construct_default_ISA_mptable (void))
 {
 	int i, pos=0;
 
@@ -650,31 +793,84 @@
 
 	setup_ioapic_id();
 }
-			
-void setup_IO_APIC (void)
+
+/*
+ * There is a nasty bug in some older SMP boards, their mptable lies
+ * about the timer IRQ. We do the following to work around the situation:
+ *
+ *	- timer IRQ defaults to IO-APIC IRQ
+ *	- if this function detects that timer IRQs are defunct, then we fall
+ *	  back to ISA timer IRQs
+ */
+__initfunc(static int timer_irq_works (void))
 {
-	int i;
+	unsigned int t1=jiffies;
+	unsigned long flags;
 
-	if (!pirqs_enabled)
-		for (i=0; i<MAX_PIRQS; i++)
-			pirq_entries[i]=-1;
+	save_flags(flags);
+	sti();
 
-	init_sym_mode();
-	{
-		struct IO_APIC_reg_01 reg_01;
+	udelay(10*10000);
 
-		*(int *)&reg_01 = io_apic_read(1);
-		nr_ioapic_registers = reg_01.entries+1;
+	if (jiffies-t1>1)
+		return 1;
+
+	return 0;
+}
+
+/*
+ * This code may look a bit paranoid, but it's supposed to cooperate with
+ * a wide range of boards and BIOS bugs ... fortunately only the timer IRQ
+ * is so screwy. Thanks to Brian Perkins for testing/hacking this beast
+ * fanatically on his truly bugged board.
+ */
+__initfunc(static void check_timer (void))
+{
+	int pin1, pin2;
+
+	pin1 = find_timer_pin (mp_INT);
+	pin2 = find_timer_pin (mp_ExtINT);
+
+	if (!timer_irq_works ()) {
+		if (pin1 != -1)
+			printk("..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
+		printk("..trying to set up timer as ExtINT ... ");
+
+		if (pin2 != -1) {
+			printk(".. (found pin %d) ...", pin2);
+			setup_ExtINT_pin (pin2);
+			make_8259A_irq(0);
+		}
+
+		if (!timer_irq_works ()) {
+			printk(" failed.\n");
+			printk("..trying to set up timer as BP irq ...");
+			/*
+			 * Just in case ...
+			 */
+			if (pin1 != -1)
+				clear_IO_APIC_pin (pin1);
+			if (pin2 != -1)
+				clear_IO_APIC_pin (pin2);
+
+			make_8259A_irq(0);
+
+			if (!timer_irq_works ()) {
+				printk(" failed.\n");
+				panic("IO-APIC + timer doesnt work!");
+			}
+		}
+		printk(" works.\n");
 	}
+}
 
-	/*
-	 * do not trust the IO-APIC being empty at bootup
-	 */
-	for (i=0; i<nr_ioapic_registers; i++)
-		clear_IO_APIC_irq (i);
+__initfunc(void setup_IO_APIC (void))
+{
+	init_sym_mode();
 
 	/*
-	 * the following IO-APIC's can be enabled:
+	 * Determine the range of IRQs handled by the IO-APIC. The
+	 * following boards can be fully enabled:
 	 *
 	 * - whitelisted ones
 	 * - those which have no PCI pins connected
@@ -699,7 +895,7 @@
 	/*
 	 * If there are no explicit mp irq entries: it's either one of the
 	 * default configuration types or we are broken. In both cases it's
-	 * fine to set up most of the low 16 IOAPIC pins to ISA defaults.
+	 * fine to set up most of the low 16 IO-APIC pins to ISA defaults.
 	 */
 	if (!mp_irq_entries) {
 		printk("no explicit IRQ entries, using default mptable\n");
@@ -708,18 +904,13 @@
 
 	init_IO_APIC_traps();
 
+	/*
+	 * Set up the IO-APIC irq routing table by parsing the MP-BIOS
+	 * mptable:
+	 */
 	setup_IO_APIC_irqs ();
-
-	if (!timer_irq_works ()) {
-		make_8259A_irq(0);
-		if (!timer_irq_works ())
-			panic("IO-APIC + timer doesnt work!");
-		printk("..MP-BIOS bug: i8254 timer not connected to IO-APIC\n");
-		printk("..falling back to 8259A-based timer interrupt\n");
-	}
+	check_timer();
  
- 	printk("nr of MP irq sources: %d.\n", mp_irq_entries);
- 	printk("nr of IOAPIC registers: %d.\n", nr_ioapic_registers);
 	print_IO_APIC();
 }
 
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/ioport.c linux/arch/i386/kernel/ioport.c
--- v2.1.99/linux/arch/i386/kernel/ioport.c	Wed Apr  1 20:11:47 1998
+++ linux/arch/i386/kernel/ioport.c	Wed May  6 10:56:01 1998
@@ -58,7 +58,7 @@
 
 	if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
 		return -EINVAL;
-	if (!suser())
+	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
 	/*
 	 * If it's the first ioperm() call in this thread's lifetime, set the
@@ -94,7 +94,7 @@
 
 	if (level > 3)
 		return -EINVAL;
-	if (!suser())
+	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
 	regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
 	return 0;
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.99/linux/arch/i386/kernel/irq.c	Sat May  2 14:19:52 1998
+++ linux/arch/i386/kernel/irq.c	Thu May  7 19:03:16 1998
@@ -70,9 +70,8 @@
 
 /*
  * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
- * boards the timer interrupt and sometimes the keyboard interrupt is
- * not connected to any IO-APIC pin, it's fed to the CPU ExtInt IRQ line
- * directly.
+ * boards the timer interrupt is not connected to any IO-APIC pin, it's
+ * 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,
@@ -82,11 +81,8 @@
 /*
  * Default to all normal IRQ's _not_ using the IO APIC.
  *
- * To get IO-APIC interrupts you should either:
- *  - turn some of them into IO-APIC interrupts at runtime
- *    with some magic system call interface.
- *  - explicitly use irq 16-19 depending on which PCI irq
- *    line your PCI controller uses.
+ * To get IO-APIC interrupts we turn some of them into IO-APIC
+ * interrupts during boot.
  */
 unsigned int io_apic_irqs = 0;
 
@@ -109,15 +105,34 @@
 
 
 #ifdef __SMP__
-static void do_ioapic_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
-static void enable_ioapic_irq (unsigned int irq);
-static void disable_ioapic_irq (unsigned int irq);
-
-static struct hw_interrupt_type ioapic_irq_type = {
-	do_ioapic_IRQ,
-	enable_ioapic_irq,
-	disable_ioapic_irq
+
+/*
+ * Level and edge triggered IO-APIC interrupts need different handling,
+ * so we use two separate irq descriptors:
+ */
+
+static void do_edge_ioapic_IRQ (unsigned int irq, int cpu,
+						 struct pt_regs * regs);
+static void enable_edge_ioapic_irq (unsigned int irq);
+static void disable_edge_ioapic_irq (unsigned int irq);
+
+static struct hw_interrupt_type ioapic_edge_irq_type = {
+	do_edge_ioapic_IRQ,
+	enable_edge_ioapic_irq,
+	disable_edge_ioapic_irq
+};
+
+static void do_level_ioapic_IRQ (unsigned int irq, int cpu,
+						 struct pt_regs * regs);
+static void enable_level_ioapic_irq (unsigned int irq);
+static void disable_level_ioapic_irq (unsigned int irq);
+
+static struct hw_interrupt_type ioapic_level_irq_type = {
+	do_level_ioapic_IRQ,
+	enable_level_ioapic_irq,
+	disable_level_ioapic_irq
 };
+
 #endif
 
 /*
@@ -147,7 +162,7 @@
 irq_desc_t irq_desc[NR_IRQS] = {
 	[0 ... 15] = { 0, 0, 0, &i8259A_irq_type, },	/* standard ISA IRQs */
 #ifdef __SMP__
-	[16 ... 23] = { 0, 0, 0, &ioapic_irq_type, },	/* 'high' PCI IRQs */
+	[16 ... 23] = { 0, 0, 0, &ioapic_edge_irq_type, }, /* 'high' PCI IRQs */
 #endif
 };
 
@@ -341,11 +356,16 @@
 			p += sprintf(p, "%10u ",
 				kstat.irqs[cpu_logical_map(j)][i]);
 #endif
-
-		if (IO_APIC_IRQ(i))
-			p += sprintf(p, " IO-APIC ");
-		else
-			p += sprintf(p, "  XT-PIC ");
+		if (IO_APIC_IRQ(i)) {
+			p += sprintf(p, " IO-APIC");
+#ifdef __SMP__
+			if (irq_desc[i].handler == &ioapic_level_irq_type)
+				p += sprintf(p, "-level ");
+			else
+				p += sprintf(p, "-edge  ");
+#endif
+		} else
+			p += sprintf(p, "  XT-PIC       ");
 		p += sprintf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next) {
@@ -732,38 +752,53 @@
  * better to do it this way as thus we dont have to be aware of
  * 'pending' interrupts in the IRQ path, except at this point.
  */
-static void enable_ioapic_irq(unsigned int irq)
+static inline void self_IPI (unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
+
 	if (desc->events && !desc->ipi) {
 		desc->ipi = 1;
 		send_IPI(APIC_DEST_SELF, IO_APIC_VECTOR(irq));
 	}
 }
 
-/*
- * We do not actually disable IO-APIC irqs in hardware ...
- */
-static void disable_ioapic_irq(unsigned int irq)
+static void enable_edge_ioapic_irq(unsigned int irq)
 {
+	self_IPI(irq);
 }
 
-static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
+static void disable_edge_ioapic_irq(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc + irq;
+}
 
-	spin_lock(&irq_controller_lock);
+/*
+ * if we enable this, why does it cause a hang in the BusLogic
+ * driver, when level triggered PCI IRQs are used?
+ */
+#define NOT_BROKEN 0
 
-	/* Ack the irq inside the lock! */
-	ack_APIC_irq();
-	desc->ipi = 0;
+static void enable_level_ioapic_irq(unsigned int irq)
+{
+#if NOT_BROKEN
+	enable_IO_APIC_irq(irq);
+#endif
+	self_IPI(irq);
+}
 
-	/* If the irq is disabled for whatever reason, just set a flag and return */
-	if (desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
-		desc->events = 1;
-		spin_unlock(&irq_controller_lock);
-		return;
-	}
+static void disable_level_ioapic_irq(unsigned int irq)
+{
+#if NOT_BROKEN
+	disable_IO_APIC_irq(irq);
+#endif
+}
+
+/*
+ * Has to be called with the irq controller locked
+ */
+static void handle_ioapic_event (unsigned int irq, int cpu,
+						struct pt_regs * regs)
+{
+	irq_desc_t *desc = irq_desc + irq;
 
 	desc->status = IRQ_INPROGRESS;
 	desc->events = 0;
@@ -790,6 +825,65 @@
 	spin_unlock(&irq_controller_lock);
 
 no_handler:
+}
+
+static void do_edge_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
+{
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Edge triggered IRQs can be acked immediately
+	 */
+	ack_APIC_irq();
+
+	spin_lock(&irq_controller_lock);
+	desc->ipi = 0;
+
+	/*
+	 * If the irq is disabled for whatever reason, just
+	 * set a flag and return
+	 */
+	if (desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
+		desc->events = 1;
+		spin_unlock(&irq_controller_lock);
+		return;
+	}
+
+	handle_ioapic_event(irq,cpu,regs);
+
+	hardirq_exit(cpu);
+	release_irqlock(cpu);
+}
+
+static void do_level_ioapic_IRQ (unsigned int irq, int cpu,
+						 struct pt_regs * regs)
+{
+	irq_desc_t *desc = irq_desc + irq;
+
+	spin_lock(&irq_controller_lock);
+	/*
+	 * in the level triggered case we first disable the IRQ
+	 * in the IO-APIC, then we 'early ACK' the IRQ, then we
+	 * handle it and enable the IRQ when finished.
+	 */
+#if NOT_BROKEN
+	disable_IO_APIC_irq(irq);
+#endif
+	ack_APIC_irq();
+	desc->ipi = 0;
+
+	/*
+	 * If the irq is disabled for whatever reason, just
+	 * set a flag and return
+	 */
+	if (desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
+		desc->events = 1;
+		spin_unlock(&irq_controller_lock);
+		return;
+	}
+
+	handle_ioapic_event(irq,cpu,regs);
+
 	hardirq_exit(cpu);
 	release_irqlock(cpu);
 }
@@ -912,7 +1006,12 @@
 		spin_lock(&irq_controller_lock);
 #ifdef __SMP__
 		if (IO_APIC_IRQ(irq)) {
-			irq_desc[irq].handler = &ioapic_irq_type;
+			if (IO_APIC_VECTOR(irq) > 0xfe)
+				/*
+				 * break visibly for now, FIXME
+				 */
+				panic("ayiee, tell mingo");
+
 			/*
 			 * First disable it in the 8259A:
 			 */
@@ -1066,18 +1165,21 @@
 	 * also, we've got to be careful not to trash gate
 	 * 0x80, because int 0x80 is hm, kindof importantish ;)
 	 */
-	for (i = 0; i < NR_IRQS ; i++)
-		if (IO_APIC_VECTOR(i) <= 0xfe)  /* HACK */ {
-			if (IO_APIC_IRQ(i)) {
-				irq_desc[i].handler = &ioapic_irq_type;
-				/*
-				 * First disable it in the 8259A:
-				 */
-				cached_irq_mask |= 1 << i;
-				if (i < 16)
-					set_8259A_irq_mask(i);
-			}
+	for (i = 0; i < NR_IRQS ; i++) {
+		if ((IO_APIC_VECTOR(i) <= 0xfe)  /* HACK */ &&
+		    (IO_APIC_IRQ(i))) {
+			if (IO_APIC_irq_trigger(i))
+				irq_desc[i].handler = &ioapic_level_irq_type;
+			else
+				irq_desc[i].handler = &ioapic_edge_irq_type;
+			/*
+			 * disable it in the 8259A:
+			 */
+			cached_irq_mask |= 1 << i;
+			if (i < 16)
+				set_8259A_irq_mask(i);
 		}
+	}
 }
 #endif
 
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.1.99/linux/arch/i386/kernel/irq.h	Sat May  2 14:19:52 1998
+++ linux/arch/i386/kernel/irq.h	Tue May  5 16:10:32 1998
@@ -17,6 +17,7 @@
 void setup_IO_APIC (void);
 void init_IO_APIC_traps(void);
 int IO_APIC_get_PCI_irq_vector (int bus, int slot, int fn);
+int IO_APIC_irq_trigger (int irq);
 void make_8259A_irq (unsigned int irq);
 void send_IPI (int dest, int vector);
 void init_pic_mode (void);
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.1.99/linux/arch/i386/kernel/mtrr.c	Sat May  2 14:19:52 1998
+++ linux/arch/i386/kernel/mtrr.c	Sun May  3 11:58:36 1998
@@ -104,6 +104,12 @@
 	       Moved register-setting macros into this file.
 	       Moved setup code from init/main.c to i386-specific areas.
   v1.18
+    19980502   Richard Gooch <rgooch@atnf.csiro.au>
+	       Moved MTRR detection outside conditionals in <mtrr_init>.
+  v1.19
+    19980502   Richard Gooch <rgooch@atnf.csiro.au>
+	       Documentation improvement: mention Pentium II and AGP.
+  v1.20
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -137,7 +143,7 @@
 #include <asm/atomic.h>
 #include <linux/smp.h>
 
-#define MTRR_VERSION            "1.18 (19980429)"
+#define MTRR_VERSION            "1.20 (19980502)"
 
 #define TRUE  1
 #define FALSE 0
@@ -801,7 +807,7 @@
 	if (ltype != type)
 	{
 	    spin_unlock (&main_lock);
-	    printk ( "mtrr: type missmatch for %lx,%lx old: %s new: %s\n",
+	    printk ( "mtrr: type mismatch for %lx,%lx old: %s new: %s\n",
 		     base, size, attrib_to_str (ltype), attrib_to_str (type) );
 	    return -EINVAL;
 	}
@@ -1193,8 +1199,8 @@
 __initfunc(int mtrr_init(void))
 #endif
 {
-#  if !defined(__SMP__) || defined(MODULE) 
     if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return 0;
+#  if !defined(__SMP__) || defined(MODULE) 
     printk("mtrr: v%s Richard Gooch (rgooch@atnf.csiro.au)\n", MTRR_VERSION);
 #endif
 
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.1.99/linux/arch/i386/kernel/process.c	Thu Apr 23 20:21:28 1998
+++ linux/arch/i386/kernel/process.c	Sun May  3 18:09:24 1998
@@ -297,9 +297,9 @@
 			int i;
 			for (i=0; i<100; i++) {
 				kb_wait();
-				udelay(10);
+				udelay(50);
 				outb(0xfe,0x64);         /* pulse reset low */
-				udelay(10);
+				udelay(50);
 			}
 			/* That didn't work - force a triple fault.. */
 			__asm__ __volatile__("lidt %0": :"m" (no_idt));
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- v2.1.99/linux/arch/i386/kernel/ptrace.c	Tue Mar 17 22:18:14 1998
+++ linux/arch/i386/kernel/ptrace.c	Wed May  6 10:56:01 1998
@@ -386,7 +386,7 @@
 		    (current->uid != child->uid) ||
 	 	    (current->gid != child->egid) ||
 	 	    (current->gid != child->sgid) ||
-	 	    (current->gid != child->gid)) && !suser())
+	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
 			goto out;
 		/* the same process cannot be attached many times */
 		if (child->flags & PF_PTRACED)
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.1.99/linux/arch/i386/kernel/smp.c	Sat May  2 14:19:52 1998
+++ linux/arch/i386/kernel/smp.c	Thu May  7 14:38:40 1998
@@ -439,6 +439,8 @@
 				{
 					unsigned long cfg;
 
+					/* local APIC has default address */
+					mp_lapic_addr = 0xFEE00000;
 					/*
 					 *	We need to know what the local
 					 *	APIC id of the boot CPU is!
@@ -627,20 +629,29 @@
 	smp_commenced=1;
 }
 
+__initfunc(void enable_local_APIC(void))
+{
+	unsigned long value;
+
+ 	value = apic_read(APIC_SPIV);
+ 	value |= (1<<8);		/* Enable APIC (bit==1) */
+ 	value &= ~(1<<9);		/* Enable focus processor (bit==0) */
+ 	apic_write(APIC_SPIV,value);
+
+	udelay(100);			/* B safe */
+}
+
 __initfunc(void smp_callin(void))
 {
 	extern void calibrate_delay(void);
 	int cpuid=GET_APIC_ID(apic_read(APIC_ID));
-	unsigned long l;
 
 	/*
 	 *	Activate our APIC
 	 */
 	
 	SMP_PRINTK(("CALLIN %d %d\n",hard_smp_processor_id(), smp_processor_id()));
- 	l=apic_read(APIC_SPIV);
- 	l|=(1<<8);		/* Enable */
- 	apic_write(APIC_SPIV,l);
+	enable_local_APIC();
 
 	/*
 	 * Set up our APIC timer.
@@ -1004,15 +1015,7 @@
 	}
 #endif
 
-	/*
-	 *	Enable the local APIC
-	 */
-
-	cfg=apic_read(APIC_SPIV);
-	cfg|=(1<<8);		/* Enable APIC */
-	apic_write(APIC_SPIV,cfg);
-
-	udelay(10);
+	enable_local_APIC();
 
 	/*
 	 * Set up our local APIC timer:
@@ -1561,7 +1564,7 @@
  * APIC double write bug.
  */
 
-#define APIC_DIVISOR 16
+#define APIC_DIVISOR 1
 
 void setup_APIC_timer (unsigned int clocks)
 {
@@ -1585,7 +1588,7 @@
 	 */
 	tmp_value = apic_read(APIC_TDCR);
 	apic_write(APIC_TDCR , (tmp_value & ~APIC_TDR_DIV_1 )
-				 | APIC_TDR_DIV_16);
+				 | APIC_TDR_DIV_1);
 
 	tmp_value = apic_read(APIC_TMICT);
 	apic_write(APIC_TMICT, clocks/APIC_DIVISOR);
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/trampoline.S linux/arch/i386/kernel/trampoline.S
--- v2.1.99/linux/arch/i386/kernel/trampoline.S	Tue Mar 17 22:18:14 1998
+++ linux/arch/i386/kernel/trampoline.S	Wed May  6 11:42:54 1998
@@ -54,7 +54,7 @@
 	lmsw	%ax		# into protected mode
 	jmp	flush_instr
 flush_instr:
-	ljmp	$__KERNEL_CS, $0x00100000
+	ljmpl	$__KERNEL_CS, $0x00100000
 				# jump to startup_32
 
 idt_48:
diff -u --recursive --new-file v2.1.99/linux/arch/i386/kernel/vm86.c linux/arch/i386/kernel/vm86.c
--- v2.1.99/linux/arch/i386/kernel/vm86.c	Wed Apr  1 20:11:47 1998
+++ linux/arch/i386/kernel/vm86.c	Wed May  6 10:56:01 1998
@@ -660,7 +660,7 @@
 			int sig = irqnumber >> 8;
 			int irq = irqnumber & 255;
 			handle_irq_zombies();
-			if (!suser()) return -EPERM;
+			if (!capable(CAP_SYS_ADMIN)) return -EPERM;
 			if (!((1 << sig) & ALLOWED_SIGS)) return -EPERM;
 			if ( (irq<3) || (irq>15) ) return -EPERM;
 			if (vm86_irqs[irq].tsk) return -EPERM;
diff -u --recursive --new-file v2.1.99/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- v2.1.99/linux/arch/m68k/kernel/ptrace.c	Thu Mar 26 15:57:02 1998
+++ linux/arch/m68k/kernel/ptrace.c	Wed May  6 10:56:01 1998
@@ -340,7 +340,7 @@
 		    (current->uid != child->uid) ||
 	 	    (current->gid != child->egid) ||
 		    (current->gid != child->sgid) ||
-	 	    (current->gid != child->gid)) && !suser())
+	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
 			goto out;
 		/* the same process cannot be attached many times */
 		if (child->flags & PF_PTRACED)
diff -u --recursive --new-file v2.1.99/linux/arch/m68k/kernel/sys_m68k.c linux/arch/m68k/kernel/sys_m68k.c
--- v2.1.99/linux/arch/m68k/kernel/sys_m68k.c	Tue Feb 17 13:12:45 1998
+++ linux/arch/m68k/kernel/sys_m68k.c	Wed May  6 10:56:01 1998
@@ -548,7 +548,7 @@
 	if (scope == FLUSH_SCOPE_ALL) {
 		/* Only the superuser may flush the whole cache. */
 		ret = -EPERM;
-		if (!suser ())
+		if (!capable(CAP_SYS_ADMIN))
 			goto out;
 	} else {
 		/* Verify that the specified address region actually belongs to
diff -u --recursive --new-file v2.1.99/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- v2.1.99/linux/arch/mips/kernel/ptrace.c	Wed Dec 10 10:31:09 1997
+++ linux/arch/mips/kernel/ptrace.c	Wed May  6 10:56:01 1998
@@ -289,7 +289,8 @@
 		    (current->uid != child->uid) ||
 	 	    (current->gid != child->egid) ||
 		    (current->gid != child->sgid) ||
-	 	    (current->gid != child->gid)) && !suser()) {
+	 	    (current->gid != child->gid)) && 
+		    !capable(CAP_SYS_PTRACE)) {
 			res = -EPERM;
 			goto out;
 		}
diff -u --recursive --new-file v2.1.99/linux/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- v2.1.99/linux/arch/mips/kernel/sysirix.c	Wed Dec 10 10:31:10 1997
+++ linux/arch/mips/kernel/sysirix.c	Wed May  6 10:56:01 1998
@@ -113,7 +113,7 @@
 		       current->comm, current->pid, (unsigned long) value);
 		if(value > RLIM_INFINITY)
 			value = RLIM_INFINITY;
-		if(suser()) {
+		if(capable(CAP_SYS_ADMIN)) {
 			current->rlim[RLIMIT_STACK].rlim_max =
 				current->rlim[RLIMIT_STACK].rlim_cur = value;
 			error = value;
@@ -545,7 +545,7 @@
 	int ret;
 
 	lock_kernel();
-	if(!suser()) {
+	if(!capable(CAP_SYS_TIME)) {
 		ret = -EPERM;
 		goto out;
 	}
diff -u --recursive --new-file v2.1.99/linux/arch/mips/kernel/sysmips.c linux/arch/mips/kernel/sysmips.c
--- v2.1.99/linux/arch/mips/kernel/sysmips.c	Wed Dec 10 10:31:10 1997
+++ linux/arch/mips/kernel/sysmips.c	Wed May  6 10:56:01 1998
@@ -58,7 +58,7 @@
 	{
 	case SETNAME:
 		retval = -EPERM;
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			goto out;
 
 		name = (char *) arg1;
diff -u --recursive --new-file v2.1.99/linux/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c
--- v2.1.99/linux/arch/ppc/kernel/ptrace.c	Thu Apr 23 20:21:29 1998
+++ linux/arch/ppc/kernel/ptrace.c	Wed May  6 10:56:02 1998
@@ -331,7 +331,7 @@
 		    (current->uid != child->euid) ||
 		    (current->uid != child->uid) ||
 	 	    (current->gid != child->egid) ||
-	 	    (current->gid != child->gid)) && !suser())
+	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
 			goto out;
 		/* the same process cannot be attached many times */
 		if (child->flags & PF_PTRACED)
diff -u --recursive --new-file v2.1.99/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.1.99/linux/arch/ppc/mm/init.c	Thu Apr 23 20:21:29 1998
+++ linux/arch/ppc/mm/init.c	Tue May  5 21:33:34 1998
@@ -1296,11 +1296,8 @@
 {
 #ifndef CONFIG_8xx
 	mm->context = NO_CONTEXT;
-	if (mm == current->mm) {
-		get_mmu_context(current);
-		/* done by get_mmu_context() now -- Cort */
-		/*set_context(current->mm->context);*/
-	}
+	if (mm == current->mm)
+		activate_context(current);
 #else
 	asm volatile ("tlbia" : : );
 #endif
diff -u --recursive --new-file v2.1.99/linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c
--- v2.1.99/linux/arch/sparc/kernel/ptrace.c	Tue Mar 17 22:18:14 1998
+++ linux/arch/sparc/kernel/ptrace.c	Wed May  6 10:56:02 1998
@@ -539,7 +539,8 @@
 		    (current->uid != child->euid) ||
 		    (current->uid != child->uid) ||
 		    (current->gid != child->egid) ||
-		    (current->gid != child->gid)) && !suser()) {
+		    (current->gid != child->gid)) && 
+		   !capable(CAP_SYS_PTRACE)) {
 			pt_error_return(regs, EPERM);
 			goto out;
 		}
diff -u --recursive --new-file v2.1.99/linux/arch/sparc64/kernel/psycho.c linux/arch/sparc64/kernel/psycho.c
--- v2.1.99/linux/arch/sparc64/kernel/psycho.c	Thu Apr 23 20:21:32 1998
+++ linux/arch/sparc64/kernel/psycho.c	Wed May  6 10:56:02 1998
@@ -2323,7 +2323,7 @@
 	unsigned int uint;
 	int err = 0;
 
-	if(!suser())
+	if(!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	lock_kernel();
@@ -2361,7 +2361,7 @@
 	unsigned int uint;
 	int err = 0;
 
-	if(!suser())
+	if(!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	lock_kernel();
diff -u --recursive --new-file v2.1.99/linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
--- v2.1.99/linux/arch/sparc64/kernel/ptrace.c	Mon Jan 12 15:15:44 1998
+++ linux/arch/sparc64/kernel/ptrace.c	Wed May  6 10:56:02 1998
@@ -557,7 +557,8 @@
 		    (current->uid != child->euid) ||
 		    (current->uid != child->uid) ||
 		    (current->gid != child->egid) ||
-		    (current->gid != child->gid)) && !suser()) {
+		    (current->gid != child->gid)) && 
+		   !capable(CAP_SYS_PTRACE)) {
 			pt_error_return(regs, EPERM);
 			goto out;
 		}
diff -u --recursive --new-file v2.1.99/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.1.99/linux/arch/sparc64/kernel/sys_sparc32.c	Thu Apr 23 20:21:32 1998
+++ linux/arch/sparc64/kernel/sys_sparc32.c	Wed May  6 10:56:02 1998
@@ -1366,7 +1366,7 @@
 	unsigned long type_page;
 	int err, is_smb, is_ncp;
 
-	if(!suser())
+	if(!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	is_smb = is_ncp = 0;
 	err = copy_mount_stuff_to_kernel((const void *)A(type), &type_page);
diff -u --recursive --new-file v2.1.99/linux/arch/sparc64/kernel/traps.c linux/arch/sparc64/kernel/traps.c
--- v2.1.99/linux/arch/sparc64/kernel/traps.c	Thu Apr 23 20:21:32 1998
+++ linux/arch/sparc64/kernel/traps.c	Wed May  6 10:56:02 1998
@@ -583,7 +583,7 @@
 
 	regs->tpc = regs->tnpc;
 	regs->tnpc = regs->tnpc + 4;
-	if (!suser()) return;
+	if (!capable(CAP_SYS_ADMIN)) return;
 	size >>= PAGE_SHIFT;
 	addr = PAGE_OFFSET - PAGE_SIZE;
 	page = mem_map - 1;
diff -u --recursive --new-file v2.1.99/linux/arch/sparc64/solaris/fs.c linux/arch/sparc64/solaris/fs.c
--- v2.1.99/linux/arch/sparc64/solaris/fs.c	Thu Apr 23 20:21:32 1998
+++ linux/arch/sparc64/solaris/fs.c	Wed May  6 10:56:02 1998
@@ -464,7 +464,7 @@
 		val <<= 9;
 		lock_kernel();
 		if (val > current->rlim[RLIMIT_FSIZE].rlim_max) {
-			if (!suser()) {
+			if (!capable(CAP_SYS_RESOURCE)) {
 				unlock_kernel();
 				return -EPERM;
 			}
diff -u --recursive --new-file v2.1.99/linux/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c
--- v2.1.99/linux/drivers/acorn/block/fd1772.c	Tue Mar 10 10:03:31 1998
+++ linux/drivers/acorn/block/fd1772.c	Wed May  6 10:56:02 1998
@@ -1368,7 +1368,7 @@
 	case FDFLUSH:
 		return invalidate_drive(drive);
 	}
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	if (drive < 0 || drive > 3)
 		return -EINVAL;
diff -u --recursive --new-file v2.1.99/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- v2.1.99/linux/drivers/acorn/block/mfmhd.c	Wed Apr  8 19:36:25 1998
+++ linux/drivers/acorn/block/mfmhd.c	Wed May  6 10:56:02 1998
@@ -1206,14 +1206,14 @@
 		return 0;
 
 	case BLKFLSBUF:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		fsync_dev(dev);
 		invalidate_buffers(dev);
 		return 0;
 
 	case BLKRASET:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		if (arg > 0xff)
 			return -EINVAL;
@@ -1227,7 +1227,7 @@
 		return put_user (mfm[minor].nr_sects, (long *)arg);
 
 	case BLKFRASET:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		max_readahead[major][minor] = arg;
 		return 0;
@@ -1239,7 +1239,7 @@
 		return put_user(max_sectors[major][minor], (long *) arg);
 
 	case BLKRRPART:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		return mfm_reread_partitions(dev);
 
diff -u --recursive --new-file v2.1.99/linux/drivers/ap1000/ddv.c linux/drivers/ap1000/ddv.c
--- v2.1.99/linux/drivers/ap1000/ddv.c	Mon Feb 23 18:12:03 1998
+++ linux/drivers/ap1000/ddv.c	Wed May  6 10:56:08 1998
@@ -856,6 +856,8 @@
 
 	case BLKRRPART:
 		printk("\tBLKRRPART\n");
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
 		return ddv_revalidate(inode->i_rdev,&ddv_gendisk);
 
 	case BLKGETSIZE:   /* Return device size */
diff -u --recursive --new-file v2.1.99/linux/drivers/block/acsi.c linux/drivers/block/acsi.c
--- v2.1.99/linux/drivers/block/acsi.c	Mon Feb 23 18:12:03 1998
+++ linux/drivers/block/acsi.c	Wed May  6 10:56:08 1998
@@ -1149,13 +1149,15 @@
 				(long *) arg);
 		
 	  case BLKFLSBUF:
-		if(!suser())  return -EACCES;
+		if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 		if(!inode->i_rdev) return -EINVAL;
 		fsync_dev(inode->i_rdev);
 		invalidate_buffers(inode->i_rdev);
 		return 0;
 
 	  case BLKRRPART: /* Re-read partition tables */
+	        if (!capable(CAP_SYS_ADMIN)) 
+			return -EACCES;
 		return revalidate_acsidisk(inode->i_rdev, 1);
 	  RO_IOCTLS(inode->i_rdev,arg);
 	  default:
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ali14xx.c linux/drivers/block/ali14xx.c
--- v2.1.99/linux/drivers/block/ali14xx.c	Wed Dec 17 11:11:16 1997
+++ linux/drivers/block/ali14xx.c	Wed May  6 14:42:53 1998
@@ -134,15 +134,15 @@
 
 	/* stuff timing parameters into controller registers */
 	driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit;
-	save_flags(flags);
-	cli();
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
 	outb_p(regOn, basePort);
 	outReg(param1, regTab[driveNum].reg1);
 	outReg(param2, regTab[driveNum].reg2);
 	outReg(param3, regTab[driveNum].reg3);
 	outReg(param4, regTab[driveNum].reg4);
 	outb_p(regOff, basePort);
-	restore_flags(flags);
+	restore_flags(flags);	/* all CPUs */
 }
 
 /*
@@ -154,8 +154,8 @@
 	byte t;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 	for (i = 0; i < ALI_NUM_PORTS; ++i) {
 		basePort = ports[i];
 		regOff = inb(basePort);
@@ -166,7 +166,7 @@
 				dataPort = basePort + 8;
 				t = inReg(0) & 0xf0;
 				outb_p(regOff, basePort);
-				restore_flags(flags);
+				__restore_flags(flags);	/* local CPU only */
 				if (t != 0x50)
 					return 0;
 				return 1;  /* success */
@@ -174,7 +174,7 @@
 		}
 		outb_p(regOff, basePort);
 	}
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 	return 0;
 }
 
@@ -186,15 +186,15 @@
 	byte t;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 	outb_p(regOn, basePort);
 	for (p = initData; p->reg != 0; ++p)
 		outReg(p->data, p->reg);
 	outb_p(0x01, regPort);
 	t = inb(regPort) & 0x01;
 	outb_p(regOff, basePort);
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 	return t;
 }
 
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c
--- v2.1.99/linux/drivers/block/ataflop.c	Mon Feb 23 18:12:04 1998
+++ linux/drivers/block/ataflop.c	Wed May  6 10:56:02 1998
@@ -1631,7 +1631,7 @@
 			return -EFAULT;
 		return 0;
 	case BLKRASET:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		if (param > 0xff)
 			return -EINVAL;
@@ -1641,7 +1641,7 @@
 		return put_user(read_ahead[MAJOR(inode->i_rdev)],
 				(int *) param);
 	case BLKFLSBUF:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		fsync_dev(inode->i_rdev);
 		invalidate_buffers(inode->i_rdev);
diff -u --recursive --new-file v2.1.99/linux/drivers/block/dtc2278.c linux/drivers/block/dtc2278.c
--- v2.1.99/linux/drivers/block/dtc2278.c	Wed Dec 17 11:11:16 1997
+++ linux/drivers/block/dtc2278.c	Wed May  6 14:42:53 1998
@@ -74,14 +74,14 @@
 	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
 
 	if (pio >= 3) {
-		save_flags(flags);
-		cli();
+		save_flags(flags);	/* all CPUs */
+		cli();			/* all CPUs */
 		/*
 		 * This enables PIO mode4 (3?) on the first interface
 		 */
 		sub22(1,0xc3);
 		sub22(0,0xa0);
-		restore_flags(flags);
+		restore_flags(flags);	/* all CPUs */
 	} else {
 		/* we don't know how to set it back again.. */
 	}
@@ -97,8 +97,8 @@
 {
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 	/*
 	 * This enables the second interface
 	 */
@@ -114,7 +114,7 @@
 	sub22(1,0xc3);
 	sub22(0,0xa0);
 #endif
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 
 	ide_hwifs[0].serialized = 1;
 	ide_hwifs[1].serialized = 1;
diff -u --recursive --new-file v2.1.99/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.1.99/linux/drivers/block/floppy.c	Sat May  2 14:19:52 1998
+++ linux/drivers/block/floppy.c	Thu May  7 18:13:47 1998
@@ -1825,7 +1825,6 @@
 	if (!initialising)
 		show_floppy();
 	cancel_activity();
-	sti();
 
 	floppy_enable_hlt();
 	fd_disable_dma();
@@ -2876,7 +2875,6 @@
 		printk("sect=%ld cmd=%d\n", CURRENT->sector, CURRENT->cmd);
 		return;
 	}
-	sti();
 	if (fdc_busy){
 		/* fdc busy, this new request will be treated when the
 		   current one is done */
@@ -3208,7 +3206,7 @@
 	    (g->stretch&~(FD_STRETCH|FD_SWAPSIDES)) != 0)
 		return -EINVAL;
 	if (type){
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		LOCK_FDC(drive,1);
 		for (cnt = 0; cnt < N_DRIVE; cnt++){
@@ -3373,7 +3371,7 @@
 			return _COPYOUT(loc);
 		}
 		case BLKRASET:
-			if(!suser()) return -EACCES;
+			if(!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if(param > 0xff) return -EINVAL;
 			read_ahead[MAJOR(inode->i_rdev)] = param;
 			return 0;
@@ -3381,7 +3379,7 @@
 			return put_user(read_ahead[MAJOR(inode->i_rdev)],
 					(long *) param);
 		case BLKFLSBUF:
-			if(!suser()) return -EACCES;
+			if(!capable(CAP_SYS_ADMIN)) return -EACCES;
 			fsync_dev(inode->i_rdev);
 			invalidate_buffers(inode->i_rdev);
 			return 0;
diff -u --recursive --new-file v2.1.99/linux/drivers/block/hd.c linux/drivers/block/hd.c
--- v2.1.99/linux/drivers/block/hd.c	Sat Sep  6 10:08:56 1997
+++ linux/drivers/block/hd.c	Wed May  6 10:56:08 1998
@@ -603,7 +603,7 @@
 			return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
 		}
 		case BLKRASET:
-			if(!suser())  return -EACCES;
+			if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 			if(arg > 0xff) return -EINVAL;
 			read_ahead[MAJOR(inode->i_rdev)] = arg;
 			return 0;
@@ -616,12 +616,14 @@
 			return put_user(hd[MINOR(inode->i_rdev)].nr_sects, 
 					(long *) arg);
 		case BLKFLSBUF:
-			if(!suser())  return -EACCES;
+			if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 			fsync_dev(inode->i_rdev);
 			invalidate_buffers(inode->i_rdev);
 			return 0;
 
 		case BLKRRPART: /* Re-read partition tables */
+			if (!capable(CAP_SYS_ADMIN)) 
+				return -EACCES;
 			return revalidate_hddisk(inode->i_rdev, 1);
 
 		RO_IOCTLS(inode->i_rdev,arg);
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ht6560b.c linux/drivers/block/ht6560b.c
--- v2.1.99/linux/drivers/block/ht6560b.c	Wed Dec 17 11:11:16 1997
+++ linux/drivers/block/ht6560b.c	Wed May  6 14:42:53 1998
@@ -133,8 +133,8 @@
 	if (select != current_select || timing != current_timing) {
 		current_select = select;
 		current_timing = timing;
-		save_flags (flags);
-		cli();
+		__save_flags (flags);	/* local CPU only */
+		__cli();		/* local CPU only */
 		(void) inb(HT_SELECT_PORT);
 		(void) inb(HT_SELECT_PORT);
 		(void) inb(HT_SELECT_PORT);
@@ -150,7 +150,7 @@
                  */
                 outb (timing, IDE_SELECT_REG);
                 (void) inb (IDE_STATUS_REG);
-		restore_flags (flags);
+		__restore_flags (flags);	/* local CPU only */
 #ifdef DEBUG
 		printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, t, timing);
 #endif
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- v2.1.99/linux/drivers/block/ide-cd.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/ide-cd.c	Tue May  5 10:53:18 1998
@@ -201,10 +201,14 @@
  *                         now set ionly for CD-R and CD-RW drives.  I had 
  *                         removed this support because it produced errors.
  *                         It produced errors _only_ for non-writers. duh.
+ * 4.13  May 05, 1998  -- Suppress useless "in progress of becoming ready"
+ *                         messages, since this is not an error.
+ *                     -- Change error messages to be const
+ *                     -- Remove a "\t" which looks ugly in the syslogs
  *
  *************************************************************************/
 
-#define IDECD_VERSION "4.12"
+#define IDECD_VERSION "4.13"
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -264,11 +268,13 @@
 			return;
 	}
 	if (reqbuf->error_code == 0x70 && reqbuf->sense_key  == 0x02
-	 && reqbuf->asc        == 0x3a && reqbuf->ascq       == 0x00)
+	 && ((reqbuf->asc        == 0x3a && reqbuf->ascq       == 0x00) ||
+	     (reqbuf->asc        == 0x04 && reqbuf->ascq       == 0x01)))
 	{
 		/*
-		 * No disc in drive ("Medium not present"),
-		 * so keep the noise level down to a dull roar.
+		 * Suppress the following errors:
+		 * "Medium not present", and "in progress of becoming ready",
+		 * to keep the noise level down to a dull roar.
 		 */
 		return;
 	}
@@ -276,7 +282,7 @@
 #if VERBOSE_IDE_CD_ERRORS
 	{
 		int i;
-		char *s;
+		const char *s;
 		char buf[80];
 
 		printk ("ATAPI device %s:\n", drive->name);
@@ -346,7 +352,7 @@
 					lo = mid+1;
 			}
 
-			printk ("  The failed \"%s\" packet command was: \n\t\"", s);
+			printk ("  The failed \"%s\" packet command was: \n  \"", s);
 			for (i=0; i<sizeof (failed_command->c); i++)
 				printk ("%02x ", failed_command->c[i]);
 			printk ("\"\n");
@@ -1020,7 +1026,7 @@
 
 #define IDECD_SEEK_THRESHOLD	(1000)			/* 1000 blocks */
 #define IDECD_SEEK_TIMER	(2 * WAIT_MIN_SLEEP)	/* 40 ms */
-#define IDECD_SEEK_TIMEOUT	(20 * IDECD_SEEK_TIMER) /* 0.8 sec */
+#define IDECD_SEEK_TIMEOUT     WAIT_CMD                /* 10 sec */
 
 static void cdrom_seek_intr (ide_drive_t *drive)
 {
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-cd.h linux/drivers/block/ide-cd.h
--- v2.1.99/linux/drivers/block/ide-cd.h	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/ide-cd.h	Wed May  6 14:42:53 1998
@@ -415,7 +415,7 @@
 /* From Table 124 of the ATAPI 1.2 spec.
    Unchanged in Table 140 of the ATAPI 2.6 draft standard. */
 
-char *sense_key_texts[16] = {
+const char * const sense_key_texts[16] = {
 	"No sense data",
 	"Recovered error",
 	"Not ready",
@@ -436,9 +436,9 @@
 
 
 /* From Table 37 of the ATAPI 2.6 draft standard. */
-struct {
+const struct {
 	unsigned short packet_command;
-	char *text;
+	const char * const text;
 } packet_command_texts[] = {
 	{ TEST_UNIT_READY, "Test Unit Ready" },
 	{ REQUEST_SENSE, "Request Sense" },
@@ -471,9 +471,9 @@
 /* From Table 125 of the ATAPI 1.2 spec.,
    with additions from Tables 141 and 142 of the ATAPI 2.6 draft standard. */
 
-struct {
+const struct {
 	unsigned short asc_ascq;
-	char *text;
+	const char * const text;
 } sense_data_texts[] = {
 	{ 0x0000, "No additional sense information" },
 
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c
--- v2.1.99/linux/drivers/block/ide-disk.c	Tue Apr 14 14:29:20 1998
+++ linux/drivers/block/ide-disk.c	Wed May  6 14:42:53 1998
@@ -18,9 +18,10 @@
  * Version 1.04		add /proc configurable settings and S.M.A.R.T support
  * Version 1.05		add capacity support for ATA3 >= 8GB
  * Version 1.06		get boot-up messages to show full cyl count
+ * Version 1.07		disable door-locking if it fails
  */
 
-#define IDEDISK_VERSION	"1.06"
+#define IDEDISK_VERSION	"1.07"
 
 #undef REALLY_SLOW_IO		/* most systems can safely undef this */
 
@@ -185,9 +186,7 @@
 		}
 	} else
 		error = 1;
-
 out:
-
 	if (error)
 		ide_error(drive, "write_intr", stat);
 }
@@ -258,9 +257,7 @@
 		}
 	} else
 		error = 1;
-
 out:
-
 	if (error)
 		ide_error(drive, "multwrite_intr", stat);
 }
@@ -380,7 +377,7 @@
 			return;
 		}
 		if (!drive->unmask)
-			__cli();
+			__cli();	/* local CPU only */
 		if (drive->mult_count) {
 			HWGROUP(drive)->wrq = *rq; /* scratchpad */
 			ide_set_handler (drive, &multwrite_intr, WAIT_CMD);
@@ -405,7 +402,8 @@
 		 * since the open() has already succeeded,
 		 * and the door_lock is irrelevant at this point.
 		 */
-		(void) ide_wait_cmd(drive, WIN_DOORLOCK, 0, 0, 0, NULL);
+		if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORLOCK, 0, 0, 0, NULL))
+			drive->doorlocking = 0;
 	}
 	return 0;
 }
@@ -414,7 +412,8 @@
 {
 	if (drive->removable && !drive->usage) {
 		invalidate_buffers(inode->i_rdev);
-		(void) ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL);
+		if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL))
+			drive->doorlocking = 0;
 	}
 	MOD_DEC_USE_COUNT;
 }
@@ -587,8 +586,13 @@
 
 static int set_nowerr(ide_drive_t *drive, int arg)
 {
+	unsigned long flags;
+
+	if (ide_spin_wait_hwgroup("set_nowerr", drive, &flags))
+		return -EBUSY;
 	drive->nowerr = arg;
 	drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
+	spin_unlock_irqrestore(&HWGROUP(drive)->spinlock, flags);
 	return 0;
 }
 
@@ -658,14 +662,12 @@
 
 	/* check for removable disks (eg. SYQUEST), ignore 'WD' drives */
 	if (id->config & (1<<7)) {	/* removable disk ? */
-		if (id->model[0] != 'W' || id->model[1] != 'D')
+		if (id->model[0] != 'W' || id->model[1] != 'D') {
 			drive->removable = 1;
+			drive->doorlocking = 1;
+		}
 	}
 
-	/* SunDisk drives: treat as non-removable;   can mess up non-Sun systems!  FIXME */
-	if (id->model[0] == 'S' && id->model[1] == 'u')
-		drive->removable = 0;
-
 	/* Extract geometry if we did not already have one for the drive */
 	if (!drive->cyl || !drive->head || !drive->sect) {
 		drive->cyl     = drive->bios_cyl  = id->cyls;
@@ -714,9 +716,10 @@
 		if (drive->cyl > drive->bios_cyl)
 			drive->bios_cyl = drive->cyl;
 	}
+#if 0	/* done instead for entire identify block in arch/ide.h stuff */
 	/* fix byte-ordering of buffer size field */
 	id->buf_size = le16_to_cpu(id->buf_size);
-
+#endif
 	printk (KERN_INFO "%s: %.40s, %ldMB w/%dkB Cache, CHS=%d/%d/%d",
 	 drive->name, id->model, idedisk_capacity(drive)/2048L, id->buf_size/2,
 	 drive->bios_cyl, drive->bios_head, drive->bios_sect);
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-dma.c linux/drivers/block/ide-dma.c
--- v2.1.99/linux/drivers/block/ide-dma.c	Thu Apr 23 20:21:32 1998
+++ linux/drivers/block/ide-dma.c	Wed May  6 14:42:53 1998
@@ -84,7 +84,7 @@
  */
 const char *good_dma_drives[] = {"Micropolis 2112A",
 				 "CONNER CTMA 4000",
-				 "ST34342A",
+				 "ST34342A",	/* for Sun Ultra */
 				 NULL};
 
 /*
@@ -128,7 +128,7 @@
 		}
 		printk("%s: dma_intr: bad DMA status\n", drive->name);
 	}
-	sti();
+	ide__sti();	/* local CPU only */
 	ide_error(drive, "dma_intr", stat);
 }
 
@@ -210,7 +210,7 @@
 	struct hd_driveid *id = drive->id;
 	ide_hwif_t *hwif = HWIF(drive);
 
-	if (id && (id->capability & 1) && !HWIF(drive)->no_autodma) {
+	if (id && (id->capability & 1) && !hwif->no_autodma) {
 		/* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */
 		if (id->field_valid & 4)	/* UltraDMA */
 			if  ((id->dma_ultra & (id->dma_ultra >> 8) & 7))
@@ -250,6 +250,7 @@
 	ide_hwif_t *hwif = HWIF(drive);
 	unsigned long dma_base = hwif->dma_base;
 	unsigned int count, reading = 0;
+	byte dma_stat;
 
 	switch (func) {
 		case ide_dma_off:
@@ -267,22 +268,29 @@
 				return 1;	/* try PIO instead of DMA */
 			outl(virt_to_bus(hwif->dmatable), dma_base + 4); /* PRD table */
 			outb(reading, dma_base);			/* specify r/w */
-			outb(inb(dma_base+2)|0x06, dma_base+2);		/* clear status bits */
+			outb(inb(dma_base+2)|6, dma_base+2);		/* clear INTR & ERROR flags */
+			drive->waiting_for_dma = 1;
 			if (drive->media != ide_disk)
 				return 0;
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);/* issue cmd to drive */
 			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 		case ide_dma_begin:
+			/* Note that this is done *after* the cmd has
+			 * been issued to the drive, as per the BM-IDE spec.
+			 * The Promise Ultra33 doesn't work correctly when
+			 * we do this part before issuing the drive cmd.
+			 */
 			outb(inb(dma_base)|1, dma_base);		/* start DMA */
 			return 0;
 		case ide_dma_end: /* returns 1 on error, 0 otherwise */
-		{
-			byte dma_stat = inb(dma_base+2);
-			int rc = (dma_stat & 7) != 4;
+			drive->waiting_for_dma = 0;
+			dma_stat = inb(dma_base+2);
 			outb(inb(dma_base)&~1, dma_base);		/* stop DMA */
 			outb(dma_stat|6, dma_base+2);	/* clear the INTR & ERROR bits */
-			return rc;	/* verify good DMA status */
-		}
+			return (dma_stat & 7) != 4;	/* verify good DMA status */
+		case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
+			dma_stat = inb(dma_base+2);
+			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
 		default:
 			printk("ide_dmaproc: unsupported func: %d\n", func);
 			return 1;
@@ -331,9 +339,10 @@
 /*
  * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
  */
-__initfunc(unsigned long ide_get_or_set_dma_base (struct pci_dev *dev, ide_hwif_t *hwif, int extra, const char *name))
+__initfunc(unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name))
 {
-	unsigned long dma_base = 0;
+	unsigned long	dma_base = 0;
+	struct pci_dev	*dev = hwif->pci_dev;
 
 	if (hwif->mate && hwif->mate->dma_base) {
 		dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
--- v2.1.99/linux/drivers/block/ide-floppy.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/ide-floppy.c	Wed May  6 14:42:53 1998
@@ -713,7 +713,7 @@
 #endif /* IDEFLOPPY_DEBUG_LOG */
 		clear_bit (PC_DMA_IN_PROGRESS, &pc->flags);
 
-		ide_sti();
+		ide__sti();	/* local CPU only */
 
 		if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) {	/* Error detected */
 #if IDEFLOPPY_DEBUG_LOG
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c
--- v2.1.99/linux/drivers/block/ide-pci.c	Thu Apr 23 20:21:32 1998
+++ linux/drivers/block/ide-pci.c	Wed May  6 14:42:53 1998
@@ -43,6 +43,7 @@
 #define DEVID_NS87415	((ide_pci_devid_t){PCI_VENDOR_ID_NS,      PCI_DEVICE_ID_NS_87415})
 #define DEVID_HT6565	((ide_pci_devid_t){PCI_VENDOR_ID_HOLTEK,  PCI_DEVICE_ID_HOLTEK_6565})
 #define DEVID_AEC6210	((ide_pci_devid_t){0x1191,                0x0005})
+#define DEVID_W82C105	((ide_pci_devid_t){PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105})
 
 #define IDE_IGNORE	((void *)-1)
 
@@ -71,7 +72,18 @@
 extern void ide_init_cmd646(ide_hwif_t *);
 #define INIT_CMD646	&ide_init_cmd646
 #else
+#ifdef __sparc_v9__
 #define INIT_CMD646	IDE_IGNORE
+#else
+#define INIT_CMD646	NULL
+#endif
+#endif
+
+#ifdef CONFIG_BLK_DEV_SL82C105
+extern void ide_init_sl82c105(ide_hwif_t *);
+#define INIT_W82C105	&ide_init_sl82c105
+#else
+#define INIT_W82C105	IDE_IGNORE
 #endif
 
 #ifdef CONFIG_BLK_DEV_RZ1000
@@ -113,6 +125,7 @@
 	{DEVID_TRM290,	"TRM290",	INIT_TRM290,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}} },
 	{DEVID_NS87415,	"NS87415",	INIT_NS87415,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}} },
 	{DEVID_AEC6210,	"AEC6210",	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}} },
+	{DEVID_W82C105,	"W82C105",	INIT_W82C105,	{{0x40,0x01,0x01}, {0x40,0x10,0x10}} },
 	{IDE_PCI_DEVID_NULL, "PCI_IDE",	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}} }};
 
 /*
@@ -269,7 +282,7 @@
 		ide_pci_enablebit_t *e = &(d->enablebits[port]);
 		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val))
 			continue;	/* port not enabled */
-		ctl = dev->base_address[1+2*port] & PCI_BASE_ADDRESS_IO_MASK;
+		ctl = dev->base_address[(2*port)+1] & PCI_BASE_ADDRESS_IO_MASK;
 		if (!ctl)
 			ctl = port ? 0x374 : 0x3f4;	/* use default value */
 		base = dev->base_address[2*port] & ~7;
@@ -299,7 +312,7 @@
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) ||
 		    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) {
 			unsigned int extra = (!mate && IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246)) ? 16 : 0;
-			unsigned long dma_base = ide_get_or_set_dma_base(dev, hwif, extra, d->name);
+			unsigned long dma_base = ide_get_or_set_dma_base(hwif, extra, d->name);
 			if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
 				/*
  	 			 * Set up BM-DMA capability (PnP BIOS should have done this)
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c
--- v2.1.99/linux/drivers/block/ide-probe.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/ide-probe.c	Wed May  6 14:42:53 1998
@@ -47,7 +47,7 @@
 
 	id = drive->id = kmalloc (SECTOR_WORDS*4, GFP_KERNEL);
 	ide_input_data(drive, id, SECTOR_WORDS);	/* read 512 bytes of id info */
-	sti();
+	ide__sti();	/* local CPU only */
 	ide_fix_driveid(id);
 
 #if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
@@ -195,12 +195,12 @@
 	delay_50ms();		/* wait for IRQ and DRQ_STAT */
 	if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
 		unsigned long flags;
-		save_flags(flags);
-		cli();			/* some systems need this */
+		__save_flags(flags);	/* local CPU only */
+		__cli();		/* local CPU only; some systems need this */
 		do_identify(drive, cmd); /* drive returned ID */
 		rc = 0;			/* drive responded with ID */
 		(void) GET_STAT();	/* clear drive IRQ */
-		restore_flags(flags);
+		__restore_flags(flags);	/* local CPU only */
 	} else
 		rc = 2;			/* drive refused ID */
 	if (!HWIF(drive)->irq) {
@@ -398,8 +398,8 @@
 		return;	
 	}
 
-	save_flags(flags);
-	sti();	/* needed for jiffies and irq probing */
+	__save_flags(flags);	/* local CPU only */
+	__sti();		/* local CPU only; needed for jiffies and irq probing */
 	/*
 	 * Second drive should only exist if first drive was found,
 	 * but a lot of cdrom drives are configured as single slaves.
@@ -429,7 +429,7 @@
 		} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));
 
 	}
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		ide_drive_t *drive = &hwif->drives[unit];
 		if (drive->present) {
@@ -486,8 +486,8 @@
 	ide_hwgroup_t *hwgroup;
 	ide_hwif_t *match = NULL;
 
-	save_flags(flags);
-	cli();
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
 
 	hwif->hwgroup = NULL;
 #if MAX_HWIFS > 1
@@ -499,7 +499,9 @@
 		if (h->hwgroup) {  /* scan only initialized hwif's */
 			if (hwif->irq == h->irq) {
 				hwif->sharing_irq = h->sharing_irq = 1;
-				save_match(hwif, h, &match);
+				if (hwif->chipset != ide_pci || h->chipset != ide_pci) {
+					save_match(hwif, h, &match);
+				}
 			}
 			if (hwif->serialized) {
 				if (hwif->mate && hwif->mate->irq == h->irq)
@@ -520,10 +522,15 @@
 	} else {
 		hwgroup = kmalloc(sizeof(ide_hwgroup_t), GFP_KERNEL);
 		memset(hwgroup, 0, sizeof(ide_hwgroup_t));
-		hwgroup->hwif 	 = hwif->next = hwif;
-		hwgroup->rq      = NULL;
-		hwgroup->handler = NULL;
-		hwgroup->drive   = NULL;
+		hwgroup->hwif     = hwif->next = hwif;
+		hwgroup->rq       = NULL;
+		hwgroup->handler  = NULL;
+		hwgroup->drive    = NULL;
+		hwgroup->busy     = 0;
+		hwgroup->spinlock = (spinlock_t)SPIN_LOCK_UNLOCKED;
+#if (DEBUG_SPINLOCK > 0)
+		printk("hwgroup(%s) spinlock is %p\n", hwif->name,  &hwgroup->spinlock);	/* FIXME */
+#endif
 		init_timer(&hwgroup->timer);
 		hwgroup->timer.function = &ide_timer_expiry;
 		hwgroup->timer.data = (unsigned long) hwgroup;
@@ -533,10 +540,11 @@
 	 * Allocate the irq, if not already obtained for another hwif
 	 */
 	if (!match || match->irq != hwif->irq) {
-		if (ide_request_irq(hwif->irq, &ide_intr, SA_INTERRUPT, hwif->name, hwgroup)) {
+		int sa = (hwif->chipset == ide_pci) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;
+		if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) {
 			if (!match)
 				kfree(hwgroup);
-			restore_flags(flags);
+			restore_flags(flags);	/* all CPUs */
 			return 1;
 		}
 	}
@@ -558,7 +566,7 @@
 		hwgroup->drive->next = drive;
 	}
 	hwgroup->hwif = HWIF(hwgroup->drive);
-	restore_flags(flags);	/* safe now that hwif->hwgroup is set up */
+	restore_flags(flags);	/* all CPUs; safe now that hwif->hwgroup is set up */
 
 #ifndef __mc68000__
 	printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,
@@ -685,13 +693,17 @@
 		read_ahead[hwif->major] = 8;	/* (4kB) */
 		hwif->present = 1;	/* success */
 	}
+#if (DEBUG_SPINLOCK > 0)
+{
+	static int done = 0;
+	if (!done++)
+		printk("io_request_lock is %p\n", &io_request_lock);    /* FIXME */
+}
+#endif
 	return hwif->present;
 }
 
-
-int ideprobe_init(void);
-
-
+int ideprobe_init (void);
 static ide_module_t ideprobe_module = {
 	IDE_PROBE_MODULE,
 	ideprobe_init,
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-proc.c linux/drivers/block/ide-proc.c
--- v2.1.99/linux/drivers/block/ide-proc.c	Thu Apr 23 20:21:32 1998
+++ linux/drivers/block/ide-proc.c	Wed May  6 14:42:53 1998
@@ -111,7 +111,7 @@
 	unsigned long	startn = 0, n, flags;
 	const char	*start = NULL, *msg = NULL;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 	/*
 	 * Skip over leading whitespace
@@ -124,7 +124,7 @@
 	 * Do one full pass to verify all parameters,
 	 * then do another to actually write the regs.
 	 */
-	save_flags(flags);
+	save_flags(flags);	/* all CPUs */
 	do {
 		const char *p;
 		if (for_real) {
@@ -133,14 +133,15 @@
 			ide_hwgroup_t *mategroup = NULL;
 			if (hwif->mate && hwif->mate->hwgroup)
 				mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup);
-			cli();	/* ensure all writes are done together */
-			while (mygroup->active || (mategroup && mategroup->active)) {
-				restore_flags(flags);
+			cli();	/* all CPUs; ensure all writes are done together */
+			while (mygroup->busy || (mategroup && mategroup->busy)) {
+				sti();	/* all CPUs */
 				if (0 < (signed long)(jiffies - timeout)) {
 					printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name);
+					restore_flags(flags);	/* all CPUs */
 					return -EBUSY;
 				}
-				cli();
+				cli();	/* all CPUs */
 			}
 		}
 		p = buffer;
@@ -155,7 +156,7 @@
 						break;
 				case 'P':	is_pci = 1;
 #ifdef CONFIG_BLK_DEV_IDEPCI
-						if (!IDE_PCI_DEVID_EQ(hwif->pci_devid, IDE_PCI_DEVID_NULL))
+						if (hwif->pci_dev && !IDE_PCI_DEVID_EQ(hwif->pci_devid, IDE_PCI_DEVID_NULL))
 							break;
 #endif	/* CONFIG_BLK_DEV_IDEPCI */
 						msg = "not a PCI device";
@@ -174,7 +175,7 @@
 				msg = "bad/missing register number";
 				goto parse_error;
 			}
-			if (--n < 0 || *p++ != ':') {
+			if (n-- == 0 || *p++ != ':') {
 				msg = "missing ':'";
 				goto parse_error;
 			}
@@ -223,7 +224,7 @@
 							break;
 					}
 					if (rc) {
-						restore_flags(flags);
+						restore_flags(flags);	/* all CPUs */
 						printk("proc_ide_write_config: error writing %s at bus %02x dev %02x reg 0x%x value 0x%x\n",
 							msg, dev->bus->number, dev->devfn, reg, val);
 						printk("proc_ide_write_config: error %d\n", rc);
@@ -243,10 +244,10 @@
 			}
 		}
 	} while (!for_real++);
-	restore_flags(flags);
+	restore_flags(flags);	/* all CPUs */
 	return count;
 parse_error:
-	restore_flags(flags);
+	restore_flags(flags);	/* all CPUs */
 	printk("parse error\n");
 	return xx_xx_parse_error(start, startn, msg);
 }
@@ -259,27 +260,25 @@
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
 	ide_hwif_t	*hwif = (ide_hwif_t *)data;
-	int		reg = 0;
+	struct pci_dev	*dev = hwif->pci_dev;
+	if (!IDE_PCI_DEVID_EQ(hwif->pci_devid, IDE_PCI_DEVID_NULL) && dev && dev->bus) {
+		int reg = 0;
 
-	struct pci_dev *dev = hwif->pci_dev;
-
-	out += sprintf(out, "pci bus %02x device %02x vid %04x did %04x channel %d\n",
-		dev->bus->number, dev->devfn, hwif->pci_devid.vid, hwif->pci_devid.did, hwif->channel);
-	do {
-		byte val;
-		int rc = pci_read_config_byte(dev, reg, &val);
-		if (rc) {
-			printk("proc_ide_read_config: error reading bus %02x dev %02x reg 0x%02x\n",
-				dev->bus->number, dev->devfn, reg);
-			printk("proc_ide_read_config: error %d\n", rc);
-			return -EIO;
-			out += sprintf(out, "??%c", (++reg & 0xf) ? ' ' : '\n');
-		} else
-			out += sprintf(out, "%02x%c", val, (++reg & 0xf) ? ' ' : '\n');
-	} while (reg < 0x100);
-#else	/* CONFIG_BLK_DEV_IDEPCI */
-	out += sprintf(out, "(none)\n");
+		out += sprintf(out, "pci bus %02x device %02x vid %04x did %04x channel %d\n",
+			dev->bus->number, dev->devfn, hwif->pci_devid.vid, hwif->pci_devid.did, hwif->channel);
+		do {
+			byte val;
+			int rc = pci_read_config_byte(dev, reg, &val);
+			if (rc) {
+				printk("proc_ide_read_config: error %d reading bus %02x dev %02x reg 0x%02x\n",
+					rc, dev->bus->number, dev->devfn, reg);
+				out += sprintf(out, "??%c", (++reg & 0xf) ? ' ' : '\n');
+			} else
+				out += sprintf(out, "%02x%c", val, (++reg & 0xf) ? ' ' : '\n');
+		} while (reg < 0x100);
+	} else
 #endif	/* CONFIG_BLK_DEV_IDEPCI */
+		out += sprintf(out, "(none)\n");
 	len = out - page;
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
@@ -425,14 +424,13 @@
 	(struct file *file, const char *buffer, unsigned long count, void *data)
 {
 	ide_drive_t	*drive = (ide_drive_t *) data;
-	ide_hwif_t	*hwif = HWIF(drive);
 	char		name[MAX_LEN + 1];
 	int		for_real = 0, len;
-	unsigned long	n, flags;
+	unsigned long	n;
 	const char	*start = NULL;
 	ide_settings_t	*setting;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 	/*
 	 * Skip over leading whitespace
@@ -443,27 +441,10 @@
 	}
 	/*
 	 * Do one full pass to verify all parameters,
-	 * then do another to actually write the pci regs.
+	 * then do another to actually write the new settings.
 	 */
-	save_flags(flags);
 	do {
 		const char *p;
-		if (for_real) {
-			unsigned long timeout = jiffies + (3 * HZ);
-			ide_hwgroup_t *mygroup = (ide_hwgroup_t *)(hwif->hwgroup);
-			ide_hwgroup_t *mategroup = NULL;
-			if (hwif->mate && hwif->mate->hwgroup)
-				mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup);
-			cli();	/* ensure all writes are done together */
-			while (mygroup->active || (mategroup && mategroup->active)) {
-				restore_flags(flags);
-				if (0 < (signed long)(jiffies - timeout)) {
-					printk("/proc/ide/%s/settings: channel(s) busy, cannot write\n", drive->name);
-					return -EBUSY;
-				}
-				cli();
-			}
-		}
 		p = buffer;
 		n = count;
 		while (n > 0) {
@@ -508,10 +489,8 @@
 				ide_write_setting(drive, setting, val * setting->div_factor / setting->mul_factor);
 		}
 	} while (!for_real++);
-	restore_flags(flags);
 	return count;
 parse_error:
-	restore_flags(flags);
 	printk("proc_ide_write_settings(): parse error\n");
 	return -EINVAL;
 }
@@ -573,7 +552,7 @@
 {
 	ide_drive_t	*drive = (ide_drive_t *) data;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 	if (ide_replace_subdriver(drive, buffer))
 		return -EINVAL;
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
--- v2.1.99/linux/drivers/block/ide-tape.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/ide-tape.c	Wed May  6 14:42:53 1998
@@ -1432,8 +1432,8 @@
 #if IDETAPE_DEBUG_LOG
 	printk (KERN_INFO "Reached idetape_add_stage_tail\n");
 #endif /* IDETAPE_DEBUG_LOG */
-	save_flags (flags);
-	cli ();
+	save_flags (flags);	/* all CPUs (overkill?) */
+	cli();			/* all CPUs (overkill?) */
 	stage->next=NULL;
 	if (tape->last_stage != NULL)
 		tape->last_stage->next=stage;
@@ -1444,7 +1444,7 @@
 		tape->next_stage=tape->last_stage;
 	tape->nr_stages++;
 	tape->nr_pending_stages++;
-	restore_flags (flags);
+	restore_flags (flags);	/* all CPUs (overkill?) */
 }
 
 /*
@@ -1754,7 +1754,7 @@
 #endif /* IDETAPE_DEBUG_LOG */
 		clear_bit (PC_DMA_IN_PROGRESS, &pc->flags);
 
-		ide_sti();
+		ide__sti();	/* local CPU only */
 
 		if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) {	/* Error detected */
 #if IDETAPE_DEBUG_LOG
@@ -2398,11 +2398,11 @@
 		 */
 		return (idetape_queue_rw_tail (drive, IDETAPE_READ_RQ, blocks, tape->merge_stage->bh));
 	}
-	save_flags (flags);
-	cli ();
+	save_flags (flags);	/* all CPUs (overkill?) */
+	cli();			/* all CPUs (overkill?) */
 	if (tape->active_stage == tape->first_stage)
 		idetape_wait_for_request (tape->active_data_request);
-	restore_flags (flags);
+	restore_flags (flags);	/* all CPUs (overkill?) */
 
 	rq_ptr = &tape->first_stage->rq;
 	bytes_read = tape->tape_block_size * (rq_ptr->nr_sectors - rq_ptr->current_nr_sectors);
@@ -2451,13 +2451,13 @@
 	 *	Pay special attention to possible race conditions.
 	 */
 	while ((new_stage = idetape_kmalloc_stage (tape)) == NULL) {
-		save_flags (flags);
-		cli ();
+		save_flags (flags);	/* all CPUs (overkill?) */
+		cli();			/* all CPUs (overkill?) */
 		if (idetape_pipeline_active (tape)) {
 			idetape_wait_for_request (tape->active_data_request);
-			restore_flags (flags);
+			restore_flags (flags);	/* all CPUs (overkill?) */
 		} else {
-			restore_flags (flags);
+			restore_flags (flags);	/* all CPUs (overkill?) */
 			idetape_insert_pipeline_into_queue (drive);
 			if (idetape_pipeline_active (tape))
 				continue;
@@ -2514,12 +2514,12 @@
 	if (tape->first_stage == NULL)
 		return;
 		
-	save_flags (flags);
-	cli ();
+	save_flags (flags);	/* all CPUs (overkill?) */
+	cli();			/* all CPUs (overkill?) */
 	tape->next_stage = NULL;
 	if (idetape_pipeline_active (tape))
 		idetape_wait_for_request (tape->active_data_request);
-	restore_flags (flags);
+	restore_flags (flags);	/* all CPUs (overkill?) */
 
 	while (tape->first_stage != NULL)
 		idetape_remove_stage_head (drive);
@@ -2539,8 +2539,8 @@
 	if (!idetape_pipeline_active (tape))
 		idetape_insert_pipeline_into_queue (drive);
 
-	save_flags (flags);
-	cli ();
+	save_flags (flags);	/* all CPUs (overkill?) */
+	cli();			/* all CPUs (overkill?) */
 	if (!idetape_pipeline_active (tape))
 		goto abort;
 #if IDETAPE_DEBUG_BUGS
@@ -2550,7 +2550,7 @@
 #endif /* IDETAPE_DEBUG_BUGS */
 	idetape_wait_for_request (&tape->last_stage->rq);
 abort:
-	restore_flags (flags);
+	restore_flags (flags);	/* all CPUs (overkill?) */
 }
 
 static void idetape_pad_zeros (ide_drive_t *drive, int bcount)
@@ -2795,11 +2795,11 @@
 			 *	Wait until the first read-ahead request
 			 *	is serviced.
 			 */
-			save_flags (flags);
-			cli ();
+			save_flags (flags);	/* all CPUs (overkill?) */
+			cli();			/* all CPUs (overkill?) */
 			if (tape->active_stage == tape->first_stage)
 				idetape_wait_for_request (tape->active_data_request);
-			restore_flags (flags);
+			restore_flags (flags);	/* all CPUs (overkill?) */
 
 			if (tape->first_stage->rq.errors == IDETAPE_ERROR_FILEMARK)
 				count++;
@@ -3620,14 +3620,14 @@
 	int minor = tape->minor;
 	unsigned long flags;
 
-	save_flags (flags);
-	cli ();
+	save_flags (flags);	/* all CPUs (overkill?) */
+	cli();			/* all CPUs (overkill?) */
 	if (test_bit (IDETAPE_BUSY, &tape->flags) || tape->first_stage != NULL || tape->merge_stage_size || drive->usage) {
-		restore_flags(flags);
+		restore_flags(flags);	/* all CPUs (overkill?) */
 		return 1;
 	}
 	idetape_chrdevs[minor].drive = NULL;
-	restore_flags (flags);
+	restore_flags (flags);	/* all CPUs (overkill?) */
 	DRIVER(drive)->busy = 0;
 	(void) ide_unregister_subdriver (drive);
 	drive->driver_data = NULL;
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.1.99/linux/drivers/block/ide.c	Sat May  2 14:19:53 1998
+++ linux/drivers/block/ide.c	Wed May  6 14:42:54 1998
@@ -86,6 +86,9 @@
  * Version 6.12		integrate ioctl and proc interfaces
  *			fix parsing of "idex=" command line parameter
  * Version 6.13		add support for ide4/ide5 courtesy rjones@orchestream.com
+ * Version 6.14		fixed IRQ sharing among PCI devices
+ * Version 6.15		added SMP awareness to IDE drivers
+ * Version 6.16		fixed various bugs; even more SMP friendly
  *
  *  Some additional driver compile-time options are in ide.h
  *
@@ -155,13 +158,13 @@
 	unsigned long t, flags;
 	int i;
 
-	__save_flags(flags);
-	__cli();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 	t = jiffies * 11932;
     	outb_p(0, 0x43);
 	i = inb_p(0x40);
 	i |= inb(0x40) << 8;
-	__restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 	return (t - i);
 }
 #endif /* DISK_RECOVERY_TIME */
@@ -178,15 +181,11 @@
  */
 static void init_hwif_data (unsigned int index)
 {
-	byte *p;
 	unsigned int unit;
 	ide_hwif_t *hwif = &ide_hwifs[index];
 
 	/* bulk initialize hwif & drive info with zeros */
-	p = ((byte *) hwif) + sizeof(ide_hwif_t);
-	do {
-		*--p = 0;
-	} while (p > (byte *) hwif);
+	memset(hwif, 0, sizeof(ide_hwif_t));
 
 	/* fill in any non-zero initial values */
 	hwif->index     = index;
@@ -299,11 +298,11 @@
 #if SUPPORT_VLB_SYNC
 		if (io_32bit & 2) {
 			unsigned long flags;
-			__save_flags(flags);
-			__cli();
+			__save_flags(flags);	/* local CPU only */
+			__cli();		/* local CPU only */
 			do_vlb_sync(IDE_NSECTOR_REG);
 			insl(IDE_DATA_REG, buffer, wcount);
-			__restore_flags(flags);
+			__restore_flags(flags);	/* local CPU only */
 		} else
 #endif /* SUPPORT_VLB_SYNC */
 			insl(IDE_DATA_REG, buffer, wcount);
@@ -332,11 +331,11 @@
 #if SUPPORT_VLB_SYNC
 		if (io_32bit & 2) {
 			unsigned long flags;
-			__save_flags(flags);
-			__cli();
+			__save_flags(flags);	/* local CPU only */
+			__cli();		/* local CPU only */
 			do_vlb_sync(IDE_NSECTOR_REG);
 			outsl(IDE_DATA_REG, buffer, wcount);
-			__restore_flags(flags);
+			__restore_flags(flags);	/* local CPU only */
 		} else
 #endif /* SUPPORT_VLB_SYNC */
 			outsl(IDE_DATA_REG, buffer, wcount);
@@ -392,6 +391,85 @@
 }
 
 /*
+ * Needed for PCI irq sharing
+ */
+static inline int drive_is_ready (ide_drive_t *drive)
+{
+	if (drive->waiting_for_dma)
+		return HWIF(drive)->dmaproc(ide_dma_test_irq, drive);
+#if 0
+	udelay(1);	/* need to guarantee 400ns since last command was issued */
+#endif
+	if (GET_STAT() & BUSY_STAT)
+		return 0;	/* drive busy:  definitely not interrupting */
+	return 1;		/* drive ready: *might* be interrupting */
+}
+
+#if !defined(__SMP__) && defined(DEBUG_SPINLOCKS) && (DEBUG_SPINLOCKS > 1)
+
+static const char *ide_lock_name(spinlock_t *spinlock)
+{
+	int index;
+
+	if (spinlock == &io_request_lock)
+		return "io_request_lock";
+	for (index = 0; index < MAX_HWIFS; index++) {
+		ide_hwif_t	*hwif    = &ide_hwifs[index];
+		ide_hwgroup_t	*hwgroup = hwif->hwgroup;
+		if (spinlock == &hwgroup->spinlock)
+			return hwif->name;
+	}
+	return "?";
+}
+
+#define IDE_SPIN_LOCK_IRQ(msg,spinlock)				\
+{								\
+	static int __babble = 20;				\
+	__cli();							\
+	if ((spinlock)->lock && __babble) {			\
+		__babble--;					\
+		printk("ide_lock: %s: already locked (%s)\n", msg, ide_lock_name(spinlock)); \
+	}							\
+	/* spin_lock_irq(spinlock); */				\
+	(spinlock)->lock = 1;					\
+}
+
+#define IDE_SPIN_LOCK_IRQSAVE(msg,spinlock,flags)		\
+{								\
+	__save_flags(flags);					\
+	IDE_SPIN_LOCK_IRQ(msg,spinlock);			\
+}
+
+#define IDE_SPIN_UNLOCK_IRQRESTORE(msg,spinlock,flags)		\
+{								\
+	static int __babble = 20;				\
+	__cli();							\
+	if (!((spinlock)->lock) && __babble) {			\
+		__babble--;					\
+		printk("ide_unlock: %s: not locked (%s)\n", msg, ide_lock_name(spinlock)); \
+	}							\
+	/* spin_unlock_irqrestore(msg,spinlock,flags); */	\
+	(spinlock)->lock = 0;					\
+	restore_flags(flags);					\
+}
+
+#define IDE_SPIN_UNLOCK(msg,spinlock)				\
+{								\
+	unsigned long __flags;					\
+	__save_flags(__flags);					\
+	IDE_SPIN_UNLOCK_IRQRESTORE(msg,spinlock,__flags);	\
+}
+
+#else	/* DEBUG_SPINLOCKS */
+
+#define IDE_SPIN_LOCK_IRQ(msg,spinlock)			spin_lock_irq(spinlock)
+#define IDE_SPIN_LOCK_IRQSAVE(msg,spinlock,flags)	spin_lock_irqsave(spinlock,flags)
+#define IDE_SPIN_UNLOCK(msg,spinlock)			spin_unlock(spinlock)
+#define IDE_SPIN_UNLOCK_IRQRESTORE(msg,spinlock,flags)	spin_unlock_irqrestore(spinlock,flags)
+
+#endif	/* DEBUG_SPINLOCKS */
+
+/*
  * This should get invoked any time we exit the driver to
  * wait for an interrupt response from a drive.  handler() points
  * at the appropriate code to handle the next interrupt, and a
@@ -400,7 +478,10 @@
  */
 void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout)
 {
+	unsigned long flags;
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
+
+	IDE_SPIN_LOCK_IRQSAVE("ide_set_handler", &hwgroup->spinlock, flags);
 #ifdef DEBUG
 	if (hwgroup->handler != NULL) {
 		printk("%s: ide_set_handler: handler not null; old=%p, new=%p\n",
@@ -410,6 +491,7 @@
 	hwgroup->handler       = handler;
 	hwgroup->timer.expires = jiffies + timeout;
 	add_timer(&(hwgroup->timer));
+	IDE_SPIN_UNLOCK_IRQRESTORE("ide_set_handler", &hwgroup->spinlock, flags);
 }
 
 /*
@@ -558,8 +640,8 @@
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 
-	__save_flags(flags);
-	__cli();		/* Why ? */
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 
 	/* For an ATAPI device, first try an ATAPI SRST. */
 	if (drive->media != ide_disk && !do_not_try_atapi) {
@@ -569,7 +651,7 @@
 		OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
 		ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20);
-		__restore_flags (flags);
+		__restore_flags (flags);	/* local CPU only */
 		return;
 	}
 
@@ -597,7 +679,7 @@
 	ide_set_handler (drive, &reset_pollfunc, HZ/20);
 #endif	/* OK_TO_RESET_CONTROLLER */
 
-	__restore_flags (flags);
+	__restore_flags (flags);	/* local CPU only */
 }
 
 /*
@@ -625,15 +707,17 @@
 			args[2] = IN_BYTE(IDE_NSECTOR_REG);
 		}
 	}
-	__save_flags(flags);
-	__cli();
+	IDE_SPIN_LOCK_IRQSAVE("ide_end_drive_cmd", &io_request_lock, flags);
 	drive->queue = rq->next;
 	blk_dev[MAJOR(rq->rq_dev)].current_request = NULL;
 	HWGROUP(drive)->rq = NULL;
 	rq->rq_status = RQ_INACTIVE;
+	IDE_SPIN_UNLOCK_IRQRESTORE("ide_end_drive_cmd", &io_request_lock, flags);
+	save_flags(flags);	/* all CPUs; overkill? */
+	cli();			/* all CPUs; overkill? */
 	if (rq->sem != NULL)
-		up(rq->sem);
-	__restore_flags(flags);
+		up(rq->sem);	/* inform originator that rq has been serviced */
+	restore_flags(flags);	/* all CPUs; overkill? */
 }
 
 /*
@@ -644,8 +728,8 @@
 	unsigned long flags;
 	byte err = 0;
 
-	__save_flags (flags);
-	/* ide_sti(); HACK */
+	__save_flags (flags);	/* local CPU only */
+	ide__sti();		/* local CPU only */
 	printk("%s: %s: status=0x%02x", drive->name, msg, stat);
 #if FANCY_STATUS_DUMPS
 	printk(" { ");
@@ -698,7 +782,7 @@
 #endif	/* FANCY_STATUS_DUMPS */
 		printk("\n");
 	}
-	__restore_flags (flags);
+	__restore_flags (flags);	/* local CPU only */
 	return err;
 }
 
@@ -732,7 +816,7 @@
 	byte err;
 
 	err = ide_dump_status(drive, msg, stat);
-	if ((rq = HWGROUP(drive)->rq) == NULL || drive == NULL)
+	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
 		return;
 	/* retry only "normal" I/O: */
 	if (rq->cmd == IDE_DRIVE_CMD) {
@@ -784,7 +868,7 @@
 void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
 {
 	ide_set_handler (drive, handler, WAIT_CMD);
-	OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
+	OUT_BYTE(drive->ctl,IDE_CONTROL_REG);	/* clear nIEN */
 	OUT_BYTE(nsect,IDE_NSECTOR_REG);
 	OUT_BYTE(cmd,IDE_COMMAND_REG);
 }
@@ -799,7 +883,7 @@
 	byte stat = GET_STAT();
 	int retries = 10;
 
-	/* ide_sti(); HACK */
+	ide__sti();	/* local CPU only */
 	if ((stat & DRQ_STAT) && args && args[3]) {
 		byte io_32bit = drive->io_32bit;
 		drive->io_32bit = 0;
@@ -857,17 +941,17 @@
 
 	udelay(1);	/* spec allows drive 400ns to assert "BUSY" */
 	if ((stat = GET_STAT()) & BUSY_STAT) {
-		__save_flags(flags);
-		/* ide_sti(); HACK */
+		__save_flags(flags);	/* local CPU only */
+		ide__sti();		/* local CPU only */
 		timeout += jiffies;
 		while ((stat = GET_STAT()) & BUSY_STAT) {
 			if (0 < (signed long)(jiffies - timeout)) {
-				__restore_flags(flags);
+				__restore_flags(flags);	/* local CPU only */
 				ide_error(drive, "status timeout", stat);
 				return 1;
 			}
 		}
-		__restore_flags(flags);
+		__restore_flags(flags);	/* local CPU only */
 	}
 	udelay(1);	/* allow status to settle, then read it again */
 	if (OK_STAT((stat = GET_STAT()), good, bad))
@@ -909,17 +993,18 @@
 }
 
 /*
- * do_request() initiates handling of a new I/O request
+ * start_request() initiates handling of a new I/O request
  */
-static inline void do_request (ide_hwgroup_t *hwgroup, ide_hwif_t *hwif, ide_drive_t *drive)
+static inline void start_request (ide_drive_t *drive)
 {
 	unsigned long block, blockend;
 	struct request *rq = drive->queue;
 	unsigned int minor = MINOR(rq->rq_dev), unit = minor >> PARTN_BITS;
+	ide_hwif_t *hwif = HWIF(drive);
 
-	/* ide_sti(); HACK */
+	ide__sti();	/* local CPU only */
 #ifdef DEBUG
-	printk("%s: do_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
+	printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
 #endif
 	if (unit >= MAX_DRIVES) {
 		printk("%s: bad device number: %s\n", hwif->name, kdevname(rq->rq_dev));
@@ -946,15 +1031,11 @@
 #if (DISK_RECOVERY_TIME > 0)
 	while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME);
 #endif
-
-	hwgroup->hwif = hwif;
-	hwgroup->drive = drive;
 	SELECT_DRIVE(hwif, drive);
 	if (ide_wait_stat(drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) {
 		printk("%s: drive not ready for command\n", drive->name);
 		return;
 	}
-
 	if (!drive->special.all) {
 		if (rq->cmd == IDE_DRIVE_CMD) {
 			execute_drive_cmd(drive, rq);
@@ -973,7 +1054,7 @@
 	if (drive->driver != NULL)
 		DRIVER(drive)->end_request(0, HWGROUP(drive));
 	else
-		ide_end_request(0, hwgroup);
+		ide_end_request(0, HWGROUP(drive));
 }
 
 /*
@@ -1000,21 +1081,19 @@
 	best = NULL;
 	drive = hwgroup->drive;
 	do {
-		if (!drive->queue)
-			continue;
-		if (drive->sleep && 0 < (signed long)(drive->sleep - jiffies))
-			continue;
-		if (!best) {
-			best = drive;
-			continue;
+		if (drive->queue && (!drive->sleep || 0 <= (signed long)(jiffies - drive->sleep))) {
+			if (!best
+			 || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
+			 || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
+			{
+				struct blk_dev_struct *bdev = &blk_dev[HWIF(drive)->major];
+				if (bdev->current_request != &bdev->plug)
+					best = drive;
+			}
 		}
-		if (drive->sleep && (!best->sleep || drive->sleep < best->sleep))
-			best = drive;
-		if (!best->sleep && WAKEUP(drive) < WAKEUP(best))
-			best = drive;
 	} while ((drive = drive->next) != hwgroup->drive);
-	if (best != hwgroup->drive && best && best->service_time > WAIT_MIN_SLEEP && !best->sleep && best->nice1) {
-		long t = (signed) (WAKEUP(best) - jiffies);	/* BUGGY? */
+	if (best && best->nice1 && !best->sleep && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
+		long t = (signed long)(WAKEUP(best) - jiffies);
 		if (t >= WAIT_MIN_SLEEP) {
 			/*
 			 * We *may* have some time to spare, but first let's see if
@@ -1022,9 +1101,10 @@
 			 */
 			drive = best->next;
 			do {
-				if (drive->sleep)	/* this drive tried to be nice to us */
-					continue;
-				if (WAKEUP(drive) > (jiffies - best->service_time) && WAKEUP(drive) < (jiffies + t)) {  /* BUGGY? */
+				if (!drive->sleep
+				 && 0 < (signed long)(WAKEUP(drive) - (jiffies - best->service_time))
+				 && 0 < (signed long)((jiffies + t) - WAKEUP(drive)))
+				{
 					ide_stall_queue(best, IDE_MIN(t, 10 * WAIT_MIN_SLEEP));
 					goto repeat;
 				}
@@ -1034,33 +1114,6 @@
 	return best;
 }
 
-static inline void ide_leave_hwgroup (ide_hwgroup_t *hwgroup)
-{
-	ide_drive_t *drive = hwgroup->drive;
-	unsigned long sleep = 0;
-
-	hwgroup->rq = NULL;
-	do {
-		blk_dev[HWIF(drive)->major].current_request = NULL;
-		if (!drive->sleep)
-			continue;
-		if (!sleep) {
-			sleep = drive->sleep;
-			continue;
-		}
-		if (drive->sleep < sleep)
-			sleep = drive->sleep;
-	} while ((drive = drive->next) != hwgroup->drive);
-	if (sleep) {
-		if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) 
-			sleep = jiffies + WAIT_MIN_SLEEP;
-		hwgroup->timer.expires = sleep;
-		add_timer(&hwgroup->timer);
-	} else	/* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_scheduler? */
-		ide_release_lock(&ide_lock);
-	hwgroup->active = 0;
-}
-
 /*
  * The driver enables interrupts as much as possible.  In order to do this,
  * (a) the device-interrupt is always masked before entry, and
@@ -1075,30 +1128,68 @@
  * tolerance for latency during I/O.  For devices which don't suffer from
  * this problem (most don't), the unmask flag can be set using the "hdparm"
  * utility, to permit other interrupts during data/cmd transfers.
+ *
+ * Caller must have already acquired spinlock using *spinflags 
+ *
  */
-void ide_do_request (ide_hwgroup_t *hwgroup)
+static void ide_do_request (ide_hwgroup_t *hwgroup, unsigned long *hwgroup_flags, int masked_irq)
 {
-	__cli();	/* paranoia */
-	if (hwgroup->handler != NULL) {
-		printk("%s: EEeekk!! handler not NULL in ide_do_request()\n", hwgroup->hwif->name);
-		return;
-	}
-	do {
-		ide_drive_t *drive = choose_drive(hwgroup);
-		if (drive != NULL) {
-			ide_hwif_t *hwif = HWIF(drive);
-			if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif)
-				OUT_BYTE(hwgroup->drive->ctl|2, hwgroup->hwif->io_ports[IDE_CONTROL_OFFSET]);
-			drive->sleep = 0;
-			blk_dev[hwif->major].current_request = hwgroup->rq = drive->queue;
-			drive->service_start = jiffies;
-			do_request(hwgroup, hwif, drive);
-			__cli();
-		} else {
-			ide_leave_hwgroup(hwgroup);	/* no work left for this hwgroup */
+	struct blk_dev_struct *bdev;
+	ide_drive_t	*drive;
+	ide_hwif_t	*hwif;
+	unsigned long	io_flags;
+
+	hwgroup->busy = 1;
+	while (hwgroup->handler == NULL) {
+		IDE_SPIN_LOCK_IRQSAVE("ide_do_request1", &io_request_lock, io_flags);
+		drive = choose_drive(hwgroup);
+		if (drive == NULL) {
+			unsigned long sleep = 0;
+
+			hwgroup->rq = NULL;
+			drive = hwgroup->drive;
+			do {
+				bdev = &blk_dev[HWIF(drive)->major];
+				if (bdev->current_request != &bdev->plug)	/* FIXME: this will do for now */
+					bdev->current_request = NULL;		/* (broken since patch-2.1.15) */
+				if (drive->sleep && (!sleep || 0 < (signed long)(sleep - drive->sleep)))
+					sleep = drive->sleep;
+			} while ((drive = drive->next) != hwgroup->drive);
+			IDE_SPIN_UNLOCK_IRQRESTORE("ide_do_request2", &io_request_lock, io_flags);
+			if (sleep) {
+				if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) 
+					sleep = jiffies + WAIT_MIN_SLEEP;
+				hwgroup->timer.expires = sleep;
+				add_timer(&hwgroup->timer);
+			} else {
+				/* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_scheduler? */
+				ide_release_lock(&ide_lock);	/* for atari only */
+			}
+			hwgroup->busy = 0;
 			return;
 		}
-	} while (hwgroup->handler == NULL);
+		hwif = HWIF(drive);
+		if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif) /* set nIEN for previous hwif */
+			OUT_BYTE(hwgroup->drive->ctl|2, hwgroup->hwif->io_ports[IDE_CONTROL_OFFSET]);
+		hwgroup->hwif = hwif;
+		hwgroup->drive = drive;
+		drive->sleep = 0;
+		drive->service_start = jiffies;
+
+		bdev = &blk_dev[hwif->major];
+		if (bdev->current_request == &bdev->plug)	/* FIXME: paranoia */
+			printk("%s: Huh? nuking plugged queue\n", drive->name);
+		bdev->current_request = hwgroup->rq = drive->queue;
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_do_request3", &io_request_lock, io_flags);
+
+		if (hwif->irq != masked_irq)
+			disable_irq(hwif->irq);
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_do_request4", &hwgroup->spinlock, *hwgroup_flags);
+		start_request(drive);
+		IDE_SPIN_LOCK_IRQSAVE("ide_do_request5", &hwgroup->spinlock, *hwgroup_flags);
+		if (hwif->irq != masked_irq)
+			enable_irq(hwif->irq);
+	}
 }
 
 /*
@@ -1106,100 +1197,136 @@
  */
 struct request **ide_get_queue (kdev_t dev)
 {
-	struct blk_dev_struct *bdev = blk_dev + MAJOR(dev);
-	ide_hwif_t *hwif = bdev->data;
+	ide_hwif_t *hwif = (ide_hwif_t *)blk_dev[MAJOR(dev)].data;
 
 	return &hwif->drives[DEVICE_NR(dev) & 1].queue;
 }
 
 /*
- * do_hwgroup_request() invokes ide_do_request() after first masking
- * all possible interrupts for the current hwgroup.  This prevents race
- * conditions in the event that an unexpected interrupt occurs while
- * we are in the driver.
- *
- * Note that the io-request lock will guarantee that the driver never gets
- * re-entered even on another interrupt level, so we no longer need to
- * mask the irq's.
+ * do_hwgroup_request() invokes ide_do_request() after claiming hwgroup->busy.
  */
-static void do_hwgroup_request (ide_hwgroup_t *hwgroup)
+static void do_hwgroup_request (const char *msg, ide_hwgroup_t *hwgroup)
 {
-	if (hwgroup->handler == NULL) {
-		del_timer(&hwgroup->timer);
-		ide_get_lock(&ide_lock, ide_intr, hwgroup);
-		hwgroup->active = 1;
-		ide_do_request (hwgroup);
+	unsigned long flags;
+
+	IDE_SPIN_LOCK_IRQSAVE(msg, &hwgroup->spinlock, flags);
+	if (hwgroup->busy) {
+		IDE_SPIN_UNLOCK_IRQRESTORE(msg, &hwgroup->spinlock, flags);
+		return;
 	}
+	del_timer(&hwgroup->timer);
+	ide_get_lock(&ide_lock, ide_intr, hwgroup);	/* for atari only */
+	ide_do_request(hwgroup, &flags, 0);
+	IDE_SPIN_UNLOCK_IRQRESTORE(msg, &hwgroup->spinlock, flags);
+}
+
+/*
+ * As of linux-2.1.95, ll_rw_blk.c invokes our do_idex_request()
+ * functions with the io_request_spinlock already grabbed.
+ * Since we need to do our own spinlock's internally,
+ * on paths that don't necessarily originate through the
+ * do_idex_request() path.
+ *
+ * We have to undo the spinlock on entry, and restore it again on exit.
+ * Fortunately, this is mostly a nop for non-SMP kernels.
+ */
+static inline void unlock_do_hwgroup_request (ide_hwgroup_t *hwgroup)
+{
+	IDE_SPIN_UNLOCK("unlock_do_hwgroup_request", &io_request_lock);
+	do_hwgroup_request ("from unlock_do_hwgroup_request", hwgroup);
+	IDE_SPIN_LOCK_IRQ("unlock_do_hwgroup_request", &io_request_lock);
 }
 
-void do_ide0_request (void)	/* invoked with __cli() */
+void do_ide0_request (void)
 {
-	do_hwgroup_request (ide_hwifs[0].hwgroup);
+	unlock_do_hwgroup_request (ide_hwifs[0].hwgroup);
 }
 
 #if MAX_HWIFS > 1
-void do_ide1_request (void)	/* invoked with __cli() */
+void do_ide1_request (void)
 {
-	do_hwgroup_request (ide_hwifs[1].hwgroup);
+	unlock_do_hwgroup_request (ide_hwifs[1].hwgroup);
 }
 #endif /* MAX_HWIFS > 1 */
 
 #if MAX_HWIFS > 2
-void do_ide2_request (void)	/* invoked with __cli() */
+void do_ide2_request (void)
 {
-	do_hwgroup_request (ide_hwifs[2].hwgroup);
+	unlock_do_hwgroup_request (ide_hwifs[2].hwgroup);
 }
 #endif /* MAX_HWIFS > 2 */
 
 #if MAX_HWIFS > 3
-void do_ide3_request (void)	/* invoked with __cli() */
+void do_ide3_request (void)
 {
-	do_hwgroup_request (ide_hwifs[3].hwgroup);
+	unlock_do_hwgroup_request (ide_hwifs[3].hwgroup);
 }
 #endif /* MAX_HWIFS > 3 */
 
 #if MAX_HWIFS > 4
-void do_ide4_request (void)	/* invoked with cli() */
+void do_ide4_request (void)
 {
-	do_hwgroup_request (ide_hwifs[4].hwgroup);
+	unlock_do_hwgroup_request (ide_hwifs[4].hwgroup);
 }
 #endif /* MAX_HWIFS > 4 */
 
 #if MAX_HWIFS > 5
-void do_ide5_request (void)	/* invoked with cli() */
+void do_ide5_request (void)
 {
-	do_hwgroup_request (ide_hwifs[5].hwgroup);
+	unlock_do_hwgroup_request (ide_hwifs[5].hwgroup);
 }
 #endif /* MAX_HWIFS > 5 */
 
+static void start_next_request (ide_hwgroup_t *hwgroup, int masked_irq)
+{
+	unsigned long	flags;
+	ide_drive_t	*drive;
+
+	IDE_SPIN_LOCK_IRQSAVE("start_next_request", &hwgroup->spinlock, flags);
+	if (hwgroup->handler != NULL) {
+		IDE_SPIN_UNLOCK_IRQRESTORE("start_next_request", &hwgroup->spinlock, flags);
+		return;
+	}
+	drive = hwgroup->drive;
+	set_recovery_timer(HWIF(drive));
+	drive->service_time = jiffies - drive->service_start;
+	ide_do_request(hwgroup, &flags, masked_irq);
+	IDE_SPIN_UNLOCK_IRQRESTORE("start_next_request", &hwgroup->spinlock, flags);
+}
+
 void ide_timer_expiry (unsigned long data)
 {
 	ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
-	ide_drive_t   *drive   = hwgroup->drive;
+	ide_drive_t   *drive;
 	ide_handler_t *handler;
 	unsigned long flags;
 
-	__save_flags(flags);
-	__cli();
-
-	if ((handler = hwgroup->handler) != NULL) {
-		hwgroup->handler = NULL;
-		if (hwgroup->poll_timeout != 0)	/* polling in progress? */
-			handler(drive);
-		else {				/* abort the operation */
-			if (hwgroup->hwif->dmaproc)
-				(void) hwgroup->hwif->dmaproc (ide_dma_end, drive);
-			ide_error(drive, "irq timeout", GET_STAT());
-		}
-		__cli();
-		if (hwgroup->handler == NULL) {
-			set_recovery_timer(HWIF(drive));
-			drive->service_time = jiffies - drive->service_start;
-			do_hwgroup_request (hwgroup);
-		}
-	} else
-		do_hwgroup_request (hwgroup);
-	__restore_flags(flags);
+	IDE_SPIN_LOCK_IRQSAVE("ide_timer_expiry1", &hwgroup->spinlock, flags);
+	drive = hwgroup->drive;
+	if ((handler = hwgroup->handler) == NULL) {
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_timer_expiry2", &hwgroup->spinlock, flags);
+		do_hwgroup_request("timer do_hwgroup_request", hwgroup);
+		return;
+	}
+	hwgroup->busy = 1;	/* should already be "1" */
+	hwgroup->handler = NULL;
+	if (hwgroup->poll_timeout != 0) {	/* polling in progress? */
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_timer_expiry3", &hwgroup->spinlock, flags);
+		handler(drive);
+	} else if (drive_is_ready(drive)) {
+		printk("%s: lost interrupt\n", drive->name);
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_timer_expiry4", &hwgroup->spinlock, flags);
+		handler(drive);
+	} else {
+		if (drive->waiting_for_dma) {
+			(void) hwgroup->hwif->dmaproc(ide_dma_end, drive);
+			printk("%s: timeout waiting for DMA\n", drive->name);
+		}
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_timer_expiry5", &hwgroup->spinlock, flags);
+		ide_error(drive, "irq timeout", GET_STAT());
+	}
+	del_timer(&hwgroup->timer);
+	start_next_request(hwgroup, 0);
 }
 
 /*
@@ -1238,75 +1365,78 @@
 			stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
 			if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
 				/* Try to not flood the console with msgs */
-				static unsigned long last_msgtime = 0;
+				static unsigned long last_msgtime = 0, count = 0;
+				++count;
 				if (0 < (signed long)(jiffies - (last_msgtime + HZ))) {
 					last_msgtime = jiffies;
-					printk("%s%s: unexpected interrupt, status=0x%02x\n",
-					 hwif->name, (hwif->next == hwgroup->hwif) ? "" : "(?)", stat);
+					printk("%s%s: unexpected interrupt, status=0x%02x, count=%ld\n",
+					 hwif->name, (hwif->next == hwgroup->hwif) ? "" : "(?)", stat, count);
 				}
 			}
 		}
 	} while ((hwif = hwif->next) != hwgroup->hwif);
 }
-
-#ifdef __sparc_v9__
-#define IDE_IRQ_EQUAL(irq1, irq2)	(1)
-#else
-#define IDE_IRQ_EQUAL(irq1, irq2)	((irq1) == (irq2))
-#endif
-
-static void do_ide_intr (int irq, void *dev_id, struct pt_regs *regs)
-{
-	ide_hwgroup_t *hwgroup = dev_id;
-	ide_hwif_t *hwif = hwgroup->hwif;
-	ide_handler_t *handler;
-
-	if (!ide_ack_intr (hwif->io_ports[IDE_STATUS_OFFSET], hwif->io_ports[IDE_IRQ_OFFSET]))
-		return;
-
-	if (IDE_IRQ_EQUAL(irq, hwif->irq)
-	    && (handler = hwgroup->handler) != NULL) {
-		ide_drive_t *drive = hwgroup->drive;
-#if 1  /* temporary, remove later -- FIXME */
-		{
-			struct request *rq = hwgroup->rq;
-			if (rq != NULL
-			    &&( MAJOR(rq->rq_dev) != HWIF(drive)->major
-			    || (MINOR(rq->rq_dev) >> PARTN_BITS) != drive->select.b.unit))
-			{
-				printk("ide_intr: got IRQ from wrong device: email mlord@pobox.com!!\n");
-				return;
-			}
-		}
-#endif /* temporary */
-		hwgroup->handler = NULL;
-		del_timer(&(hwgroup->timer));
-		/* if (drive->unmask)
-			ide_sti(); HACK */
-		handler(drive);
-		/* this is necessary, as next rq may be different irq */
-		if (hwgroup->handler == NULL) {
-			set_recovery_timer(HWIF(drive));
-			drive->service_time = jiffies - drive->service_start;
-			ide_do_request(hwgroup);
-		}
-	} else {
-		unexpected_intr(irq, hwgroup);
-	}
-	__cli();
-	hwif = hwgroup->hwif;
-}
-
 /*
  * entry point for all interrupts, caller does __cli() for us
  */
 void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned long flags;
+	ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
+	ide_hwif_t *hwif;
+	ide_drive_t *drive;
+	ide_handler_t *handler;
 
-	spin_lock_irqsave(&io_request_lock, flags);
-	do_ide_intr(irq, dev_id, regs);
-	spin_unlock_irqrestore(&io_request_lock, flags);
+	__cli();	/* local CPU only */
+	IDE_SPIN_LOCK_IRQSAVE("ide_intr1", &hwgroup->spinlock, flags);
+	hwif = hwgroup->hwif;
+	if ((handler = hwgroup->handler) == NULL || hwgroup->poll_timeout != 0) {
+		/*
+		 * Not expecting an interrupt from this drive.
+		 * That means this could be:
+		 *	(1) an interrupt from another PCI device
+		 *	sharing the same PCI INT# as us.
+		 * or	(2) a drive just entered sleep or standby mode,
+		 *	and is interrupting to let us know.
+		 * or	(3) a spurious interrupt of unknown origin.
+		 *
+		 * For PCI, we cannot tell the difference,
+		 * so in that case we just ignore it and hope it goes away.
+		 */
+#ifdef CONFIG_BLK_DEV_IDEPCI
+		if (IDE_PCI_DEVID_EQ(hwif->pci_devid, IDE_PCI_DEVID_NULL))
+#endif	/* CONFIG_BLK_DEV_IDEPCI */
+		{
+			/*
+			 * Probably not a shared PCI interrupt,
+			 * so we can safely try to do something about it:
+			 */
+			(void)ide_ack_intr(hwif->io_ports[IDE_STATUS_OFFSET], hwif->io_ports[IDE_IRQ_OFFSET]);
+			unexpected_intr(irq, hwgroup);
+		}
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_intr2", &hwgroup->spinlock, flags);
+		return;
+	}
+	drive = hwgroup->drive;
+	if (!drive || !drive_is_ready(drive)) {
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_intr3", &hwgroup->spinlock, flags);
+		return;
+	}
+	hwgroup->handler = NULL;
+	(void)ide_ack_intr(hwif->io_ports[IDE_STATUS_OFFSET], hwif->io_ports[IDE_IRQ_OFFSET]);
+	del_timer(&(hwgroup->timer));
+	IDE_SPIN_UNLOCK_IRQRESTORE("ide_intr4", &hwgroup->spinlock, flags);
+	if (drive->unmask)
+		ide__sti();	/* local CPU only */
+	handler(drive);		/* service this interrupt, may set handler for next interrupt */
+	/*
+	 * Note that handler() may have set things up for another
+	 * interrupt to occur soon, but it cannot happen until
+	 * we exit from this routine, because it will be the
+	 * same irq as is currently being serviced here,
+	 * and Linux won't allow another (on any CPU) until we return.
+	 */
+	start_next_request(hwgroup, hwif->irq);
 }
 
 /*
@@ -1390,10 +1520,8 @@
 	if (action == ide_wait)
 		rq->sem = &sem;
 
-	__save_flags(flags);
-	__cli();
+	IDE_SPIN_LOCK_IRQSAVE("ide_do_drive_cmd", &io_request_lock, flags);
 	cur_rq = drive->queue;
-
 	if (cur_rq == NULL || action == ide_preempt) {
 		rq->next = cur_rq;
 		drive->queue = rq;
@@ -1407,13 +1535,13 @@
 		rq->next = cur_rq->next;
 		cur_rq->next = rq;
 	}
-	if (!hwgroup->active) {
-		do_hwgroup_request(hwgroup);
-		__cli();
-	}
-	if (action == ide_wait  && rq->rq_status != RQ_INACTIVE)
+	IDE_SPIN_UNLOCK_IRQRESTORE("ide_do_drive_cmd", &io_request_lock, flags);
+	do_hwgroup_request("drive_cmd do_hwgroup_request", hwgroup);
+	save_flags(flags);	/* all CPUs; overkill? */
+	cli();			/* all CPUs; overkill? */
+	if (action == ide_wait && rq->rq_status != RQ_INACTIVE)
 		down(&sem);	/* wait for it to be serviced */
-	__restore_flags(flags);
+	restore_flags(flags);	/* all CPUs; overkill? */
 	return rq->errors ? -EIO : 0;	/* return -EIO if errors */
 }
 
@@ -1428,6 +1556,7 @@
 int ide_revalidate_disk(kdev_t i_rdev)
 {
 	ide_drive_t *drive;
+	ide_hwgroup_t *hwgroup;
 	unsigned int p, major, minor;
 	long flags;
 
@@ -1435,15 +1564,15 @@
 		return -ENODEV;
 	major = MAJOR(i_rdev);
 	minor = drive->select.b.unit << PARTN_BITS;
-	__save_flags(flags);
-	__cli();
+	hwgroup = HWGROUP(drive);
+	IDE_SPIN_LOCK_IRQSAVE("ide_revalidate_disk", &hwgroup->spinlock, flags);
 	if (drive->busy || (drive->usage > 1)) {
-		__restore_flags(flags);
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_revalidate_disk", &hwgroup->spinlock, flags);
 		return -EBUSY;
 	};
 	drive->busy = 1;
 	MOD_INC_USE_COUNT;
-	__restore_flags(flags);
+	IDE_SPIN_UNLOCK_IRQRESTORE("ide_revalidate_disk", &hwgroup->spinlock, flags);
 
 	for (p = 0; p < (1<<PARTN_BITS); ++p) {
 		if (drive->part[p].nr_sects > 0) {
@@ -1589,8 +1718,8 @@
 
 	if (index >= MAX_HWIFS)
 		return;
-	__save_flags(flags);
-	__cli();
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
 	hwif = &ide_hwifs[index];
 	if (!hwif->present)
 		goto abort;
@@ -1680,7 +1809,7 @@
 	}
 	init_hwif_data (index);	/* restore hwif data to pristine status */
 abort:
-	__restore_flags(flags);
+	restore_flags(flags);	/* all CPUs */
 }
 
 int ide_register (int arg1, int arg2, int irq)
@@ -1719,7 +1848,7 @@
 	return hwif->present ? index : -1;
 }
 
-void ide_add_setting(ide_drive_t *drive, char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
+void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
 {
 	ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
 
@@ -1798,38 +1927,63 @@
 
 int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting)
 {
-	if (!(setting->rw & SETTING_READ))
-		return -EINVAL;
-	switch(setting->data_type) {
-		case TYPE_BYTE:
-			return *((u8 *) setting->data);
-		case TYPE_SHORT:
-			return *((u16 *) setting->data);
-		case TYPE_INT:
-		case TYPE_INTA:
-			return *((u32 *) setting->data);
-		default:
-			return -EINVAL;
+	int		val = -EINVAL;
+	unsigned long	flags;
+
+	if ((setting->rw & SETTING_READ)) {
+		IDE_SPIN_LOCK_IRQSAVE("ide_read_setting", &HWGROUP(drive)->spinlock, flags);
+		switch(setting->data_type) {
+			case TYPE_BYTE:
+				val = *((u8 *) setting->data);
+				break;
+			case TYPE_SHORT:
+				val = *((u16 *) setting->data);
+				break;
+			case TYPE_INT:
+			case TYPE_INTA:
+				val = *((u32 *) setting->data);
+				break;
+		}
+		IDE_SPIN_UNLOCK_IRQRESTORE("ide_read_setting", &HWGROUP(drive)->spinlock, flags);
+	}
+	return val;
+}
+
+int ide_spin_wait_hwgroup (const char *msg, ide_drive_t *drive, unsigned long *flags)
+{
+	ide_hwgroup_t *hwgroup = HWGROUP(drive);
+	unsigned long timeout = jiffies + (3 * HZ);
+
+	IDE_SPIN_LOCK_IRQSAVE(msg, &hwgroup->spinlock, *flags);
+	while (hwgroup->busy) {
+		IDE_SPIN_UNLOCK_IRQRESTORE(msg, &hwgroup->spinlock, *flags);
+		__sti();	/* local CPU only; needed for jiffies */
+		if (0 < (signed long)(jiffies - timeout)) {
+			printk("%s: %s: channel busy\n", drive->name, msg);
+			return -EBUSY;
+		}
+		IDE_SPIN_LOCK_IRQSAVE(msg, &hwgroup->spinlock, *flags);
 	}
+	return 0;
 }
 
 int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val)
 {
 	unsigned long flags;
-	int i, rc = 0;
+	int i;
 	u32 *p;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 	if (!(setting->rw & SETTING_WRITE))
 		return -EPERM;
 	if (val < setting->min || val > setting->max)
 		return -EINVAL;
-	__save_flags(flags);
-	__cli();
 	if (setting->set)
-		rc = setting->set(drive, val);
-	else switch (setting->data_type) {
+		return setting->set(drive, val);
+	if (ide_spin_wait_hwgroup("ide_write_settings", drive, &flags))
+		return -EBUSY;
+	switch (setting->data_type) {
 		case TYPE_BYTE:
 			*((u8 *) setting->data) = val;
 			break;
@@ -1845,8 +1999,8 @@
 				*p = val;
 			break;
 	}
-	__restore_flags(flags);
-	return rc;
+	IDE_SPIN_UNLOCK_IRQRESTORE("ide_write_setting4", &HWGROUP(drive)->spinlock, flags);
+	return 0;
 }
 
 static int set_io_32bit(ide_drive_t *drive, int arg)
@@ -1956,7 +2110,7 @@
 			return 0;
 		}
 		case BLKFLSBUF:
-			if (!suser()) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			fsync_dev(inode->i_rdev);
 			invalidate_buffers(inode->i_rdev);
 			return 0;
@@ -1965,21 +2119,17 @@
 			return put_user(drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects, (long *) arg);
 
 		case BLKRRPART: /* Re-read partition tables */
-			if (!suser()) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			return ide_revalidate_disk(inode->i_rdev);
 
+		case HDIO_OBSOLETE_IDENTITY:
 		case HDIO_GET_IDENTITY:
 			if (MINOR(inode->i_rdev) & PARTN_MASK)
 				return -EINVAL;
 			if (drive->id == NULL)
 				return -ENOMSG;
-#if 0
-			if (copy_to_user((char *)arg, (char *)drive->id, sizeof(*drive->id)))
+			if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))
 				return -EFAULT;
-#else
-			if (copy_to_user((char *)arg, (char *)drive->id, 142))
-				return -EFAULT;
-#endif
 			return 0;
 
 		case HDIO_GET_NICE:
@@ -1993,7 +2143,7 @@
 		{
 			byte args[4], *argbuf = args;
 			int argsize = 4;
-			if (!suser()) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if (NULL == (void *) arg)
 				return ide_do_drive_cmd(drive, &rq, ide_wait);
 			if (copy_from_user(args, (void *)arg, 4))
@@ -2016,7 +2166,7 @@
 		case HDIO_SCAN_HWIF:
 		{
 			int args[3];
-			if (!suser()) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if (copy_from_user(args, (void *)arg, 3 * sizeof(int)))
 				return -EFAULT;
 			if (ide_register(args[0], args[1], args[2]) == -1)
@@ -2024,7 +2174,7 @@
 			return 0;
 		}
 		case HDIO_SET_NICE:
-			if (!suser()) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if (drive->driver == NULL)
 				return -EPERM;
 			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
@@ -2311,7 +2461,7 @@
 				goto bad_option;	/* chipset already specified */
 			if (i <= -7 && hw != 0)
 				goto bad_hwif;		/* chipset drivers are for "ide0=" only */
-			if (ide_hwifs[hw^1].chipset != ide_unknown)
+			if (i <= -7 && ide_hwifs[hw^1].chipset != ide_unknown)
 				goto bad_option;	/* chipset for 2nd port already specified */
 			printk("\n");
 		}
@@ -2528,12 +2678,6 @@
 			ide_probe_for_rz100x();
 		}
 #endif /* CONFIG_BLK_DEV_RZ1000 */
-#ifdef CONFIG_BLK_DEV_SL82C105
-		{
-			extern void ide_probe_for_sl82c105(void);
-			ide_probe_for_sl82c105();
-		}
-#endif /* CONFIG_BLK_DEV_SL82C105 */
 #endif /* CONFIG_BLK_DEV_IDEPCI */
 	}
 #endif /* CONFIG_PCI */
@@ -2560,21 +2704,21 @@
 	probe_for_hwifs ();
 
 #ifdef CONFIG_BLK_DEV_IDE
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
-		ide_get_lock(&ide_lock, NULL, NULL);
+		ide_get_lock(&ide_lock, NULL, NULL);	/* for atari only */
 		disable_irq(ide_hwifs[0].irq);
 	}
-#endif /* __mc68000__ */
+#endif /* __mc68000__ || CONFIG_APUS */
 
 	(void) ideprobe_init();
 
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
 		enable_irq(ide_hwifs[0].irq);
-		ide_release_lock(&ide_lock);
+		ide_release_lock(&ide_lock);	/* for atari only */
 	}
-#endif /* __mc68000__ */
+#endif /* __mc68000__ || CONFIG_APUS */
 #endif /* CONFIG_BLK_DEV_IDE */
 
 #ifdef CONFIG_PROC_FS
@@ -2705,16 +2849,15 @@
 {
 	unsigned long flags;
 	
-	__save_flags(flags);
-	__cli();
-	if (version != IDE_SUBDRIVER_VERSION || !drive->present || drive->driver != NULL ||
-	    drive->busy || drive->usage) {
-	    	__restore_flags(flags);
+	save_flags(flags);		/* all CPUs */
+	cli();				/* all CPUs */
+	if (version != IDE_SUBDRIVER_VERSION || !drive->present || drive->driver != NULL || drive->busy || drive->usage) {
+		restore_flags(flags);	/* all CPUs */
 		return 1;
 	}
 	drive->driver = driver;
 	setup_driver_defaults(drive);
-	__restore_flags(flags);
+	restore_flags(flags);		/* all CPUs */
 	if (drive->autotune != 2) {
 		if (driver->supports_dma && HWIF(drive)->dmaproc != NULL)
 			(void) (HWIF(drive)->dmaproc(ide_dma_check, drive));
@@ -2733,10 +2876,10 @@
 {
 	unsigned long flags;
 	
-	__save_flags(flags);
-	__cli();
+	save_flags(flags);		/* all CPUs */
+	cli();				/* all CPUs */
 	if (drive->usage || drive->busy || drive->driver == NULL || DRIVER(drive)->busy) {
-		__restore_flags(flags);
+		restore_flags(flags);	/* all CPUs */
 		return 1;
 	}
 #ifdef CONFIG_PROC_FS
@@ -2745,7 +2888,7 @@
 #endif
 	auto_remove_settings(drive);
 	drive->driver = NULL;
-	__restore_flags(flags);
+	restore_flags(flags);		/* all CPUs */
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ide.h linux/drivers/block/ide.h
--- v2.1.99/linux/drivers/block/ide.h	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/ide.h	Thu May  7 18:14:38 1998
@@ -204,26 +204,28 @@
 	unsigned long service_start;	/* time we started last request */
 	unsigned long service_time;	/* service time of last request */
 	special_t	special;	/* special action flags */
+	byte     keep_settings;		/* restore settings after drive reset */
+	byte     using_dma;		/* disk is using dma for read/write */
+	byte     waiting_for_dma;	/* dma currently in progress */
+	byte     unmask;		/* flag: okay to unmask other irqs */
+	byte     slow;			/* flag: slow data port */
+	byte     bswap;			/* flag: byte swap data */
+	byte     dsc_overlap;		/* flag: DSC overlap */
+	byte     nice1;			/* flag: give potential excess bandwidth */
 	unsigned present	: 1;	/* drive is physically present */
 	unsigned noprobe 	: 1;	/* from:  hdx=noprobe */
-	byte     keep_settings;		/* restore settings after drive reset */
 	unsigned busy		: 1;	/* currently doing revalidate_disk() */
 	unsigned removable	: 1;	/* 1 if need to do check_media_change */
-	byte     using_dma;		/* disk is using dma for read/write */
 	unsigned forced_geom	: 1;	/* 1 if hdx=c,h,s was given at boot */
-	byte     unmask;		/* flag: okay to unmask other irqs */
 	unsigned no_unmask	: 1;	/* disallow setting unmask bit */
 	unsigned no_io_32bit	: 1;	/* disallow enabling 32bit I/O */
 	unsigned nobios		: 1;	/* flag: do not probe bios for drive */
-	byte     slow;			/* flag: slow data port */
-	unsigned autotune	: 2;	/* 1=autotune, 2=noautotune, 0=default */
 	unsigned revalidate	: 1;	/* request revalidation */
-	byte     bswap;			/* flag: byte swap data */
-	byte     dsc_overlap;		/* flag: DSC overlap */
 	unsigned atapi_overlap	: 1;	/* flag: ATAPI overlap (not supported) */
 	unsigned nice0		: 1;	/* flag: give obvious excess bandwidth */
-	byte     nice1;			/* flag: give potential excess bandwidth */
 	unsigned nice2		: 1;	/* flag: give a share in our own bandwidth */
+	unsigned doorlocking	: 1;	/* flag: for removable only: door lock/unlock works */
+	unsigned autotune	: 2;	/* 1=autotune, 2=noautotune, 0=default */
 #if FAKE_FDISK_FOR_EZDRIVE
 	unsigned remap_0_to_1	: 1;	/* flag: partitioned with ezdrive */
 #endif /* FAKE_FDISK_FOR_EZDRIVE */
@@ -270,7 +272,8 @@
  * should either try again later, or revert to PIO for the current request.
  */
 typedef enum {	ide_dma_read,	ide_dma_write,	ide_dma_begin,	ide_dma_end,
-		ide_dma_check,	ide_dma_on,	ide_dma_off,	ide_dma_off_quietly
+		ide_dma_check,	ide_dma_on,	ide_dma_off,	ide_dma_off_quietly,
+		ide_dma_test_irq
 	} ide_dma_action_t;
 
 typedef int (ide_dmaproc_t)(ide_dma_action_t, ide_drive_t *);
@@ -340,7 +343,7 @@
 	unsigned	reset      : 1;	/* reset after probe */
 	unsigned	no_autodma : 1;	/* don't automatically enable DMA at boot */
 	byte		channel;	/* for dual-port chips: 0=primary, 1=secondary */
-	struct		pci_dev *pci_dev; /* for pci chipsets */
+	struct pci_dev	*pci_dev;	/* for pci chipsets */
 	ide_pci_devid_t	pci_devid;	/* for pci chipsets: {VID,DID} */
 #if (DISK_RECOVERY_TIME > 0)
 	unsigned long	last_time;	/* time when previous rq was done */
@@ -353,14 +356,15 @@
 typedef void (ide_handler_t)(ide_drive_t *);
 
 typedef struct hwgroup_s {
+	spinlock_t		spinlock; /* protects "busy" and "handler" */
 	ide_handler_t		*handler;/* irq handler, if active */
+	int			busy;	/* BOOL: protects all fields below */
 	ide_drive_t		*drive;	/* current drive */
 	ide_hwif_t		*hwif;	/* ptr to current hwif in linked-list */
 	struct request		*rq;	/* current request */
 	struct timer_list	timer;	/* failsafe timer */
 	struct request		wrq;	/* local copy of current write rq */
 	unsigned long		poll_timeout;	/* timeout value during long polls */
-	int			active;	/* set when servicing requests */
 	} ide_hwgroup_t;
 
 /*
@@ -393,7 +397,7 @@
 	struct ide_settings_s	*next;
 } ide_settings_t;
 
-void ide_add_setting(ide_drive_t *drive, char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
+void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
 void ide_remove_setting(ide_drive_t *drive, char *name);
 ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name);
 int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
@@ -663,6 +667,7 @@
  */
 struct request **ide_get_queue (kdev_t dev);
 
+int  ide_spin_wait_hwgroup(const char *msg, ide_drive_t *drive, unsigned long *flags);
 void ide_timer_expiry (unsigned long data);
 void ide_intr (int irq, void *dev_id, struct pt_regs *regs);
 void ide_geninit (struct gendisk *gd);
@@ -689,6 +694,9 @@
 #endif
 
 #ifdef _IDE_C
+#ifdef CONFIG_BLK_DEV_IDE
+int ideprobe_init (void);
+#endif /* CONFIG_BLK_DEV_IDE */
 #ifdef CONFIG_BLK_DEV_IDEDISK
 int idedisk_init (void);
 #endif /* CONFIG_BLK_DEV_IDEDISK */
@@ -722,12 +730,8 @@
 void ide_dma_intr  (ide_drive_t *drive);
 int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
 void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init;
-unsigned long ide_get_or_set_dma_base (struct pci_dev *dev, ide_hwif_t *hwif, int extra, const char *name) __init;
+unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init;
 #endif
-
-#ifdef CONFIG_BLK_DEV_IDE
-int ideprobe_init (void);
-#endif /* CONFIG_BLK_DEV_IDE */
 
 #ifdef CONFIG_BLK_DEV_PDC4030
 #include "pdc4030.h"
diff -u --recursive --new-file v2.1.99/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.1.99/linux/drivers/block/loop.c	Thu Mar 26 15:57:02 1998
+++ linux/drivers/block/loop.c	Wed May  6 10:56:02 1998
@@ -448,7 +448,7 @@
 	info.lo_flags = lo->lo_flags;
 	strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
 	info.lo_encrypt_type = lo->lo_encrypt_type;
-	if (lo->lo_encrypt_key_size && suser()) {
+	if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
 		info.lo_encrypt_key_size = lo->lo_encrypt_key_size;
 		memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,
 		       lo->lo_encrypt_key_size);
diff -u --recursive --new-file v2.1.99/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.1.99/linux/drivers/block/md.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/md.c	Wed May  6 10:56:02 1998
@@ -622,7 +622,7 @@
   int minor, err;
   struct hd_geometry *loc = (struct hd_geometry *) arg;
 
-  if (!suser())
+  if (!capable(CAP_SYS_ADMIN))
     return -EACCES;
 
   if (((minor=MINOR(inode->i_rdev)) & 0x80) &&
diff -u --recursive --new-file v2.1.99/linux/drivers/block/nbd.c linux/drivers/block/nbd.c
--- v2.1.99/linux/drivers/block/nbd.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/nbd.c	Wed May  6 10:56:02 1998
@@ -316,7 +316,7 @@
 	struct nbd_device *lo;
 	int dev, error;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	if (!inode)
 		return -EINVAL;
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ns87415.c linux/drivers/block/ns87415.c
--- v2.1.99/linux/drivers/block/ns87415.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/ns87415.c	Wed May  6 14:42:54 1998
@@ -35,7 +35,8 @@
 	struct pci_dev *dev = hwif->pci_dev;
 	unsigned long flags;
 
-	save_flags(flags); cli();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 	new = *old;
 
 	/* adjust IRQ enable bit */
@@ -56,7 +57,7 @@
 		*old = new;
 		(void) pci_write_config_dword(dev, 0x40, new);
 	}
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 }
 
 static void ns87415_selectproc (ide_drive_t *drive)
@@ -66,33 +67,25 @@
 
 static int ns87415_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = HWIF(drive);
+	ide_hwif_t	*hwif = HWIF(drive);
+	byte		dma_stat;
 
 	switch (func) {
 		case ide_dma_end: /* returns 1 on error, 0 otherwise */
-		{
-			byte dma_stat = inb(hwif->dma_base+2);
-			int rc = (dma_stat & 7) != 4;
-			/* from errata: stop DMA, clear INTR & ERROR */
-			outb(7, hwif->dma_base);
-			/* clear the INTR & ERROR bits */
-			outb(dma_stat|6, hwif->dma_base+2);
-			/* verify good DMA status */
-			return rc;
-		}
+			drive->waiting_for_dma = 0;
+			dma_stat = inb(hwif->dma_base+2);
+			outb(7, hwif->dma_base);		/* from errata: stop DMA, clear INTR & ERROR */
+			outb(dma_stat|6, hwif->dma_base+2);	/* clear the INTR & ERROR bits */
+			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		case ide_dma_write:
 		case ide_dma_read:
-			/* select DMA xfer */
-			ns87415_prepare_drive(drive, 1);
-			/* use standard DMA stuff */
-			if (!ide_dmaproc(func, drive))
+			ns87415_prepare_drive(drive, 1);	/* select DMA xfer */
+			if (!ide_dmaproc(func, drive))		/* use standard DMA stuff */
 				return 0;
-			/* DMA failed: select PIO xfer */
-			ns87415_prepare_drive(drive, 0);
+			ns87415_prepare_drive(drive, 0);	/* DMA failed: select PIO xfer */
 			return 1;
 		default:
-			/* use standard DMA stuff */
-			return ide_dmaproc(func, drive);
+			return ide_dmaproc(func, drive);	/* use standard DMA stuff */
 	}
 }
 
@@ -100,8 +93,7 @@
 {
 	struct pci_dev *dev = hwif->pci_dev;
 	unsigned int ctrl, using_inta;
-	byte progif, stat;
-	int timeout;
+	byte progif;
 
 	/*
 	 * We cannot probe for IRQ: both ports share common IRQ on INTA.
@@ -134,6 +126,9 @@
 		pci_write_config_byte(dev, 0x55, 0xee);
 
 #ifdef __sparc_v9__
+{
+		int	timeout;
+		byte	stat;
 		/*
 		 * XXX: Reset the device, if we don't it will not respond
 		 *      to SELECT_DRIVE() properly during first probe_hwif().
@@ -148,6 +143,7 @@
                 	if (stat == 0xff)
                         	break;
         	} while ((stat & BUSY_STAT) && --timeout);
+}
 #endif
 	}
 	if (!using_inta)
diff -u --recursive --new-file v2.1.99/linux/drivers/block/opti621.c linux/drivers/block/opti621.c
--- v2.1.99/linux/drivers/block/opti621.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/opti621.c	Wed May  6 14:42:54 1998
@@ -242,8 +242,8 @@
 		hwif->name, ax, second.data_time, second.recovery_time, drdy);
 #endif
 
-	save_flags(flags);
-	cli();
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
 
      	reg_base = hwif->io_ports[IDE_DATA_OFFSET];
 	outb(0xc0, reg_base+CNTRL_REG);	/* allow Register-B */
@@ -268,7 +268,7 @@
  	write_reg(misc, MISC_REG);	/* set address setup, DRDY timings,   */
  					/*  and read prefetch for both drives */
 
-	restore_flags(flags);
+	restore_flags(flags);	/* all CPUs */
 }
 
 /*
diff -u --recursive --new-file v2.1.99/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- v2.1.99/linux/drivers/block/paride/pd.c	Fri Jan 30 11:28:06 1998
+++ linux/drivers/block/paride/pd.c	Wed May  6 10:56:02 1998
@@ -466,7 +466,7 @@
                 put_user(pd_hd[dev].start_sect,(long *)&geo->start);
                 return 0;
             case BLKRASET:
-                if(!suser()) return -EACCES;
+                if(!capable(CAP_SYS_ADMIN)) return -EACCES;
                 if(!(inode->i_rdev)) return -EINVAL;
                 if(arg > 0xff) return -EINVAL;
                 read_ahead[MAJOR(inode->i_rdev)] = arg;
@@ -484,12 +484,14 @@
                 put_user(pd_hd[dev].nr_sects,(long *) arg);
                 return (0);
             case BLKFLSBUF:
-                if(!suser())  return -EACCES;
+                if(!capable(CAP_SYS_ADMIN))  return -EACCES;
                 if(!(inode->i_rdev)) return -EINVAL;
                 fsync_dev(inode->i_rdev);
                 invalidate_buffers(inode->i_rdev);
                 return 0;
             case BLKRRPART:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
                 return pd_revalidate(inode->i_rdev);
             RO_IOCTLS(inode->i_rdev,arg);
             default:
diff -u --recursive --new-file v2.1.99/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
--- v2.1.99/linux/drivers/block/paride/pf.c	Sun Dec 28 12:05:45 1997
+++ linux/drivers/block/paride/pf.c	Wed May  6 10:56:03 1998
@@ -416,7 +416,7 @@
                 put_user(0,(long *)&geo->start);
                 return 0;
             case BLKRASET:
-                if(!suser()) return -EACCES;
+                if(!capable(CAP_SYS_ADMIN)) return -EACCES;
                 if(!(inode->i_rdev)) return -EINVAL;
                 if(arg > 0xff) return -EINVAL;
                 read_ahead[MAJOR(inode->i_rdev)] = arg;
@@ -434,7 +434,7 @@
                 put_user(PF.capacity,(long *) arg);
                 return (0);
             case BLKFLSBUF:
-                if(!suser())  return -EACCES;
+                if(!capable(CAP_SYS_ADMIN))  return -EACCES;
                 if(!(inode->i_rdev)) return -EINVAL;
                 fsync_dev(inode->i_rdev);
                 invalidate_buffers(inode->i_rdev);
diff -u --recursive --new-file v2.1.99/linux/drivers/block/pdc4030.c linux/drivers/block/pdc4030.c
--- v2.1.99/linux/drivers/block/pdc4030.c	Wed Dec 17 11:11:16 1997
+++ linux/drivers/block/pdc4030.c	Wed May  6 14:42:54 1998
@@ -327,15 +327,9 @@
 	    do {
 		stat=GET_STAT();
 		if(stat & DRQ_STAT) {
-/*                    unsigned long flags;
-                    save_flags(flags);
-                    cli();
                     disable_irq(HWIF(drive)->irq);
-*/
 		    ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL);
-/*                    enable_irq(HWIF(drive)->irq);
-                    restore_flags(flags);
-*/
+                    enable_irq(HWIF(drive)->irq);
 		    return;
 		}
 		if(IN_BYTE(IDE_SELECT_REG) & 0x01)
@@ -353,7 +347,7 @@
 		return;
 	    }
 	    if (!drive->unmask)
-		cli();
+		__cli();	/* local CPU only */
 	    HWGROUP(drive)->wrq = *rq; /* scratchpad */
 	    promise_write(drive);
 	    return;
diff -u --recursive --new-file v2.1.99/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.1.99/linux/drivers/block/ps2esdi.c	Thu Feb 12 20:56:05 1998
+++ linux/drivers/block/ps2esdi.c	Wed May  6 10:56:08 1998
@@ -1091,7 +1091,7 @@
 			}
 			break;
 		case BLKRASET:
-			if (!suser())
+			if (!capable(CAP_SYS_ADMIN))
 				return -EACCES;
 			if (!inode->i_rdev)
 				return -EINVAL;
@@ -1109,7 +1109,7 @@
 			}
 			break;
 		case BLKFLSBUF:
-			if (!suser())
+			if (!capable(CAP_SYS_ADMIN))
 				return -EACCES;
 			if (!inode->i_rdev)
 				return -EINVAL;
@@ -1118,6 +1118,8 @@
 			return 0;
 
 		case BLKRRPART:
+                        if (!capable(CAP_SYS_ADMIN)) 
+				return -EACCES;
 			return (ps2esdi_reread_partitions(inode->i_rdev));
 			RO_IOCTLS(inode->i_rdev, arg);
 		}
diff -u --recursive --new-file v2.1.99/linux/drivers/block/qd6580.c linux/drivers/block/qd6580.c
--- v2.1.99/linux/drivers/block/qd6580.c	Wed Dec 17 11:11:16 1997
+++ linux/drivers/block/qd6580.c	Wed May  6 14:42:54 1998
@@ -49,13 +49,13 @@
 
 	pio = ide_get_best_pio_mode(drive, pio, 3, NULL);
 
-	save_flags(flags);
-	cli();
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
 	outb_p(0x8d,0xb0);
 	outb_p(0x0 ,0xb2);
 	outb_p(((pio+1)<<4)|0x0f,0xb3);
 	inb(0x3f6);
-	restore_flags(flags);
+	restore_flags(flags);	/* all CPUs */
 }
 
 void init_qd6580 (void)
diff -u --recursive --new-file v2.1.99/linux/drivers/block/raid5.c linux/drivers/block/raid5.c
--- v2.1.99/linux/drivers/block/raid5.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/block/raid5.c	Mon May  4 11:37:02 1998
@@ -1209,6 +1209,14 @@
 	sh->pd_idx = pd_idx;
 	if (sh->phase != PHASE_COMPLETE && sh->phase != PHASE_BEGIN)
 		PRINTK(("stripe %lu catching the bus!\n", sh->sector));
+	if (sh->bh_new[dd_idx]) {
+		printk("raid5: bug: stripe->bh_new[%d], sector %lu exists\n", dd_idx, sh->sector);
+		printk("raid5: bh %p, bh_new %p\n", bh, sh->bh_new[dd_idx]);
+		lock_stripe(sh);
+		md_wakeup_thread(raid_conf->thread);
+		wait_on_stripe(sh);
+		goto repeat;
+	}
 	add_stripe_bh(sh, bh, dd_idx, rw);
 
 	md_wakeup_thread(raid_conf->thread);
diff -u --recursive --new-file v2.1.99/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.1.99/linux/drivers/block/rd.c	Sat May  2 14:19:53 1998
+++ linux/drivers/block/rd.c	Wed May  6 10:56:03 1998
@@ -164,7 +164,7 @@
 
 	switch (cmd) {
 		case BLKFLSBUF:
-			if (!suser()) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			invalidate_buffers(inode->i_rdev);
 			break;
          	case BLKGETSIZE:   /* Return device size */
diff -u --recursive --new-file v2.1.99/linux/drivers/block/sl82c105.c linux/drivers/block/sl82c105.c
--- v2.1.99/linux/drivers/block/sl82c105.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/sl82c105.c	Wed May  6 14:42:54 1998
@@ -19,8 +19,9 @@
 ide_ioreg_t chrp_ide_regbase[MAX_HWIFS];
 ide_ioreg_t chrp_idedma_regbase;
 
-void ide_init_sl82c105(struct pci_dev *dev) {
-
+void ide_init_sl82c105(ide_hwif_t *hwif)
+{
+	struct pci_dev *dev = hwif->pci_dev;
 	unsigned short t16;
 	unsigned int t32;
 
@@ -37,15 +38,7 @@
 	pci_write_config_dword(dev, 0x40, 0x10ff08a1);
 }
 
-
-void ide_probe_for_sl82c105(void)
-{
-	struct pci_dev *dev = NULL;
-
-        while ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, dev)))
-                ide_init_sl82c105(dev);
-}
-
+#if 0	/* nobody ever calls these.. ?? */
 void chrp_ide_probe(void) {
 
 	struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL);
@@ -75,4 +68,4 @@
         if (irq != NULL)
                 *irq = chrp_ide_irq;
 }
-
+#endif
diff -u --recursive --new-file v2.1.99/linux/drivers/block/trm290.c linux/drivers/block/trm290.c
--- v2.1.99/linux/drivers/block/trm290.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/trm290.c	Wed May  6 14:42:54 1998
@@ -148,8 +148,8 @@
 	/* select PIO or DMA */
 	reg = use_dma ? (0x21 | 0x82) : (0x21 & ~0x82);
 
-	save_flags(flags);
-	cli();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 
 	if (reg != hwif->select_data) {
 		hwif->select_data = reg;
@@ -164,7 +164,7 @@
 		outw(reg, hwif->config_data+3);
 	}
 
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 }
 
 static void trm290_selectproc (ide_drive_t *drive)
@@ -189,15 +189,20 @@
 				break;		/* try PIO instead of DMA */
 			trm290_prepare_drive(drive, 1);	/* select DMA xfer */
 			outl(virt_to_bus(hwif->dmatable)|reading|writing, hwif->dma_base);
+			drive->waiting_for_dma = 1;
 			outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
 			if (drive->media != ide_disk)
 				return 0;
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
 			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+			return 0;
 		case ide_dma_begin:
 			return 0;
 		case ide_dma_end:
+			drive->waiting_for_dma = 0;
 			return (inw(hwif->dma_base+2) != 0x00ff);
+		case ide_dma_test_irq:
+			return (inw(hwif->dma_base+2) == 0x00ff);
 		default:
 			return ide_dmaproc(func, drive);
 	}
@@ -226,8 +231,8 @@
 		printk("TRM290: using default config base at 0x%04lx\n", hwif->config_data);
 	}
 
-	save_flags(flags);
-	cli();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 	/* put config reg into first byte of hwif->select_data */
 	outb(0x51|(hwif->channel<<3), hwif->config_data+1);
 	hwif->select_data = 0x21;			/* select PIO as default */
@@ -235,13 +240,13 @@
 	reg = inb(hwif->config_data+3);			/* get IRQ info */
 	reg = (reg & 0x10) | 0x03;			/* mask IRQs for both ports */
 	outb(reg, hwif->config_data+3);
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 
 	if ((reg & 0x10))
 		hwif->irq = hwif->channel ? 15 : 14;	/* legacy mode */
 	else if (!hwif->irq && hwif->mate && hwif->mate->irq)
 		hwif->irq = hwif->mate->irq;		/* sharing IRQ with mate */
-	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 2);
+	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
 	hwif->dmaproc = &trm290_dmaproc;
 	hwif->selectproc = &trm290_selectproc;
 	hwif->no_autodma = 1;				/* play it safe for now */
diff -u --recursive --new-file v2.1.99/linux/drivers/block/umc8672.c linux/drivers/block/umc8672.c
--- v2.1.99/linux/drivers/block/umc8672.c	Wed Dec 17 11:11:16 1997
+++ linux/drivers/block/umc8672.c	Wed May  6 14:42:54 1998
@@ -112,39 +112,39 @@
 
 	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
 	printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", drive->name, pio, pio_to_umc[pio]);
-	save_flags(flags);
-	cli();
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
 	if (hwgroup && hwgroup->handler != NULL) {
 		printk("umc8672: other interface is busy: exiting tune_umc()\n");
 	} else {
 		current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio];
 		umc_set_speeds (current_speeds);
 	}
-	restore_flags(flags);
+	restore_flags(flags);	/* all CPUs */
 }
 
 void init_umc8672 (void)	/* called from ide.c */
 {
 	unsigned long flags;
 
-	save_flags(flags);
-	cli ();
+	__save_flags(flags);	/* local CPU only */
+	__cli();		/* local CPU only */
 	if (check_region(0x108, 2)) {
-		restore_flags(flags);
+		__restore_flags(flags);
 		printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n");
 		return;
 	}
 	outb_p (0x5A,0x108); /* enable umc */
 	if (in_umc (0xd5) != 0xa0)
 	{
-		restore_flags(flags);
+		__restore_flags(flags);	/* local CPU only */
 		printk ("umc8672: not found\n");
 		return;  
 	}
 	outb_p (0xa5,0x108); /* disable umc */
 
 	umc_set_speeds (current_speeds);
-	restore_flags(flags);
+	__restore_flags(flags);	/* local CPU only */
 
 	request_region(0x108, 2, "umc8672");
 	ide_hwifs[0].chipset = ide_umc8672;
diff -u --recursive --new-file v2.1.99/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.1.99/linux/drivers/block/xd.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/xd.c	Wed May  6 10:56:08 1998
@@ -338,7 +338,7 @@
 			return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
 		}
 		case BLKRASET:
-			if(!suser()) return -EACCES;
+			if(!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if(arg > 0xff) return -EINVAL;
 			read_ahead[MAJOR(inode->i_rdev)] = arg;
 			return 0;
@@ -348,12 +348,12 @@
 			if (!arg) return -EINVAL;
 			return put_user(xd_struct[MINOR(inode->i_rdev)].nr_sects,(long *) arg);
 		case BLKFLSBUF:   /* Return devices size */
-			if(!suser())  return -EACCES;
+			if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 			fsync_dev(inode->i_rdev);
 			invalidate_buffers(inode->i_rdev);
 			return 0;
 		case HDIO_SET_DMA:
-			if (!suser()) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if (xdc_busy) return -EBUSY;
 			nodma = !arg;
 			if (nodma && xd_dma_buffer) {
@@ -366,6 +366,8 @@
 		case HDIO_GET_MULTCOUNT:
 			return put_user(xd_maxsectors, (long *) arg);
 		case BLKRRPART:
+			if (!capable(CAP_SYS_ADMIN)) 
+				return -EACCES;
 			return xd_reread_partitions(inode->i_rdev);
 		RO_IOCTLS(inode->i_rdev,arg);
 		default:
diff -u --recursive --new-file v2.1.99/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v2.1.99/linux/drivers/cdrom/sbpcd.c	Thu Feb 12 20:56:05 1998
+++ linux/drivers/cdrom/sbpcd.c	Wed May  6 10:56:03 1998
@@ -4189,7 +4189,7 @@
 	switch (cmd) 		/* Sun-compatible */
 	{
 	case DDIOCSDBG:		/* DDI Debug */
-		if (!suser()) RETURN_UP(-EPERM);
+		if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
 		i=sbpcd_dbg_ioctl(arg,1);
 		RETURN_UP(i);
 	case CDROMRESET:      /* hard reset the drive */
@@ -4478,7 +4478,7 @@
 	} /* end of CDROMREADAUDIO */
 		
 	case BLKRASET:
-		if(!suser()) RETURN_UP(-EACCES);
+		if(!capable(CAP_SYS_ADMIN)) RETURN_UP(-EACCES);
 		if(!(cdi->dev)) RETURN_UP(-EINVAL);
 		if(arg > 0xff) RETURN_UP(-EINVAL);
 		read_ahead[MAJOR(cdi->dev)] = arg;
diff -u --recursive --new-file v2.1.99/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c
--- v2.1.99/linux/drivers/char/apm_bios.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/char/apm_bios.c	Wed May  6 10:56:03 1998
@@ -1050,7 +1050,7 @@
 	 * we might close the device immediately without doing a
 	 * privileged operation -- cevans
 	 */
-	as->suser = suser();
+	as->suser = capable(CAP_SYS_ADMIN);
 	as->next = user_list;
 	user_list = as;
 	filp->private_data = as;
diff -u --recursive --new-file v2.1.99/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.1.99/linux/drivers/char/bttv.c	Tue Apr 14 14:29:20 1998
+++ linux/drivers/char/bttv.c	Wed May  6 10:56:03 1998
@@ -1581,7 +1581,7 @@
 		case VIDIOCSFBUF:
 		{
 			struct video_buffer v;
-			if(!suser())
+			if(!capable(CAP_SYS_ADMIN))
 				return -EPERM;
 			if(copy_from_user(&v, arg,sizeof(v)))
 				return -EFAULT;
@@ -1680,7 +1680,7 @@
 		        return 0;
 
 		case BTTV_WRITEE:
-			if(!suser())
+			if(!capable(CAP_SYS_ADMIN))
 				return -EPERM;
 			if(copy_from_user((void *) eedata, (void *) arg, 256))
 				return -EFAULT;
@@ -1688,7 +1688,7 @@
 			return 0;
 
 		case BTTV_READEE:
-			if(!suser())
+			if(!capable(CAP_SYS_ADMIN))
 				return -EPERM;
 			readee(&(btv->i2c), eedata);
 			if(copy_to_user((void *) arg, (void *) eedata, 256))
diff -u --recursive --new-file v2.1.99/linux/drivers/char/console.c linux/drivers/char/console.c
--- v2.1.99/linux/drivers/char/console.c	Wed Apr  8 19:36:26 1998
+++ linux/drivers/char/console.c	Wed May  6 10:56:03 1998
@@ -331,7 +331,7 @@
 	    long p, q;
 
 	    /* prevent users from taking too much memory */
-	    if (i >= MAX_NR_USER_CONSOLES && !suser())
+	    if (i >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
 	      return -EPERM;
 
 	    /* due to the granularity of kmalloc, we waste some memory here */
diff -u --recursive --new-file v2.1.99/linux/drivers/char/esp.c linux/drivers/char/esp.c
--- v2.1.99/linux/drivers/char/esp.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/char/esp.c	Wed May  6 10:56:03 1998
@@ -926,7 +926,7 @@
 			     "esp serial", info);
 
 	if (retval) {
-		if (suser()) {
+		if (capable(CAP_SYS_ADMIN)) {
 			if (info->tty)
 				set_bit(TTY_IO_ERROR,
 					&info->tty->flags);
@@ -1499,7 +1499,7 @@
 	if (change_irq && (info->line % 8))
 		return -EINVAL;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if (change_irq || 
 		    (new_serial.close_delay != info->close_delay) ||
 		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
diff -u --recursive --new-file v2.1.99/linux/drivers/char/ftape/zftape/zftape-ctl.c linux/drivers/char/ftape/zftape/zftape-ctl.c
--- v2.1.99/linux/drivers/char/ftape/zftape/zftape-ctl.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/char/ftape/zftape/zftape-ctl.c	Wed May  6 10:56:03 1998
@@ -1342,9 +1342,9 @@
 	TRACE_FUN(ft_t_flow);
 
 	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTCMD");
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		TRACE_ABORT(-EPERM, ft_t_info,
-			    "only the superuser may send raw qic-117 commands");
+			    "need CAP_SYS_ADMIN capability to send raw qic-117 commands");
 	}
 	if (zft_qic_mode) {
 		TRACE_ABORT(-EACCES, ft_t_info,
diff -u --recursive --new-file v2.1.99/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
--- v2.1.99/linux/drivers/char/istallion.c	Thu Mar 26 15:57:03 1998
+++ linux/drivers/char/istallion.c	Wed May  6 10:56:03 1998
@@ -1774,7 +1774,7 @@
 #endif
 
 	copy_from_user(&sio, sp, sizeof(struct serial_struct));
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((sio.baud_base != portp->baud_base) ||
 		    (sio.close_delay != portp->close_delay) ||
 		    ((sio.flags & ~ASYNC_USR_MASK) !=
diff -u --recursive --new-file v2.1.99/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v2.1.99/linux/drivers/char/lp.c	Sat Apr 25 18:13:11 1998
+++ linux/drivers/char/lp.c	Thu May  7 14:56:58 1998
@@ -13,7 +13,7 @@
  * lp_read (Status readback) support added by Carsten Gross,
  *                                             carsten@sol.wohnheim.uni-ulm.de
  * Support for parport by Philip Blundell <Philip.Blundell@pobox.com>
- * parport_sharing hacking by Andrea Arcangeli <arcangeli@mbox.queen.it>
+ * Parport sharing hacking by Andrea Arcangeli <arcangeli@mbox.queen.it>
  * Fixed kernel_(to/from)_user memory copy to check for errors
  * 				by Riccardo Facchetti <fizban@tin.it>
  */
@@ -75,6 +75,8 @@
 #include <linux/delay.h>
 
 #include <linux/parport.h>
+#undef LP_STATS
+#undef LP_NEED_CAREFUL
 #include <linux/lp.h>
 
 #include <asm/irq.h>
@@ -87,17 +89,23 @@
 struct lp_struct lp_table[LP_NO] =
 {
 	[0 ... LP_NO-1] = {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT,
-			   NULL, 0, 0, 0, {0}}
+			   NULL,
+#ifdef LP_STATS
+			   0, 0, {0},
+#endif
+			   NULL, 0}
 };
 
 /* Test if printer is ready (and optionally has no error conditions) */
+#ifdef LP_NEED_CAREFUL
 #define LP_READY(minor, status) \
-  ((LP_F(minor) & LP_CAREFUL) ? _LP_CAREFUL_READY(status) : (status & LP_PBUSY))
-#define LP_CAREFUL_READY(minor, status) \
-  ((LP_F(minor) & LP_CAREFUL) ? _LP_CAREFUL_READY(status) : 1)
+  ((LP_F(minor) & LP_CAREFUL) ? _LP_CAREFUL_READY(status) : ((status) & LP_PBUSY))
 #define _LP_CAREFUL_READY(status) \
-   (status & (LP_PBUSY|LP_POUTPA|LP_PSELECD|LP_PERRORP)) == \
+   ((status) & (LP_PBUSY|LP_POUTPA|LP_PSELECD|LP_PERRORP)) == \
       (LP_PBUSY|LP_PSELECD|LP_PERRORP)
+#else
+#define LP_READY(minor, status) ((status) & LP_PBUSY)
+#endif
 
 #undef LP_DEBUG
 #undef LP_READ_DEBUG
@@ -108,8 +116,8 @@
 {
        struct lp_struct *lps = (struct lp_struct *)handle;
 
-       if (waitqueue_active (&lps->dev->wait_q))
-               wake_up_interruptible(&lps->dev->wait_q);
+       if (waitqueue_active (&lps->wait_q))
+               wake_up_interruptible(&lps->wait_q);
 
        /* Don't actually release the port now */
        return 1;
@@ -157,31 +165,29 @@
 
 static inline int lp_char(char lpchar, int minor)
 {
-	int status;
+	unsigned char status;
 	unsigned int wait = 0;
 	unsigned long count = 0;
+#ifdef LP_STATS
 	struct lp_stats *stats;
+#endif
 
-	for (;;) {
+	for (;;)
+	{
 		lp_yield(minor);
 		status = r_str (minor);
-		if (++count == LP_CHAR(minor))
+		if (LP_READY(minor, status))
+			break;
+		if (!LP_POLLED(minor) || ++count == LP_CHAR(minor) ||
+		     signal_pending(current))
 			return 0;
-		if (LP_POLLING(minor))
-		{
-			if (LP_READY(minor, status))
-				break;
-		} else {
-			if (!LP_READY(minor, status))
-				return 0;
-			else
-				break;
-		}
 	}
 
 	w_dtr(minor, lpchar);
+#ifdef LP_STATS
 	stats = &LP_STAT(minor);
 	stats->chars++;
+#endif
 	/* must wait before taking strobe high, and after taking strobe
 	   low, according spec.  Some printers need it, others don't. */
 #ifndef __sparc__
@@ -200,6 +206,8 @@
 #endif
 	/* take strobe low */
 	w_ctr(minor, LP_PSELECP | LP_PINITP);
+
+#ifdef LP_STATS
 	/* update waittime statistics */
 	if (count > stats->maxwait) {
 #ifdef LP_DEBUG
@@ -212,6 +220,7 @@
 	    stats->meanwait - count;
 	stats->meanwait = (255 * stats->meanwait + count + 128) / 256;
 	stats->mdev = ((127 * stats->mdev) + wait + 64) / 128;
+#endif
 
 	return 1;
 }
@@ -220,13 +229,13 @@
 {
 	struct lp_struct *lp_dev = (struct lp_struct *) dev_id;
 
-	if (waitqueue_active (&lp_dev->dev->wait_q))
-		wake_up_interruptible(&lp_dev->dev->wait_q);
+	if (waitqueue_active (&lp_dev->wait_q))
+		wake_up_interruptible(&lp_dev->wait_q);
 }
 
 static void lp_error(int minor)
 {
-	if (LP_POLLING(minor) || LP_PREEMPTED(minor)) {
+	if (LP_POLLED(minor) || LP_PREEMPTED(minor)) {
 		current->state = TASK_INTERRUPTIBLE;
 		current->timeout = jiffies + LP_TIMEOUT_POLLED;
 		lp_parport_release(minor);
@@ -236,7 +245,7 @@
 }
 
 static int lp_check_status(int minor) {
-	static unsigned char last = 0;
+	unsigned int last = lp_table[minor].last_error;
 	unsigned char status = r_str(minor);
 	if ((status & LP_POUTPA)) {
 		if (last != LP_POUTPA) {
@@ -256,6 +265,8 @@
 	}
 	else last = 0;
 
+	lp_table[minor].last_error = last;
+
 	if (last != 0) {
 		if (LP_F(minor) & LP_ABORT)
 			return 1;
@@ -265,7 +276,7 @@
 	return 0;
 }
 
-static inline int lp_write_buf(unsigned int minor, const char *buf, int count)
+static int lp_write_buf(unsigned int minor, const char *buf, int count)
 {
 	unsigned long copy_size;
 	unsigned long total_bytes_written = 0;
@@ -275,9 +286,11 @@
 
 	if (minor >= LP_NO)
 		return -ENXIO;
-	if (lp_table[minor].dev == NULL)
+	if (lp->dev == NULL)
 		return -ENXIO;
 
+	lp_table[minor].last_error = 0;
+
 	do {
 		bytes_written = 0;
 		copy_size = (count <= LP_BUFFER_SIZE ? count : LP_BUFFER_SIZE);
@@ -289,55 +302,69 @@
 			if (lp_char(lp->lp_buffer[bytes_written], minor)) {
 				--copy_size;
 				++bytes_written;
-				lp_table[minor].runchars++;
+#ifdef LP_STATS
+				lp->runchars++;
+#endif
 			} else {
 				int rc = total_bytes_written + bytes_written;
-				if (lp_table[minor].runchars > LP_STAT(minor).maxrun)
-					LP_STAT(minor).maxrun = lp_table[minor].runchars;
+
+#ifdef LP_STATS
+				if (lp->runchars > LP_STAT(minor).maxrun)
+					LP_STAT(minor).maxrun = lp->runchars;
 				LP_STAT(minor).sleeps++;
+#endif
 
-				if (LP_POLLING(minor)) {
-				lp_polling:
+				if (signal_pending(current)) {
+					if (total_bytes_written + bytes_written)
+						return total_bytes_written + bytes_written;
+					else
+						return -EINTR;
+				}
+
+#ifdef LP_STATS
+				lp->runchars = 0;
+#endif
+
+				if (LP_POLLED(minor)) {
 					if (lp_check_status(minor))
 						return rc ? rc : -EIO;
-#ifdef LP_DEBUG
-					printk(KERN_DEBUG "lp%d sleeping at %d characters for %d jiffies\n", minor, lp_table[minor].runchars, LP_TIME(minor));
+				lp_polling:
+#if defined(LP_DEBUG) && defined(LP_STATS)
+					printk(KERN_DEBUG "lp%d sleeping at %d characters for %d jiffies\n", minor, lp->runchars, LP_TIME(minor));
 #endif
 					current->state = TASK_INTERRUPTIBLE;
 					current->timeout = jiffies + LP_TIME(minor);
 					lp_schedule (minor);
 				} else {
 					cli();
-					if (LP_PREEMPTED(minor)) {
+					if (LP_PREEMPTED(minor))
+					{
+						/*
+						 * We can' t sleep on the interrupt
+						 * since another pardevice need the port.
+						 */
 						sti();
 						goto lp_polling;
 					}
-					enable_irq(lp->dev->port->irq);
-					w_ctr(minor, LP_PSELECP|LP_PINITP|LP_PINTEN);
+					w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PINTEN);
 					status = r_str(minor);
-					if ((!(status & LP_PACK) || (status & LP_PBUSY))
-					    && LP_CAREFUL_READY(minor, status)) {
+					if (!(status & LP_PACK) || (status & LP_PBUSY))
+					{
+						/*
+						 * The interrupt is happened in the
+						 * meantime so don' t wait for it.
+						 */
 						w_ctr(minor, LP_PSELECP | LP_PINITP);
 						sti();
 						continue;
 					}
 					current->timeout = jiffies + LP_TIMEOUT_INTERRUPT;
-					interruptible_sleep_on(&lp->dev->wait_q);
-					disable_irq(lp->dev->port->irq);
+					interruptible_sleep_on(&lp->wait_q);
 					w_ctr(minor, LP_PSELECP | LP_PINITP);
 					sti();
 					if (lp_check_status(minor))
 						return rc ? rc : -EIO;
 				}
-
-				lp_table[minor].runchars = 0;
-
-				if (signal_pending(current)) {
-					if (total_bytes_written + bytes_written)
-						return total_bytes_written + bytes_written;
-					else
-						return -EINTR;
-				}
 			}
 		}
 
@@ -356,10 +383,12 @@
 	unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
 	ssize_t retv;
 
+#ifdef LP_STATS
 	if (jiffies-lp_table[minor].lastcall > LP_TIME(minor))
 		lp_table[minor].runchars = 0;
 
 	lp_table[minor].lastcall = jiffies;
+#endif
 
  	/* Claim Parport or sleep until it becomes available
  	 */
@@ -495,9 +524,8 @@
 		return -ENXIO;
 	if ((LP_F(minor) & LP_EXIST) == 0)
 		return -ENXIO;
-	if (LP_F(minor) & LP_BUSY)
+	if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor)) & LP_BUSY)
 		return -EBUSY;
-	LP_F(minor) |= LP_BUSY;
 
 	MOD_INC_USE_COUNT;
 
@@ -543,8 +571,8 @@
 
 	kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE);
 	lp_table[minor].lp_buffer = NULL;
-	LP_F(minor) &= ~LP_BUSY;
 	MOD_DEC_USE_COUNT;
+	LP_F(minor) &= ~LP_BUSY;
 	return 0;
 }
 
@@ -581,12 +609,14 @@
 			else
 				LP_F(minor) &= ~LP_ABORTOPEN;
 			break;
+#ifdef LP_NEED_CAREFUL
 		case LPCAREFUL:
 			if (arg)
 				LP_F(minor) |= LP_CAREFUL;
 			else
 				LP_F(minor) &= ~LP_CAREFUL;
 			break;
+#endif
 		case LPWAIT:
 			LP_WAIT(minor) = arg;
 			break;
@@ -609,6 +639,7 @@
 		case LPRESET:
 			lp_reset(minor);
 			break;
+#ifdef LP_STATS
 		case LPGETSTATS:
 			if (copy_to_user((int *) arg, &LP_STAT(minor),
 					sizeof(struct lp_stats)))
@@ -617,6 +648,7 @@
 				memset(&LP_STAT(minor), 0,
 						sizeof(struct lp_stats));
 			break;
+#endif
  		case LPGETFLAGS:
  			status = LP_F(minor);
 			if (copy_to_user((int *) arg, &status, sizeof(int)))
diff -u --recursive --new-file v2.1.99/linux/drivers/char/nvram.c linux/drivers/char/nvram.c
--- v2.1.99/linux/drivers/char/nvram.c	Tue Nov  4 08:34:39 1997
+++ linux/drivers/char/nvram.c	Wed May  6 10:56:03 1998
@@ -285,7 +285,7 @@
 	switch( cmd ) {
 
 	  case NVRAM_INIT:			/* initialize NVRAM contents and checksum */
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return( -EACCES );
 
 		save_flags(flags);
@@ -301,7 +301,7 @@
 	  case NVRAM_SETCKS:		/* just set checksum, contents unchanged
 								 * (maybe useful after checksum garbaged
 								 * somehow...) */
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return( -EACCES );
 
 		save_flags(flags);
diff -u --recursive --new-file v2.1.99/linux/drivers/char/random.c linux/drivers/char/random.c
--- v2.1.99/linux/drivers/char/random.c	Tue Mar 10 10:03:31 1998
+++ linux/drivers/char/random.c	Wed May  6 10:56:03 1998
@@ -1199,7 +1199,7 @@
 		put_user(ent_count, (int *) arg);
 		return 0;
 	case RNDADDTOENTCNT:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		retval = verify_area(VERIFY_READ, (void *) arg, sizeof(int));
 		if (retval)
@@ -1228,7 +1228,7 @@
 			wake_up_interruptible(&random_read_wait);
 		return 0;
 	case RNDGETPOOL:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		p = (int *) arg;
 		retval = verify_area(VERIFY_WRITE, (void *) p, sizeof(int));
@@ -1249,7 +1249,7 @@
 			return -EFAULT;
 		return 0;
 	case RNDADDENTROPY:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		p = (int *) arg;
 		retval = verify_area(VERIFY_READ, (void *) p, 2*sizeof(int));
@@ -1287,13 +1287,13 @@
 			wake_up_interruptible(&random_read_wait);
 		return 0;
 	case RNDZAPENTCNT:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		random_state.entropy_count = 0;
 		return 0;
 	case RNDCLEARPOOL:
 		/* Clear the entropy pool and associated counters. */
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		rand_clear_pool();
 		return 0;
diff -u --recursive --new-file v2.1.99/linux/drivers/char/riscom8.c linux/drivers/char/riscom8.c
--- v2.1.99/linux/drivers/char/riscom8.c	Tue Mar 10 10:03:31 1998
+++ linux/drivers/char/riscom8.c	Wed May  6 10:56:03 1998
@@ -1447,7 +1447,7 @@
 	change_speed = ((port->flags & ASYNC_SPD_MASK) !=
 			(tmp.flags & ASYNC_SPD_MASK));
 	
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((tmp.close_delay != port->close_delay) ||
 		    (tmp.closing_wait != port->closing_wait) ||
 		    ((tmp.flags & ~ASYNC_USR_MASK) !=
diff -u --recursive --new-file v2.1.99/linux/drivers/char/rocket.c linux/drivers/char/rocket.c
--- v2.1.99/linux/drivers/char/rocket.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/char/rocket.c	Wed May  6 10:56:03 1998
@@ -1315,7 +1315,7 @@
 	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
 		return -EFAULT;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.flags & ~ROCKET_USR_MASK) !=
 		    (info->flags & ~ROCKET_USR_MASK))
 			return -EPERM;
diff -u --recursive --new-file v2.1.99/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.1.99/linux/drivers/char/rtc.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/char/rtc.c	Wed May  6 10:56:03 1998
@@ -220,7 +220,7 @@
 		 * We don't really want Joe User enabling more
 		 * than 64Hz of interrupts on a multi-user machine.
 		 */
-		if ((rtc_freq > 64) && (!suser()))
+		if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
 		if (!(rtc_status & RTC_TIMER_ON)) {
@@ -308,7 +308,7 @@
 		unsigned int yrs;
 		unsigned long flags;
 			
-		if (!suser())
+		if (!capable(CAP_SYS_TIME))
 			return -EACCES;
 
 		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
@@ -394,7 +394,7 @@
 		 * We don't really want Joe User generating more
 		 * than 64Hz of interrupts on a multi-user machine.
 		 */
-		if ((arg > 64) && (!suser()))
+		if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
 		while (arg > (1<<tmp))
@@ -429,7 +429,7 @@
 		if (arg < 1900)
 			return -EINVAL;
 
-		if (!suser())
+		if (!capable(CAP_SYS_TIME))
 			return -EACCES;
 
 		epoch = arg;
diff -u --recursive --new-file v2.1.99/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.1.99/linux/drivers/char/serial.c	Thu Apr 23 20:21:33 1998
+++ linux/drivers/char/serial.c	Wed May  6 10:56:03 1998
@@ -973,7 +973,7 @@
 	 * here.
 	 */
 	if (serial_inp(info, UART_LSR) == 0xff) {
-		if (suser()) {
+		if (capable(CAP_SYS_ADMIN)) {
 			if (info->tty)
 				set_bit(TTY_IO_ERROR, &info->tty->flags);
 		} else
@@ -1005,7 +1005,7 @@
 		retval = request_irq(state->irq, handler, IRQ_T(info),
 				     "serial", NULL);
 		if (retval) {
-			if (suser()) {
+			if (capable(CAP_SYS_ADMIN)) {
 				if (info->tty)
 					set_bit(TTY_IO_ERROR,
 						&info->tty->flags);
@@ -1638,7 +1638,7 @@
 	change_port = (new_serial.port != state->port) ||
 		(new_serial.hub6 != state->hub6);
   
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if (change_irq || change_port ||
 		    (new_serial.baud_base != state->baud_base) ||
 		    (new_serial.type != state->type) ||
@@ -1837,7 +1837,7 @@
 {
 	int			retval;
 	
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	
 	if (info->state->count > 1)
@@ -1922,7 +1922,7 @@
 	int	retval;
 	void (*handler)(int, void *, struct pt_regs *);
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	state = info->state;
 	
diff -u --recursive --new-file v2.1.99/linux/drivers/char/specialix.c linux/drivers/char/specialix.c
--- v2.1.99/linux/drivers/char/specialix.c	Tue Mar 10 10:03:31 1998
+++ linux/drivers/char/specialix.c	Wed May  6 10:56:03 1998
@@ -1842,7 +1842,7 @@
 	change_speed = ((port->flags & ASYNC_SPD_MASK) !=
 			(tmp.flags & ASYNC_SPD_MASK));
 	
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((tmp.close_delay != port->close_delay) ||
 		    (tmp.closing_wait != port->closing_wait) ||
 		    ((tmp.flags & ~ASYNC_USR_MASK) !=
diff -u --recursive --new-file v2.1.99/linux/drivers/char/stallion.c linux/drivers/char/stallion.c
--- v2.1.99/linux/drivers/char/stallion.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/char/stallion.c	Wed May  6 10:56:03 1998
@@ -1338,7 +1338,7 @@
 #endif
 
 	copy_from_user(&sio, sp, sizeof(struct serial_struct));
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((sio.baud_base != portp->baud_base) ||
 		    (sio.close_delay != portp->close_delay) ||
 		    ((sio.flags & ~ASYNC_USR_MASK) !=
diff -u --recursive --new-file v2.1.99/linux/drivers/char/vt.c linux/drivers/char/vt.c
--- v2.1.99/linux/drivers/char/vt.c	Thu Apr 23 20:21:33 1998
+++ linux/drivers/char/vt.c	Wed May  6 10:56:04 1998
@@ -249,7 +249,8 @@
 		if (!(key_map = key_maps[s])) {
 			int j;
 
-			if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && !suser())
+			if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && 
+			    !capable(CAP_SYS_RESOURCE))
 				return -EPERM;
 
 			key_map = (ushort *) kmalloc(sizeof(plain_map),
@@ -268,7 +269,7 @@
 		/*
 		 * Attention Key.
 		 */
-		if (((ov == K_SAK) || (v == K_SAK)) && !suser())
+		if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		key_map[i] = U(v);
 		if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
diff -u --recursive --new-file v2.1.99/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- v2.1.99/linux/drivers/isdn/avmb1/capi.c	Wed Apr  1 20:11:49 1998
+++ linux/drivers/isdn/avmb1/capi.c	Wed May  6 10:56:04 1998
@@ -384,7 +384,7 @@
 			struct capi_manufacturer_cmd mcmd;
 			if (minor)
 				return -EINVAL;
-			if (!suser())
+			if (!capable(CAP_SYS_ADMIN))
 				return -EPERM;
 			retval = copy_from_user((void *) &mcmd, (void *) arg,
 						sizeof(mcmd));
diff -u --recursive --new-file v2.1.99/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- v2.1.99/linux/drivers/macintosh/macserial.c	Sat Apr 25 18:13:11 1998
+++ linux/drivers/macintosh/macserial.c	Wed May  6 10:56:04 1998
@@ -964,7 +964,7 @@
 	copy_from_user(&new_serial,new_info,sizeof(new_serial));
 	old_info = *info;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.type != info->type) ||
 		    (new_serial.close_delay != info->close_delay) ||
diff -u --recursive --new-file v2.1.99/linux/drivers/misc/TODO-parport linux/drivers/misc/TODO-parport
--- v2.1.99/linux/drivers/misc/TODO-parport	Fri Jan 30 11:28:07 1998
+++ linux/drivers/misc/TODO-parport	Thu May  7 14:56:58 1998
@@ -6,20 +6,13 @@
 
 2. A better lp.c:
 
-   a) It's a _mess_
-
-   b) ECP support would be nice.  This can only work if both the port and
+   a) ECP support would be nice.  This can only work if both the port and
       the printer support it.
 
-   c) Errors could do with being handled better.  There's no point logging a
-      message every 10 seconds when the printer is out of paper. 
-
-   d) Handle status readback automatically.  IEEE1284 printers can post status
+   b) Handle status readback automatically.  IEEE1284 printers can post status
       bits when they have something to say.  We should read out and deal 
       with (maybe just log) whatever the printer wants to tell the world.
 
 3. Support more hardware (eg m68k, Sun bpp).
 
 4. A better PLIP (make use of bidirectional/ECP/EPP ports).
-
-
diff -u --recursive --new-file v2.1.99/linux/drivers/misc/parport_procfs.c linux/drivers/misc/parport_procfs.c
--- v2.1.99/linux/drivers/misc/parport_procfs.c	Sat Apr 25 18:13:11 1998
+++ linux/drivers/misc/parport_procfs.c	Tue May  5 10:44:06 1998
@@ -37,8 +37,8 @@
 	int retval = -EINVAL;
 	int newirq = PARPORT_IRQ_NONE;
 	struct parport *pp = (struct parport *)data;
-	struct pardevice *cad = pp->cad;
 	int oldirq = pp->irq;
+	unsigned long flags;
 
 /*
  * We can have these valid cases:
@@ -70,35 +70,30 @@
 	if (oldirq == newirq)
 		goto out;
 
+	spin_lock_irqsave(&pp->lock, flags);
 	if (pp->flags & PARPORT_FLAG_COMA)
 		goto out_ok;
 
-	if (newirq != PARPORT_IRQ_NONE) { 
-		void (*handler)(int, void *, struct pt_regs *);
+	retval = -EBUSY;
+	if (pp->cad)
+		goto out_unlock;
 
-		if (cad && cad->irq_func)
-			handler = cad->irq_func;
-		else
-			handler = parport_null_intr_func;
-
-		retval = request_irq(newirq, handler,
-				     SA_INTERRUPT,
-				     cad ? cad->name : pp->name,
-				     cad ? cad->private : NULL);
+	if (newirq != PARPORT_IRQ_NONE) { 
+		retval = request_irq(newirq, parport_null_intr_func,
+				     SA_INTERRUPT, pp->name, NULL);
 		if (retval)
-			goto out;
+			goto out_unlock;
 		else retval = count;
 	}
 
-	if (oldirq != PARPORT_IRQ_NONE) {
-		if (cad && cad->irq_func)
-			free_irq(oldirq, cad->private);
-		else
-			free_irq(oldirq, NULL);
-	}
+	if (oldirq != PARPORT_IRQ_NONE)
+		free_irq(oldirq, NULL);
 
 out_ok:
 	pp->irq = newirq;
+
+out_unlock:
+	spin_unlock_irqrestore (&pp->lock, flags);
 
 out:
 	return retval;
diff -u --recursive --new-file v2.1.99/linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c
--- v2.1.99/linux/drivers/misc/parport_share.c	Sat Apr 25 18:13:11 1998
+++ linux/drivers/misc/parport_share.c	Mon May  4 11:03:09 1998
@@ -308,7 +308,9 @@
 	}
 
 	/* Now we do the change of devices */
+	spin_lock_irqsave(&port->lock, flags);
 	port->cad = dev;
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	/* Swap the IRQ handlers. */
 	if (port->irq != PARPORT_IRQ_NONE) {
@@ -346,9 +348,8 @@
 			dev->waitprev = port->waittail;
 			if (port->waittail)
 				port->waittail->waitnext = dev;
-			else {
-				port->waithead = dev->port->waittail = dev;
-			}
+			else
+				port->waithead = port->waittail = dev;
 		}
 		spin_unlock_irqrestore (&port->lock, flags);
 	}
diff -u --recursive --new-file v2.1.99/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v2.1.99/linux/drivers/net/3c509.c	Mon Feb 23 18:12:05 1998
+++ linux/drivers/net/3c509.c	Thu May  7 14:40:41 1998
@@ -1,8 +1,8 @@
 /* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
 /*
-	Written 1993-1995 by Donald Becker.
+	Written 1993-1997 by Donald Becker.
 
-	Copyright 1994,1995 by Donald Becker.
+	Copyright 1994-1997 by Donald Becker.
 	Copyright 1993 United States Government as represented by the
 	Director, National Security Agency.	 This software may be used and
 	distributed according to the terms of the GNU Public License,
@@ -27,10 +27,22 @@
 	FIXES:
 		Alan Cox:       Removed the 'Unexpected interrupt' bug.
 		Michael Meskes:	Upgraded to Donald Becker's version 1.07.
-		Phil Blundell:  Media selection support.
+		Alan Cox:	Increased the eeprom delay. Regardless of 
+				what the docs say some people definitely
+				get problems with lower (but in card spec)
+				delays
+		v1.10 4/21/97 Fixed module code so that multiple cards may be detected,
+				other cleanups.  -djb
+		Andrea Arcangeli:	Upgraded to Donald Becker's version 1.12.
 */
 
-static char *version = "3c509.c:1.07 6/15/95 becker@cesdis.gsfc.nasa.gov\n";
+static char *version = "3c509.c:1.12 6/4/97 becker@cesdis.gsfc.nasa.gov\n";
+/* A few values that may be tweaked. */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (400*HZ/1000)
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+#define INTR_WORK      10
 
 #include <linux/module.h>
 
@@ -48,20 +60,19 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>	/* for udelay() */
-#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
 
 #ifdef EL3_DEBUG
-static int el3_debug = EL3_DEBUG;
+int el3_debug = EL3_DEBUG;
 #else
-static int el3_debug = 2;
+int el3_debug = 2;
 #endif
 
 /* To minimize the size of the driver source I only define operating
    constants if they are used several times.  You'll need the manual
-   if you want to understand driver details. */
+   anyway if you want to understand driver details. */
 /* Offsets from base I/O address. */
 #define EL3_DATA 0x00
 #define EL3_CMD 0x0e
@@ -111,12 +122,14 @@
 #define SKB_QUEUE_SIZE	64
 
 struct el3_private {
-	struct net_device_stats stats;
+	struct enet_statistics stats;
+	struct device *next_dev;
 	/* skb send-queue */
 	int head, size;
 	struct sk_buff *queue[SKB_QUEUE_SIZE];
 };
 static int id_port = 0x100;
+static struct device *el3_root_dev = NULL;
 
 static ushort id_read_eeprom(int index);
 static ushort read_eeprom(short ioaddr, int index);
@@ -124,28 +137,19 @@
 static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
 static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void update_stats(int addr, struct device *dev);
-static struct net_device_stats *el3_get_stats(struct device *dev);
+static struct enet_statistics *el3_get_stats(struct device *dev);
 static int el3_rx(struct device *dev);
 static int el3_close(struct device *dev);
-static int el3_set_config(struct device *dev, struct ifmap *map);
-#ifdef HAVE_MULTICAST
 static void set_multicast_list(struct device *dev);
-#endif
 
 
 
-__initfunc(int el3_probe(struct device *dev))
+int el3_probe(struct device *dev)
 {
 	short lrs_state = 0xff, i;
-	ushort ioaddr, irq, port;
-	short *phys_addr = (short *)dev->dev_addr;
+	ushort ioaddr, irq, if_port;
+	short phys_addr[3];
 	static int current_tag = 0;
-	static int el3_portmap[] = { 
-	  IF_PORT_10BASET, 
-	  IF_PORT_AUI, 
-	  IF_PORT_UNKNOWN, 
-	  IF_PORT_10BASE2 
-	};
 
 	/* First check all slots of the EISA bus.  The next slot address to
 	   probe is kept in 'eisa_addr' to support multiple probe() calls. */
@@ -163,7 +167,7 @@
 			outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
 
 			irq = inw(ioaddr + WN0_IRQ) >> 12;
-			port = inw(ioaddr + 6)>>14;
+			if_port = inw(ioaddr + 6)>>14;
 			for (i = 0; i < 3; i++)
 				phys_addr[i] = htons(read_eeprom(ioaddr, i));
 
@@ -175,18 +179,14 @@
 		}
 	}
 
-/*
- * This has to be coded according to Documentation/mca.txt before
- * this driver can be used with the 3c529 MCA cards.
- */
-#if 0 /* #ifdef CONFIG_MCA */
+#ifdef CONFIG_MCA
 	if (MCA_bus) {
 		mca_adaptor_select_mode(1);
 		for (i = 0; i < 8; i++)
 			if ((mca_adaptor_id(i) | 1) == 0x627c) {
 				ioaddr = mca_pos_base_addr(i);
 				irq = inw(ioaddr + WN0_IRQ) >> 12;
-				port = inw(ioaddr + 6)>>14;
+				if_port = inw(ioaddr + 6)>>14;
 				for (i = 0; i < 3; i++)
 					phys_addr[i] = htons(read_eeprom(ioaddr, i));
 
@@ -203,6 +203,8 @@
 	outb(0x02, 0xA79);           /* Return to WaitForKey state. */
 	/* Select an open I/O location at 0x1*0 to do contention select. */
 	for (id_port = 0x100; id_port < 0x200; id_port += 0x10) {
+		if (check_region(id_port, 1))
+			continue;
 		outb(0x00, id_port);
 		outb(0xff, id_port);
 		if (inb(id_port) & 0x01)
@@ -218,13 +220,6 @@
 	   on cards as they are found.  Cards with their tag set will not
 	   respond to subsequent ID sequences. */
 
-	if (check_region(id_port,1)) {
-	  static int once = 1;
-	  if (once) printk("3c509: Somebody has reserved 0x%x, can't do ID_PORT lookup, nor card auto-probing\n",id_port);
-          once = 0;
-          return -ENODEV;
-        }
-
 	outb(0x00, id_port);
 	outb(0x00, id_port);
 	for(i = 0; i < 255; i++) {
@@ -252,16 +247,16 @@
 
 	{
 		unsigned short iobase = id_read_eeprom(8);
-		port = iobase >> 14;
+		if_port = iobase >> 14;
 		ioaddr = 0x200 + ((iobase & 0x1f) << 4);
 	}
-	if (dev->irq > 1  &&  dev->irq < 16)
+	if (dev  &&  dev->irq > 1  &&  dev->irq < 16)
 		irq = dev->irq;
 	else
 		irq = id_read_eeprom(9) >> 12;
 
-	if (dev->base_addr != 0
-		&&      dev->base_addr != (unsigned short)ioaddr) {
+	if (dev  &&  dev->base_addr != 0
+		&&  dev->base_addr != (unsigned short)ioaddr) {
 		return -ENODEV;
 	}
 
@@ -278,15 +273,20 @@
 	/* Free the interrupt so that some other card can use it. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
  found:
+	if (dev == NULL) {
+		dev = init_etherdev(dev, sizeof(struct el3_private));
+	}
+	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
-	dev->if_port = el3_portmap[port];
+	dev->if_port = (dev->mem_start & 0x1f) ? dev->mem_start & 3 : if_port;
+
 	request_region(dev->base_addr, EL3_IO_EXTENT, "3c509");
 
 	{
-		static const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
+		const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
 		printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ",
-			   dev->name, dev->base_addr, current_tag, if_names[port]);
+			   dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
 	}
 
 	/* Read in the station address. */
@@ -295,11 +295,15 @@
 	printk(", IRQ %d.\n", dev->irq);
 
 	/* Make up a EL3-specific-data structure. */
-	dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
+	if (dev->priv == NULL)
+		dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
 	if (dev->priv == NULL)
 		return -ENOMEM;
 	memset(dev->priv, 0, sizeof(struct el3_private));
 
+	((struct el3_private *)dev->priv)->next_dev = el3_root_dev;
+	el3_root_dev = dev;
+
 	if (el3_debug > 0)
 		printk(version);
 
@@ -308,30 +312,26 @@
 	dev->hard_start_xmit = &el3_start_xmit;
 	dev->stop = &el3_close;
 	dev->get_stats = &el3_get_stats;
-	dev->set_config = &el3_set_config;
-#ifdef HAVE_MULTICAST
-		dev->set_multicast_list = &set_multicast_list;
-#endif
+	dev->set_multicast_list = &set_multicast_list;
 
 	/* Fill in the generic fields of the device structure. */
 	ether_setup(dev);
-	dev->flags |= IFF_PORTSEL;
 	return 0;
 }
 
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
  */
-__initfunc(static ushort read_eeprom(short ioaddr, int index))
+static ushort read_eeprom(short ioaddr, int index)
 {
 	outw(EEPROM_READ + index, ioaddr + 10);
 	/* Pause for at least 162 us. for the read to take place. */
-	udelay (300);
+	udelay (500);
 	return inw(ioaddr + 12);
 }
 
 /* Read a word from the EEPROM when in the ISA ID probe state. */
-__initfunc(static ushort id_read_eeprom(int index))
+static ushort id_read_eeprom(int index)
 {
 	int bit, word = 0;
 
@@ -340,8 +340,8 @@
 	outb(EEPROM_READ + index, id_port);
 
 	/* Pause for at least 162 us. for the read to take place. */
-	udelay (300);
-
+	udelay (500);
+	
 	for (bit = 15; bit >= 0; bit--)
 		word = (word << 1) + (inb(id_port) & 0x01);
 
@@ -354,59 +354,6 @@
 
 
 static int
-el3_set_config(struct device *dev, struct ifmap *map)
-{
-	int ioaddr = dev->base_addr;
-    if (map->port != dev->if_port) {
-	  switch (map->port) {
-	  case IF_PORT_10BASE2:
-	  case IF_PORT_10BASET:
-	  case IF_PORT_AUI:
-		if (dev->start) {
-		  if (dev->if_port == IF_PORT_10BASE2)
-			/* Turn off thinnet power. */
-			outw(StopCoax, ioaddr + EL3_CMD);
-		  else if (dev->if_port == IF_PORT_10BASET) {
-			/* Disable link beat and jabber */
-			EL3WINDOW(4);
-			outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
-			EL3WINDOW(1);
-		  }
-		}
-		printk(KERN_INFO "%s: %s port selected.\n", dev->name, 
-			   if_port_text[map->port]);
-		dev->if_port = map->port;
-		if (dev->start) {
-		  if (dev->if_port == IF_PORT_10BASE2)
-			/* Start the thinnet transceiver. We should really wait 50ms...*/
-			outw(StartCoax, ioaddr + EL3_CMD);
-		  else if (dev->if_port == IF_PORT_10BASET) {
-			/* 10baseT interface, enabled link beat and jabber check. */
-			EL3WINDOW(4);
-			outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
-			EL3WINDOW(1);
-		  }
-		}
-		break;
-	  default:
-		printk(KERN_ERR "%s: %s port not supported.\n", dev->name, 
-			   if_port_text[map->port]);
-		return -EINVAL;
-	  }
-	}
-	if (map->irq != dev->irq) {
-	  printk(KERN_ERR "%s: cannot change interrupt.\n", dev->name);
-	  return -EINVAL;
-	}
-	if (map->base_addr != dev->base_addr) {
-	  printk(KERN_ERR "%s: cannot change base address.\n", dev->name);
-	  return -EINVAL;
-	}
-	return 0;
-}
-
-
-static int
 el3_open(struct device *dev)
 {
 	int ioaddr = dev->base_addr;
@@ -437,10 +384,10 @@
 	for (i = 0; i < 6; i++)
 		outb(dev->dev_addr[i], ioaddr + i);
 
-	if (dev->if_port == IF_PORT_10BASE2)
+	if (dev->if_port == 3)
 		/* Start the thinnet transceiver. We should really wait 50ms...*/
 		outw(StartCoax, ioaddr + EL3_CMD);
-	else if (dev->if_port == IF_PORT_10BASET) {
+	else if (dev->if_port == 0) {
 		/* 10baseT interface, enabled link beat and jabber check. */
 		EL3WINDOW(4);
 		outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
@@ -483,7 +430,8 @@
 	return 0;					/* Always succeed */
 }
 
-static int el3_start_xmit(struct sk_buff *skb, struct device *dev)
+static int
+el3_start_xmit(struct sk_buff *skb, struct device *dev)
 {
 	struct el3_private *lp = (struct el3_private *)dev->priv;
 	int ioaddr = dev->base_addr;
@@ -491,7 +439,7 @@
 	/* Transmitter timeout, serious problems. */
 	if (dev->tbusy) {
 		int tickssofar = jiffies - dev->trans_start;
-		if (tickssofar < 40*HZ/100)
+		if (tickssofar < TX_TIMEOUT)
 			return 1;
 		printk("%s: transmit timed out, Tx_status %2.2x status %4.4x "
 			   "Tx FIFO room %d.\n",
@@ -532,12 +480,15 @@
 	if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
 		printk("%s: Transmitter access conflict.\n", dev->name);
 	else {
-		lp->stats.tx_bytes+=skb->len;
 		/* Put out the doubleword header... */
 		outw(skb->len, ioaddr + TX_FIFO);
 		outw(0x00, ioaddr + TX_FIFO);
 		/* ... and the packet rounded to a doubleword. */
+#ifdef  __powerpc__
+		outsl_unswapped(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+#else
 		outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+#endif
 
 		dev->trans_start = jiffies;
 		if (inw(ioaddr + TX_FREE) > 1536) {
@@ -570,7 +521,7 @@
 {
 	struct device *dev = (struct device *)dev_id;
 	int ioaddr, status;
-	int i = 0;
+	int i = INTR_WORK;
 
 	if (dev == NULL) {
 		printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
@@ -622,7 +573,7 @@
 			}
 		}
 
-		if (++i > 10) {
+		if (--i < 0) {
 			printk("%s: Infinite loop in interrupt, status %4.4x.\n",
 				   dev->name, status);
 			/* Clear all interrupts. */
@@ -643,7 +594,8 @@
 }
 
 
-static struct net_device_stats *el3_get_stats(struct device *dev)
+static struct enet_statistics *
+el3_get_stats(struct device *dev)
 {
 	struct el3_private *lp = (struct el3_private *)dev->priv;
 	unsigned long flags;
@@ -720,18 +672,21 @@
 					   pkt_len, rx_status);
 			if (skb != NULL) {
 				skb->dev = dev;
-				skb_reserve(skb,2);     /* Align IP on 16 byte */
+				skb_reserve(skb, 2);     /* Align IP on 16 byte */
 
 				/* 'skb->data' points to the start of sk_buff data area. */
-				insl(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
-							(pkt_len + 3) >> 2);
+#ifdef  __powerpc__
+				insl_unswapped(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
+							   (pkt_len + 3) >> 2);
+#else
+				insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
+					 (pkt_len + 3) >> 2);
+#endif
 
-				skb->protocol=eth_type_trans(skb,dev);
+				skb->protocol = eth_type_trans(skb,dev);
 				netif_rx(skb);
 				outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
-				lp->stats.rx_bytes+=skb->len;
 				lp->stats.rx_packets++;
-				lp->stats.rx_bytes+=pkt_len;
 				continue;
 			} else if (el3_debug)
 				printk("%s: Couldn't allocate a sk_buff of size %d.\n",
@@ -747,7 +702,6 @@
 	return 0;
 }
 
-#ifdef HAVE_MULTICAST
 /*
  *     Set or clear the multicast filter for this adaptor.
  */
@@ -772,7 +726,6 @@
 	else
                 outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
 }
-#endif
 
 static int
 el3_close(struct device *dev)
@@ -792,10 +745,10 @@
 	outw(RxDisable, ioaddr + EL3_CMD);
 	outw(TxDisable, ioaddr + EL3_CMD);
 
-	if (dev->if_port == IF_PORT_10BASE2)
+	if (dev->if_port == 3)
 		/* Turn off thinnet power.  Green! */
 		outw(StopCoax, ioaddr + EL3_CMD);
-	else if (dev->if_port == IF_PORT_10BASET) {
+	else if (dev->if_port == 0) {
 		/* Disable link beat and jabber, if_port may change ere next open(). */
 		EL3WINDOW(4);
 		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
@@ -813,69 +766,50 @@
 }
 
 #ifdef MODULE
-#define MAX_3C_CARDS	4	/* Max number of NE cards per module */
-#define NAMELEN		8	/* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_3C_CARDS] = { 0, };
-static struct device dev_3c509[MAX_3C_CARDS] = {
-	{
-		NULL,		/* assign a chunk of namelist[] below */
-		0, 0, 0, 0,
-		0, 0,
-		0, 0, 0, NULL, NULL
-	},
-};
-
-static int io[MAX_3C_CARDS] = { 0, };
-static int irq[MAX_3C_CARDS]  = { 0, };
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C_CARDS) "i");
+/* Parameter that may be passed into the module. */
+static int debug = -1;
+static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 
 int
 init_module(void)
 {
-	int this_dev, found = 0;
+	int el3_cards = 0;
 
-	for (this_dev = 0; this_dev < MAX_3C_CARDS; this_dev++) {
-		struct device *dev = &dev_3c509[this_dev];
-		dev->name = namelist+(NAMELEN*this_dev);
-		dev->irq = irq[this_dev];
-		dev->base_addr = io[this_dev];
-		dev->init = el3_probe;
-		if (io[this_dev] == 0)  {
-			if (this_dev != 0) break; /* only complain once */
-			printk("3c509: WARNING! Module load-time probing works reliably only for EISA bus!!\n");
-		}
-		if (register_netdev(dev) != 0) {
-			printk(KERN_WARNING "3c509.c: No 3c509 card found (i/o = 0x%x).\n", io[this_dev]);
-			if (found != 0) return 0;	/* Got at least one. */
-			return -ENXIO;
-		}
-		found++;
+	if (debug >= 0)
+		el3_debug = debug;
+
+	el3_root_dev = NULL;
+	while (el3_probe(0) == 0) {
+		if (irq[el3_cards] > 1)
+			el3_root_dev->irq = irq[el3_cards];
+		if (xcvr[el3_cards] >= 0)
+			el3_root_dev->if_port = xcvr[el3_cards];
+		el3_cards++;
 	}
-	return 0;
+
+	return el3_cards ? 0 : -ENODEV;
 }
 
 void
 cleanup_module(void)
 {
-	int this_dev;
+	struct device *next_dev;
 
-	for (this_dev = 0; this_dev < MAX_3C_CARDS; this_dev++) {
-		struct device *dev = &dev_3c509[this_dev];
-		if (dev->priv != NULL) {
-			unregister_netdev(dev);
-			kfree_s(dev->priv,sizeof(struct el3_private));
-			dev->priv = NULL;
-			free_irq(dev->irq, dev);
-			release_region(dev->base_addr, EL3_IO_EXTENT);
-		}
+	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+	while (el3_root_dev) {
+		next_dev = ((struct el3_private *)el3_root_dev->priv)->next_dev;
+		unregister_netdev(el3_root_dev);
+		release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
+		kfree(el3_root_dev);
+		el3_root_dev = next_dev;
 	}
 }
 #endif /* MODULE */
 
 /*
  * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c509.c"
+ *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c509.c"
  *  version-control: t
  *  kept-new-versions: 5
  *  tab-width: 4
diff -u --recursive --new-file v2.1.99/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.1.99/linux/drivers/net/3c59x.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/net/3c59x.c	Wed May  6 10:56:04 1998
@@ -1957,7 +1957,7 @@
 		data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
 		return 0;
 	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
-		if (!suser())
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
 		return 0;
diff -u --recursive --new-file v2.1.99/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.1.99/linux/drivers/net/de4x5.c	Wed Apr  8 19:36:26 1998
+++ linux/drivers/net/de4x5.c	Wed May  6 10:56:04 1998
@@ -5487,7 +5487,7 @@
 	if (status)
 	  break;
 	status = -EPERM;
-	if (!suser())
+	if (!capable(CAP_NET_ADMIN))
 	  break;
 	status = 0;
 	copy_from_user(tmp.addr, ioc->data, ETH_ALEN);
@@ -5505,7 +5505,7 @@
 	
 	break;
       case DE4X5_SET_PROM:             /* Set Promiscuous Mode */
-	if (suser()) {
+	if (capable(CAP_NET_ADMIN)) {
 	    omr = inl(DE4X5_OMR);
 	    omr |= OMR_PR;
 	    outl(omr, DE4X5_OMR);
@@ -5516,7 +5516,7 @@
 	
 	break;
       case DE4X5_CLR_PROM:             /* Clear Promiscuous Mode */
-	if (suser()) {
+	if (capable(CAP_NET_ADMIN)) {
 	    omr = inl(DE4X5_OMR);
 	    omr &= ~OMR_PR;
 	    outb(omr, DE4X5_OMR);
@@ -5531,7 +5531,7 @@
 	
 	break;
       case DE4X5_MCA_EN:               /* Enable pass all multicast addressing */
-	if (suser()) {
+	if (capable(CAP_NET_ADMIN)) {
 	    omr = inl(DE4X5_OMR);
 	    omr |= OMR_PM;
 	    outl(omr, DE4X5_OMR);
@@ -5552,7 +5552,7 @@
 	
 	break;
       case DE4X5_CLR_STATS:            /* Zero out the driver statistics */
-	if (suser()) {
+	if (capable(CAP_NET_ADMIN)) {
 	    cli();
 	    memset(&lp->pktStats, 0, sizeof(lp->pktStats));
 	    sti();
@@ -5569,7 +5569,7 @@
 	
 	break;
       case DE4X5_SET_OMR:              /* Set the OMR Register contents */
-	if (suser()) {
+	if (capable(CAP_NET_ADMIN)) {
 	    if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, 1))) {
 		copy_from_user(tmp.addr, ioc->data, 1);
 		outl(tmp.addr[0], DE4X5_OMR);
diff -u --recursive --new-file v2.1.99/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v2.1.99/linux/drivers/net/depca.c	Thu Feb 12 20:56:08 1998
+++ linux/drivers/net/depca.c	Wed May  6 10:56:04 1998
@@ -1714,7 +1714,7 @@
 		}
 		break;
 	case DEPCA_SET_HWADDR:	/* Set the hardware address */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			if (!(status = verify_area(VERIFY_READ, (void *) ioc->data, ETH_ALEN))) {
 				copy_from_user(tmp.addr, ioc->data, ETH_ALEN);
 				for (i = 0; i < ETH_ALEN; i++) {
@@ -1736,7 +1736,7 @@
 
 		break;
 	case DEPCA_SET_PROM:	/* Set Promiscuous Mode */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			while (dev->tbusy);	/* Stop ring access */
 			set_bit(0, (void *) &dev->tbusy);
 			while (lp->tx_old != lp->tx_new);	/* Wait for the ring to empty */
@@ -1754,7 +1754,7 @@
 
 		break;
 	case DEPCA_CLR_PROM:	/* Clear Promiscuous Mode */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			while (dev->tbusy);	/* Stop ring access */
 			set_bit(0, (void *) &dev->tbusy);
 			while (lp->tx_old != lp->tx_new);	/* Wait for the ring to empty */
@@ -1782,7 +1782,7 @@
 		}
 		break;
 	case DEPCA_SET_MCA:	/* Set a multicast address */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			if (!(status = verify_area(VERIFY_READ, ioc->data, ETH_ALEN * ioc->len))) {
 				copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
 				set_multicast_list(dev);
@@ -1793,7 +1793,7 @@
 
 		break;
 	case DEPCA_CLR_MCA:	/* Clear all multicast addresses */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			set_multicast_list(dev);
 		} else {
 			status = -EPERM;
@@ -1801,7 +1801,7 @@
 
 		break;
 	case DEPCA_MCA_EN:	/* Enable pass all multicast addressing */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			set_multicast_list(dev);
 		} else {
 			status = -EPERM;
@@ -1818,7 +1818,7 @@
 
 		break;
 	case DEPCA_CLR_STATS:	/* Zero out the driver statistics */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			cli();
 			memset(&lp->pktStats, 0, sizeof(lp->pktStats));
 			sti();
diff -u --recursive --new-file v2.1.99/linux/drivers/net/dlci.c linux/drivers/net/dlci.c
--- v2.1.99/linux/drivers/net/dlci.c	Mon Feb 23 18:12:05 1998
+++ linux/drivers/net/dlci.c	Wed May  6 10:56:04 1998
@@ -322,7 +322,7 @@
 {
 	struct dlci_local *dlp;
 
-	if (!suser())
+	if (!capable(CAP_NET_ADMIN))
 		return(-EPERM);
 
 	dlp = dev->priv;
@@ -542,7 +542,7 @@
 	struct dlci_add add;
 	int err;
 	
-	if (!suser())
+	if (!capable(CAP_NET_ADMIN))
 		return(-EPERM);
 
 	if(copy_from_user(&add, arg, sizeof(struct dlci_add)))
diff -u --recursive --new-file v2.1.99/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.1.99/linux/drivers/net/eepro100.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/net/eepro100.c	Wed May  6 10:56:04 1998
@@ -1528,7 +1528,7 @@
 		data[3] = mdio_read(ioaddr, data[0], data[1]);
 		return 0;
 	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
-		if (!suser())
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		mdio_write(ioaddr, data[0], data[1], data[2]);
 		return 0;
diff -u --recursive --new-file v2.1.99/linux/drivers/net/eql.c linux/drivers/net/eql.c
--- v2.1.99/linux/drivers/net/eql.c	Thu Feb 12 20:56:08 1998
+++ linux/drivers/net/eql.c	Wed May  6 10:56:04 1998
@@ -329,7 +329,8 @@
 
 static int eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
 {  
-	if(cmd!=EQL_GETMASTRCFG && cmd!=EQL_GETSLAVECFG && !suser())
+	if(cmd!=EQL_GETMASTRCFG && cmd!=EQL_GETSLAVECFG && 
+	   !capable(CAP_NET_ADMIN))
 	  	return -EPERM;
 	switch (cmd)
 	{
diff -u --recursive --new-file v2.1.99/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v2.1.99/linux/drivers/net/ewrk3.c	Mon Feb 23 18:12:05 1998
+++ linux/drivers/net/ewrk3.c	Wed May  6 10:56:04 1998
@@ -1684,7 +1684,7 @@
 		}
 		break;
 	case EWRK3_SET_HWADDR:	/* Set the hardware address */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			if (!(status = verify_area(VERIFY_READ, (void *) ioc->data, ETH_ALEN))) {
 				csr = inb(EWRK3_CSR);
 				csr |= (CSR_TXD | CSR_RXD);
@@ -1705,7 +1705,7 @@
 
 		break;
 	case EWRK3_SET_PROM:	/* Set Promiscuous Mode */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			csr = inb(EWRK3_CSR);
 			csr |= CSR_PME;
 			csr &= ~CSR_MCE;
@@ -1716,7 +1716,7 @@
 
 		break;
 	case EWRK3_CLR_PROM:	/* Clear Promiscuous Mode */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			csr = inb(EWRK3_CSR);
 			csr &= ~CSR_PME;
 			outb(csr, EWRK3_CSR);
@@ -1749,7 +1749,7 @@
 
 		break;
 	case EWRK3_SET_MCA:	/* Set a multicast address */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			if (!(status = verify_area(VERIFY_READ, ioc->data, ETH_ALEN * ioc->len))) {
 				copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
 				set_multicast_list(dev);
@@ -1760,7 +1760,7 @@
 
 		break;
 	case EWRK3_CLR_MCA:	/* Clear all multicast addresses */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			set_multicast_list(dev);
 		} else {
 			status = -EPERM;
@@ -1768,7 +1768,7 @@
 
 		break;
 	case EWRK3_MCA_EN:	/* Enable multicast addressing */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			csr = inb(EWRK3_CSR);
 			csr |= CSR_MCE;
 			csr &= ~CSR_PME;
@@ -1788,7 +1788,7 @@
 
 		break;
 	case EWRK3_CLR_STATS:	/* Zero out the driver statistics */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			cli();
 			memset(&lp->pktStats, 0, sizeof(lp->pktStats));
 			sti();
@@ -1805,7 +1805,7 @@
 		}
 		break;
 	case EWRK3_SET_CSR:	/* Set the CSR Register contents */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			if (!(status = verify_area(VERIFY_READ, ioc->data, 1))) {
 				copy_from_user(tmp.addr, ioc->data, 1);
 				outb(tmp.addr[0], EWRK3_CSR);
@@ -1816,7 +1816,7 @@
 
 		break;
 	case EWRK3_GET_EEPROM:	/* Get the EEPROM contents */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			for (i = 0; i < (EEPROM_MAX >> 1); i++) {
 				tmp.val[i] = (short) Read_EEPROM(iobase, i);
 			}
@@ -1835,7 +1835,7 @@
 
 		break;
 	case EWRK3_SET_EEPROM:	/* Set the EEPROM contents */
-		if (suser()) {
+		if (capable(CAP_NET_ADMIN)) {
 			if (!(status = verify_area(VERIFY_READ, ioc->data, EEPROM_MAX))) {
 				copy_from_user(tmp.addr, ioc->data, EEPROM_MAX);
 				for (i = 0; i < (EEPROM_MAX >> 1); i++) {
diff -u --recursive --new-file v2.1.99/linux/drivers/net/ipddp.c linux/drivers/net/ipddp.c
--- v2.1.99/linux/drivers/net/ipddp.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/net/ipddp.c	Wed May  6 10:56:04 1998
@@ -307,7 +307,7 @@
 {
         struct ipddp_route *rt = (struct ipddp_route *)ifr->ifr_data;
 
-        if(!suser())
+        if(!capable(CAP_NET_ADMIN))
                 return -EPERM;
 
         switch(cmd)
diff -u --recursive --new-file v2.1.99/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v2.1.99/linux/drivers/net/ppp.c	Wed Apr  1 20:11:52 1998
+++ linux/drivers/net/ppp.c	Wed May  6 10:56:04 1998
@@ -8,7 +8,7 @@
  *  Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
  *  ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
  *
- *  ==FILEVERSION 980319==
+ *  ==FILEVERSION 980501==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the number above to the
@@ -107,8 +107,10 @@
 #define PPP_LQR 0xc025	/* Link Quality Reporting Protocol */
 #endif
 
+#ifdef CONFIG_MODULES
 static int ppp_register_compressor (struct compressor *cp);
 static void ppp_unregister_compressor (struct compressor *cp);
+#endif
 
 /*
  * Local functions
@@ -2279,7 +2281,7 @@
 /*
  * The user must have an euid of root to do these requests.
  */
-	if (!suser ())
+	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 /*
  * Set the MRU value
@@ -3210,6 +3212,7 @@
 	return (struct compressor *) 0;
 }
 
+#ifdef CONFIG_MODULES
 static int ppp_register_compressor (struct compressor *cp)
 {
 	struct compressor_link *new;
@@ -3261,6 +3264,7 @@
 	}
 	restore_flags(flags);
 }
+#endif
 
 /*************************************************************
  * Module support routines
diff -u --recursive --new-file v2.1.99/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c
--- v2.1.99/linux/drivers/net/sdla_fr.c	Wed Apr  8 19:36:27 1998
+++ linux/drivers/net/sdla_fr.c	Sat May  2 14:22:29 1998
@@ -831,7 +831,7 @@
 {
 	int hdr_len = 0;
 	skb->protocol = type;
-	hdr_len = wan_encapsulate(skb, dev);
+	hdr_len = wanrouter_encapsulate(skb, dev);
 	if (hdr_len < 0) 
 	{
 		hdr_len = 0;
@@ -1486,7 +1486,7 @@
 		/* Decapsulate packet and pass it up the protocol stack */
 		skb->dev = dev;
 		buf = skb_pull(skb, 1);		/* remove hardware header */
-		if (!wan_type_trans(skb, dev)) 
+		if (!wanrouter_type_trans(skb, dev)) 
 		{
 			/* can't decapsulate packet */
 			dev_kfree_skb(skb);
@@ -1601,7 +1601,7 @@
 					skb->dev = dev;
 					/* remove hardware header */
 					buf = skb_pull(skb, 1);
-					if (!wan_type_trans(skb, dev)) 
+					if (!wanrouter_type_trans(skb, dev)) 
 					{
 						/* can't decapsulate packet */
 						dev_kfree_skb(skb);
@@ -2746,7 +2746,7 @@
 			   stack */
 			new_skb->dev = dev;
 			buf = skb_pull(new_skb, 1);	/* remove hardware header */
-			if (!wan_type_trans(new_skb, dev)) 
+			if (!wanrouter_type_trans(new_skb, dev)) 
 			{
 				++chan->UDP_FPIPE_mgmt_not_passed_to_stack;
 				/* can't decapsulate packet */
@@ -2944,7 +2944,7 @@
 			new_skb->dev = dev;
 			/* remove hardware header */
 			buf = skb_pull(new_skb, 1);
-			if (!wan_type_trans(new_skb, dev)) 
+			if (!wanrouter_type_trans(new_skb, dev)) 
 			{
 				/* can't decapsulate packet */
 				++chan->UDP_DRVSTATS_mgmt_not_passed_to_stack;
diff -u --recursive --new-file v2.1.99/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c
--- v2.1.99/linux/drivers/net/sdla_x25.c	Wed Apr  8 19:36:27 1998
+++ linux/drivers/net/sdla_x25.c	Sat May  2 14:22:29 1998
@@ -649,7 +649,7 @@
 	skb->protocol = type;
 	if (!chan->protocol)
 	{
-		hdr_len = wan_encapsulate(skb, dev);
+		hdr_len = wanrouter_encapsulate(skb, dev);
 		if (hdr_len < 0)
 		{
 			hdr_len = 0;
@@ -999,7 +999,7 @@
 	chan->rx_skb = NULL;		/* dequeue packet */
 
 	/* Decapsulate packet, if necessary */
-	if (!skb->protocol && !wan_type_trans(skb, dev))
+	if (!skb->protocol && !wanrouter_type_trans(skb, dev))
 	{
 		/* can't decapsulate packet */
 		dev_kfree_skb(skb);
diff -u --recursive --new-file v2.1.99/linux/drivers/net/sdlamain.c linux/drivers/net/sdlamain.c
--- v2.1.99/linux/drivers/net/sdlamain.c	Mon Jan 12 14:46:16 1998
+++ linux/drivers/net/sdlamain.c	Sat May  2 14:22:29 1998
@@ -152,7 +152,7 @@
 		wandev->setup    = &setup;
 		wandev->shutdown = &shutdown;
 		wandev->ioctl    = &ioctl;
-		err = register_wandev(wandev);
+		err = register_wan_device(wandev);
 		if (err)
 		{
 			printk(KERN_ERR
@@ -179,7 +179,7 @@
 	for (i = 0; i < ncards; ++i)
 	{
 		sdla_t* card = &card_array[i];
-		unregister_wandev(card->devname);
+		unregister_wan_device(card->devname);
 	}
 	kfree(card_array);
 }
diff -u --recursive --new-file v2.1.99/linux/drivers/net/smc-mca.c linux/drivers/net/smc-mca.c
--- v2.1.99/linux/drivers/net/smc-mca.c	Wed Apr  1 20:11:52 1998
+++ linux/drivers/net/smc-mca.c	Sat May  2 14:22:29 1998
@@ -337,7 +337,7 @@
 		dev->name = namelist+(NAMELEN*this_dev);
 		dev->irq = irq[this_dev];
 		dev->base_addr = io[this_dev];
-		dev->init = ultra_probe;
+		dev->init = ultramca_probe;
 		if (io[this_dev] == 0)
 		{
 			if (this_dev != 0)
diff -u --recursive --new-file v2.1.99/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- v2.1.99/linux/drivers/pci/oldproc.c	Fri Apr 10 13:03:48 1998
+++ linux/drivers/pci/oldproc.c	Mon May  4 13:24:12 1998
@@ -1,5 +1,5 @@
 /*
- *	$Id: oldproc.c,v 1.10 1998/03/15 13:50:11 ecd Exp $
+ *	$Id: oldproc.c,v 1.12 1998/05/01 10:58:21 mj Exp $
  *
  *	Backward-compatible procfs interface for PCI.
  *
@@ -60,10 +60,14 @@
 	DEVICE( ATI,		ATI_210888CX,   "210888CX"),
 	DEVICE( ATI,		ATI_215GB,	"Mach64 GB"),
 	DEVICE( ATI,		ATI_215GD,	"Mach64 GD (Rage Pro)"),
+	DEVICE( ATI,		ATI_215GI,	"Mach64 GI (Rage Pro)"),
 	DEVICE( ATI,		ATI_215GP,	"Mach64 GP (Rage Pro)"),
+	DEVICE( ATI,		ATI_215GQ,	"Mach64 GQ (Rage Pro)"),
 	DEVICE( ATI,		ATI_215GT,	"Mach64 GT (Rage II)"),
 	DEVICE( ATI,		ATI_215GTB,	"Mach64 GT (Rage II)"),
 	DEVICE( ATI,		ATI_210888GX,   "210888GX"),
+	DEVICE( ATI,		ATI_215LG,	"Mach64 LG (Rage Pro)"),
+	DEVICE( ATI,		ATI_264LT,	"Mach64 LT"),
 	DEVICE( ATI,		ATI_264VT,	"Mach64 VT"),
 	DEVICE( VLSI,		VLSI_82C592,	"82C592-FC1"),
 	DEVICE( VLSI,		VLSI_82C593,	"82C593-FC1"),
@@ -116,6 +120,9 @@
 	DEVICE( IBM,		IBM_82G2675,	"82G2675"),
 	DEVICE( IBM,		IBM_MCA,	"MicroChannel"),
 	DEVICE( IBM,		IBM_82351,	"82351"),
+	DEVICE( IBM,		IBM_SERVERAID,	"ServeRAID"),
+	DEVICE( IBM,		IBM_TR_WAKE,	"Wake On LAN Token Ring"),
+	DEVICE( IBM,		IBM_3780IDSP,	"MWave DSP"),
 	DEVICE( WD,		WD_7197,	"WD 7197"),
 	DEVICE( AMD,		AMD_LANCE,	"79C970"),
 	DEVICE( AMD,		AMD_SCSI,	"53C974"),
@@ -135,12 +142,15 @@
 	DEVICE( CT,		CT_65548,	"65548"),
 	DEVICE(	CT,		CT_65550,	"65550"),
 	DEVICE( CT,		CT_65554,	"65554"),
+	DEVICE( CT,		CT_65555,	"65555"),
 	DEVICE( MIRO,		MIRO_36050,	"ZR36050"),
 	DEVICE( NEC,		NEC_PCX2,	"PowerVR PCX2"),
 	DEVICE( FD,		FD_36C70,	"TMC-18C30"),
-	DEVICE( SI,		SI_6201,	"6201"),
+	DEVICE( SI,		SI_5591_AGP,	"5591/5592 AGP"),
 	DEVICE( SI,		SI_6202,	"6202"),
 	DEVICE( SI,		SI_503,		"85C503"),
+	DEVICE( SI,		SI_ACPI,	"ACPI"),
+	DEVICE( SI,		SI_5597_VGA,	"5597/5598 VGA"),
 	DEVICE( SI,		SI_6205,	"6205"),
 	DEVICE( SI,		SI_501,		"85C501"),
 	DEVICE( SI,		SI_496,		"85C496"),
@@ -149,8 +159,9 @@
 	DEVICE( SI,		SI_5511,		"85C5511"),
 	DEVICE( SI,		SI_5513,		"85C5513"),
 	DEVICE( SI,		SI_5571,	"5571"),
-	DEVICE( SI,		SI_5597,	"5597"),
-	DEVICE( SI,		SI_7001,	"7001"),
+	DEVICE( SI,		SI_5591,	"5591/5592 Host"),
+	DEVICE( SI,		SI_5597,	"5597/5598 Host"),
+	DEVICE( SI,		SI_7001,	"7001 USB"),
 	DEVICE( HP,		HP_J2585A,	"J2585A"),
 	DEVICE( HP,		HP_J2585B,	"J2585B (Lassen)"),
 	DEVICE( PCTECH,		PCTECH_RZ1000,  "RZ1000 (buggy)"),
@@ -198,6 +209,7 @@
 	DEVICE( UMC,		UMC_UM8891N,	"UM8891N"),
 	DEVICE( X,		X_AGX016,	"ITT AGX016"),
 	DEVICE( PICOP,		PICOP_PT86C52X,	"PT86C52x Vesuvius"),
+	DEVICE( PICOP,		PICOP_PT80C524,	"PT80C524 Nile"),
 	DEVICE( APPLE,		APPLE_BANDIT,	"Bandit"),
 	DEVICE( APPLE,		APPLE_GC,	"Grand Central"),
 	DEVICE( APPLE,		APPLE_HYDRA,	"Hydra"),
@@ -242,6 +254,8 @@
 	DEVICE( WINBOND,	WINBOND_83C553,	"W83C553"),
 	DEVICE( DATABOOK,      	DATABOOK_87144,	"DB87144"),
 	DEVICE( PLX,		PLX_9080,	"PCI9080 I2O"),
+	DEVICE( MADGE,		MADGE_MK2,	"Smart 16/4 BM Mk2 Ringnode"),
+	DEVICE( 3COM,		3COM_3C339,	"3C339 TokenRing"),
 	DEVICE( 3COM,		3COM_3C590,	"3C590 10bT"),
 	DEVICE( 3COM,		3COM_3C595TX,	"3C595 100bTX"),
 	DEVICE( 3COM,		3COM_3C595T4,	"3C595 100bT4"),
@@ -249,6 +263,8 @@
 	DEVICE( 3COM,		3COM_3C900TPO,	"3C900 10bTPO"),
 	DEVICE( 3COM,		3COM_3C900COMBO,"3C900 10b Combo"),
 	DEVICE( 3COM,		3COM_3C905TX,	"3C905 100bTX"),
+	DEVICE( 3COM,		3COM_3C905T4,	"3C905 100bT4"),
+	DEVICE( 3COM,		3COM_3C905B_TX,	"3C905B 100bTX"),
 	DEVICE( SMC,		SMC_EPIC100,	"9432 TX"),
 	DEVICE( AL,		AL_M1445,	"M1445"),
 	DEVICE( AL,		AL_M1449,	"M1449"),
@@ -274,6 +290,8 @@
 	DEVICE( ASP,		ASP_ABP940,	"ABP940"),
 	DEVICE( ASP,		ASP_ABP940U,	"ABP940U"),
 	DEVICE( ASP,		ASP_ABP940UW,	"ABP940UW"),
+	DEVICE( MACRONIX,	MACRONIX_MX98713,"MX98713"),
+	DEVICE( MACRONIX,	MACRONIX_MX987x5,"MX98715 / MX98725"),
 	DEVICE( CERN,		CERN_SPSB_PMC,	"STAR/RD24 SCI-PCI (PMC)"),
 	DEVICE( CERN,		CERN_SPSB_PCI,	"STAR/RD24 SCI-PCI (PMC)"),
 	DEVICE( CERN,		CERN_HIPPI_DST,	"HIPPI destination"),
@@ -282,12 +300,14 @@
 	DEVICE( TEKRAM2,	TEKRAM2_690c,	"DC690c"),
 	DEVICE( TUNDRA,		TUNDRA_CA91C042,"CA91C042 Universe"),
 	DEVICE( AMCC,		AMCC_MYRINET,	"Myrinet PCI (M2-PCI-32)"),
+	DEVICE( AMCC,		AMCC_PARASTATION,"ParaStation Interface"),
 	DEVICE( AMCC,		AMCC_S5933,	"S5933 PCI44"),
 	DEVICE( AMCC,		AMCC_S5933_HEPC3,"S5933 Traquair HEPC3"),
 	DEVICE( INTERG,		INTERG_1680,	"IGA-1680"),
 	DEVICE( INTERG,         INTERG_1682,    "IGA-1682"),
 	DEVICE( REALTEK,	REALTEK_8029,	"8029"),
 	DEVICE( REALTEK,	REALTEK_8129,	"8129"),
+	DEVICE( REALTEK,	REALTEK_8139,	"8139"),
 	DEVICE( TRUEVISION,	TRUEVISION_T1000,"TARGA 1000"),
 	DEVICE( INIT,		INIT_320P,	"320 P"),
 	DEVICE( INIT,		INIT_360P,	"360 P"),
@@ -304,6 +324,7 @@
 	DEVICE( VIA,		VIA_82C595_97,	"VT 82C595 Apollo VP2/97"),
 	DEVICE( VIA,		VIA_82C586_2,	"VT 82C586 Apollo USB"),
 	DEVICE( VIA,		VIA_82C586_3,	"VT 82C586B Apollo ACPI"),
+	DEVICE( VIA,		VIA_86C100A,	"VT 86C100A"),
 	DEVICE( VIA,		VIA_82C597_1,	"VT 82C597 Apollo VP3 AGP"),
 	DEVICE( VORTEX,		VORTEX_GDT60x0,	"GDT 60x0"),
 	DEVICE( VORTEX,		VORTEX_GDT6000B,"GDT 6000b"),
@@ -342,6 +363,7 @@
 	DEVICE( FORE,		FORE_PCA200PC, "PCA-200PC"),
 	DEVICE( FORE,		FORE_PCA200E,	 "PCA-200E"),
 	DEVICE( IMAGINGTECH,	IMAGINGTECH_ICPCI, "MVC IC-PCI"),
+	DEVICE( PHILIPS,	PHILIPS_SAA7145,"SAA7145"),
 	DEVICE( PHILIPS,	PHILIPS_SAA7146,"SAA7146"),
 	DEVICE( CYCLONE,	CYCLONE_SDK,	"SDK"),
 	DEVICE( ALLIANCE,	ALLIANCE_PROMOTIO, "Promotion-6410"),
@@ -356,6 +378,7 @@
 	DEVICE( DIGI,		DIGI_CX,	"AccelPort C/X"),
 	DEVICE( DIGI,		DIGI_XRJ,	"AccelPort Xr/J"),
 	DEVICE( DIGI,		DIGI_EPCJ,	"AccelPort EPC/J"),
+	DEVICE( DIGI,		DIGI_XR_920,	"AccelPort Xr 920"),
 	DEVICE( MUTECH,		MUTECH_MV1000,	"MV-1000"),
 	DEVICE( RENDITION,	RENDITION_VERITE,"Verite 1000"),
 	DEVICE( RENDITION,	RENDITION_VERITE2100,"Verite 2100"),
@@ -377,20 +400,21 @@
 	DEVICE( IKON,		IKON_10117,	"10117 Greensheet"),
 	DEVICE( ZORAN,		ZORAN_36057,	"ZR36057"),
 	DEVICE( ZORAN,		ZORAN_36120,	"ZR36120"),
+	DEVICE( KINETIC,	KINETIC_2915,	"2915 CAMAC"),
 	DEVICE( COMPEX,		COMPEX_ENET100VG4, "Readylink ENET100-VG4"),
 	DEVICE( COMPEX,		COMPEX_RL2000,	"ReadyLink 2000"),
 	DEVICE( RP,             RP8OCTA,        "RocketPort 8 Oct"),
 	DEVICE( RP,             RP8INTF,        "RocketPort 8 Intf"),
 	DEVICE( RP,             RP16INTF,       "RocketPort 16 Intf"),
 	DEVICE( RP,             RP32INTF,       "RocketPort 32 Intf"),
-	DEVICE( ESSENTIAL,      ROADRUNNER,     "RoadRunner serial HIPPI"),
 	DEVICE( CYCLADES,	CYCLOM_Y_Lo,	"Cyclom-Y below 1Mbyte"),
 	DEVICE( CYCLADES,	CYCLOM_Y_Hi,	"Cyclom-Y above 1Mbyte"),
 	DEVICE( CYCLADES,	CYCLOM_Z_Lo,	"Cyclom-Z below 1Mbyte"),
 	DEVICE( CYCLADES,	CYCLOM_Z_Hi,	"Cyclom-Z above 1Mbyte"),
+	DEVICE( ESSENTIAL,	ESSENTIAL_ROADRUNNER,"Roadrunner serial HIPPI"),
 	DEVICE( O2,		O2_6832,	"6832"),
 	DEVICE( 3DFX,		3DFX_VOODOO,	"Voodoo"),
-	DEVICE( 3DFX,		3DFX_VOODOO2,	"Voodoo2"),	
+	DEVICE( 3DFX,		3DFX_VOODOO2,	"Voodoo2"),
 	DEVICE( SIGMADES,	SIGMADES_6425,	"REALmagic64/GX"),
 	DEVICE( STALLION,	STALLION_ECHPCI832,"EasyConnection 8/32"),
 	DEVICE( STALLION,	STALLION_ECHPCI864,"EasyConnection 8/64"),
@@ -400,15 +424,20 @@
 	DEVICE( OPTIBASE,	OPTIBASE_VPLEX,	"VideoPlex"),
 	DEVICE( OPTIBASE,	OPTIBASE_VPLEXCC,"VideoPlex CC"),
 	DEVICE( OPTIBASE,	OPTIBASE_VQUEST,"VideoQuest"),
+	DEVICE( SATSAGEM,	SATSAGEM_PCR2101,"PCR2101 DVB receiver"),
+	DEVICE( SATSAGEM,	SATSAGEM_TELSATTURBO,"Telsat Turbo DVB"),
+	DEVICE( HUGHES,		HUGHES_DIRECPC,	"DirecPC"),
 	DEVICE( ENSONIQ,	ENSONIQ_AUDIOPCI,"AudioPCI"),
 	DEVICE( PICTUREL,	PICTUREL_PCIVST,"PCIVST"),
 	DEVICE( NVIDIA_SGS,	NVIDIA_SGS_RIVA128,	"Riva 128"),
+	DEVICE( CBOARDS,	CBOARDS_DAS1602_16,"DAS1602/16"),
 	DEVICE( SYMPHONY,	SYMPHONY_101,	"82C101"),
 	DEVICE( TEKRAM,		TEKRAM_DC290,	"DC-290"),
 	DEVICE( 3DLABS,		3DLABS_300SX,	"GLINT 300SX"),
 	DEVICE( 3DLABS,		3DLABS_500TX,	"GLINT 500TX"),
 	DEVICE( 3DLABS,		3DLABS_DELTA,	"GLINT Delta"),
 	DEVICE( 3DLABS,		3DLABS_PERMEDIA,"PERMEDIA"),
+	DEVICE( 3DLABS,		3DLABS_MX,	"GLINT MX"),
 	DEVICE( AVANCE,		AVANCE_ALG2064,	"ALG2064i"),
 	DEVICE( AVANCE,		AVANCE_2302,	"ALG-2302"),
 	DEVICE( NETVIN,		NETVIN_NV5000SC,"NV5000"),
@@ -450,6 +479,7 @@
 	DEVICE( INTEL,		INTEL_82371MX,	"430MX - 82371MX MPIIX"),
 	DEVICE( INTEL,		INTEL_82437MX,	"430MX - 82437MX MTSC"),
 	DEVICE( INTEL,		INTEL_82441,	"82441FX Natoma"),
+	DEVICE( INTEL,		INTEL_82380FB,	"82380FB Mobile"),
 	DEVICE( INTEL,		INTEL_82439,	"82439HX Triton II"),
 	DEVICE(	INTEL,		INTEL_82371SB_0,"82371SB PIIX3 ISA"),
 	DEVICE(	INTEL,		INTEL_82371SB_1,"82371SB PIIX3 IDE"),
@@ -462,9 +492,13 @@
 	DEVICE( INTEL,		INTEL_82371AB_3,"82371AB PIIX4 ACPI"),
 	DEVICE( INTEL,		INTEL_82443LX_0,"440LX - 82443LX PAC Host"),
 	DEVICE( INTEL,		INTEL_82443LX_1,"440LX - 82443LX PAC AGP"),
+	DEVICE( INTEL,		INTEL_82443BX_0,"440BX - 82443BX Host"),
+	DEVICE( INTEL,		INTEL_82443BX_1,"440BX - 82443BX AGP"),
+	DEVICE( INTEL,		INTEL_82443BX_2,"440BX - 82443BX Host (no AGP)"),
 	DEVICE( INTEL,		INTEL_P6,	"Orion P6"),
  	DEVICE( INTEL,		INTEL_82450GX,	"82450GX Orion P6"),
 	DEVICE(	KTI,		KTI_ET32P2,	"ET32P2"),
+	DEVICE( ADAPTEC,	ADAPTEC_7810,	"AIC-7810 RAID"),
 	DEVICE( ADAPTEC,	ADAPTEC_7850,	"AIC-7850"),
 	DEVICE( ADAPTEC,	ADAPTEC_7855,	"AIC-7855"),
 	DEVICE( ADAPTEC,	ADAPTEC_5800,	"AIC-5800"),
@@ -481,7 +515,9 @@
 	DEVICE( ADAPTEC,	ADAPTEC_7882,	"AIC-7882U"),
 	DEVICE( ADAPTEC,	ADAPTEC_7883,	"AIC-7883U"),
 	DEVICE( ADAPTEC,	ADAPTEC_7884,	"AIC-7884U"),
+	DEVICE( ADAPTEC,	ADAPTEC_1030,	"ABA-1030 DVB receiver"),
   	DEVICE( ATRONICS,	ATRONICS_2015,	"IDE-2015PL"),
+	DEVICE( TIGERJET,	TIGERJET_300,	"Tiger300 ISDN"),
 	DEVICE( ARK,		ARK_STING,	"Stingray"),
 	DEVICE( ARK,		ARK_STINGARK,	"Stingray ARK 2000PV"),
 	DEVICE( ARK,		ARK_2000MT,	"2000MT")
@@ -658,6 +694,7 @@
 	      case PCI_VENDOR_ID_WINBOND:	return "Winbond";
 	      case PCI_VENDOR_ID_DATABOOK:	return "Databook";
 	      case PCI_VENDOR_ID_PLX:		return "PLX";
+	      case PCI_VENDOR_ID_MADGE:		return "Madge Networks";
 	      case PCI_VENDOR_ID_3COM:		return "3Com";
 	      case PCI_VENDOR_ID_SMC:		return "SMC";
 	      case PCI_VENDOR_ID_AL:		return "Acer Labs";
@@ -665,6 +702,7 @@
 	      case PCI_VENDOR_ID_SURECOM:	return "Surecom";
 	      case PCI_VENDOR_ID_NEOMAGIC:	return "Neomagic";
 	      case PCI_VENDOR_ID_ASP:		return "Advanced System Products";
+	      case PCI_VENDOR_ID_MACRONIX:	return "Macronix";
 	      case PCI_VENDOR_ID_CERN:		return "CERN";
 	      case PCI_VENDOR_ID_NVIDIA:	return "NVidia";
 	      case PCI_VENDOR_ID_IMS:		return "IMS";
@@ -699,17 +737,23 @@
 	      case PCI_VENDOR_ID_AURAVISION:	return "Auravision";
 	      case PCI_VENDOR_ID_IKON:		return "Ikon";
 	      case PCI_VENDOR_ID_ZORAN:		return "Zoran";
+	      case PCI_VENDOR_ID_KINETIC:	return "Kinetic";
 	      case PCI_VENDOR_ID_COMPEX:	return "Compex";
 	      case PCI_VENDOR_ID_RP:		return "Comtrol";
 	      case PCI_VENDOR_ID_CYCLADES:	return "Cyclades";
 	      case PCI_VENDOR_ID_O2:		return "O2 Micro";
 	      case PCI_VENDOR_ID_3DFX:		return "3Dfx";
-	      case PCI_VENDOR_ID_STALLION:	return "Stallion Technologies";
 	      case PCI_VENDOR_ID_SIGMADES:	return "Sigma Designs";
+	      case PCI_VENDOR_ID_CCUBE:		return "C-Cube";
+	      case PCI_VENDOR_ID_DIPIX:		return "Dipix";
+	      case PCI_VENDOR_ID_STALLION:	return "Stallion Technologies";
 	      case PCI_VENDOR_ID_OPTIBASE:	return "Optibase";
+	      case PCI_VENDOR_ID_SATSAGEM:	return "SatSagem";
+	      case PCI_VENDOR_ID_HUGHES:	return "Hughes";
 	      case PCI_VENDOR_ID_ENSONIQ:	return "Ensoniq";
 	      case PCI_VENDOR_ID_PICTUREL:	return "Picture Elements";
 	      case PCI_VENDOR_ID_NVIDIA_SGS:	return "NVidia/SGS Thomson";
+	      case PCI_VENDOR_ID_CBOARDS:	return "ComputerBoards";
 	      case PCI_VENDOR_ID_SYMPHONY:	return "Symphony";
 	      case PCI_VENDOR_ID_TEKRAM:	return "Tekram";
 	      case PCI_VENDOR_ID_3DLABS:	return "3Dlabs";
@@ -720,6 +764,7 @@
 	      case PCI_VENDOR_ID_KTI:		return "KTI";
 	      case PCI_VENDOR_ID_ADAPTEC:	return "Adaptec";
 	      case PCI_VENDOR_ID_ATRONICS:	return "Atronics";
+	      case PCI_VENDOR_ID_TIGERJET:	return "TigerJet";
 	      case PCI_VENDOR_ID_ARK:		return "ARK Logic";
 	      default:				return "Unknown vendor";
 	}
@@ -744,7 +789,7 @@
 static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
 {
 	unsigned long base;
-	unsigned int l, class_rev, bus, devfn;
+	unsigned int class_rev, bus, devfn;
 	unsigned short vendor, device, status;
 	unsigned char bist, latency, min_gnt, max_lat;
 	int reg, len = 0;
@@ -835,12 +880,7 @@
 		if (len + 40 > size) {
 			return -1;
 		}
-		pcibios_read_config_dword(bus, devfn,
-				PCI_BASE_ADDRESS_0 + (reg << 2), &l);
-		if (l == 0xffffffff)
-			base = 0;
-		else
-			base = l;
+		base = dev->base_address[reg];
 		if (!base)
 			continue;
 
@@ -863,12 +903,7 @@
 			      case PCI_BASE_ADDRESS_MEM_TYPE_1M:
 				type = "20 bit"; break;
 			      case PCI_BASE_ADDRESS_MEM_TYPE_64:
-				type = "64 bit";
-				/* read top 32 bit address of base addr: */
-				reg += 4;
-				pcibios_read_config_dword(bus, devfn, reg, &l);
-				base |= ((u64) l) << 32;
-				break;
+				type = "64 bit"; break;
 			}
 			len += sprintf(buf + len,
 				       "\n      %srefetchable %s memory at "
diff -u --recursive --new-file v2.1.99/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.1.99/linux/drivers/pci/pci.c	Sat May  2 14:19:53 1998
+++ linux/drivers/pci/pci.c	Sun May  3 11:30:01 1998
@@ -1,5 +1,5 @@
 /*
- *	$Id: pci.c,v 1.79 1998/04/17 16:25:24 mj Exp $
+ *	$Id: pci.c,v 1.84 1998/05/02 19:22:06 mj Exp $
  *
  *	PCI Bus Services
  *
@@ -68,11 +68,48 @@
 }
 
 
+int
+pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val)
+{
+	return pcibios_read_config_byte(dev->bus->number, dev->devfn, where, val);
+}
+
+int
+pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val)
+{
+	return pcibios_read_config_word(dev->bus->number, dev->devfn, where, val);
+}
+
+int
+pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val)
+{
+	return pcibios_read_config_dword(dev->bus->number, dev->devfn, where, val);
+}
+
+int
+pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val)
+{
+	return pcibios_write_config_byte(dev->bus->number, dev->devfn, where, val);
+}
+
+int
+pci_write_config_word(struct pci_dev *dev, u8 where, u16 val)
+{
+	return pcibios_write_config_word(dev->bus->number, dev->devfn, where, val);
+}
+
+int
+pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val)
+{
+	return pcibios_write_config_dword(dev->bus->number, dev->devfn, where, val);
+}
+
+
 void
 pci_set_master(struct pci_dev *dev)
 {
-	unsigned short cmd;
-	unsigned char lat;
+	u16 cmd;
+	u8 lat;
 
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	if (! (cmd & PCI_COMMAND_MASTER)) {
@@ -89,16 +126,43 @@
 	}
 }
 
+__initfunc(void pci_read_bases(struct pci_dev *dev, unsigned int howmany))
+{
+	unsigned int reg;
+	u32 l;
+
+	for(reg=0; reg<howmany; reg++) {
+		pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
+		if (l == 0xffffffff)
+			continue;
+		dev->base_address[reg] = l;
+		if ((l & PCI_MEMORY_RANGE_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+			reg++;
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
+			if (l) {
+#if BITS_PER_LONG == 64
+				dev->base_address[reg-1] |= ((unsigned long) l) << 32;
+#else
+				printk("PCI: Unable to handle 64-bit address for device %02x:%02x\n",
+					dev->bus->number, dev->devfn);
+				dev->base_address[reg-1] = 0;
+#endif
+			}
+		}
+	}
+}
+
 
 __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
 {
 	unsigned int devfn, l, max, class;
 	unsigned char cmd, irq, tmp, hdr_type, is_multi = 0;
-	struct pci_dev *dev;
+	struct pci_dev *dev, **bus_last;
 	struct pci_bus *child;
 	int reg;
 
 	DBG("pci_scan_bus for bus %d\n", bus->number);
+	bus_last = &bus->devices;
 	max = bus->secondary;
 	for (devfn = 0; devfn < 0xff; ++devfn) {
 		if (PCI_FUNC(devfn) && !is_multi) {
@@ -111,8 +175,8 @@
 
 		pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l);
 		/* some broken boards return 0 if a slot is empty: */
-		if (l == 0xffffffff || l == 0x00000000) {
-			hdr_type = 0;
+		if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) {
+			is_multi = 0;
 			continue;
 		}
 
@@ -133,11 +197,12 @@
 		pcibios_read_config_dword(bus->number, devfn, PCI_CLASS_REVISION, &class);
 		class >>= 8;				    /* upper 3 bytes */
 		dev->class = class;
+		class >>= 8;
 		dev->hdr_type = hdr_type;
 
 		switch (hdr_type & 0x7f) {		    /* header type */
 		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
-			if (class >> 8 == PCI_CLASS_BRIDGE_PCI)
+			if (class == PCI_CLASS_BRIDGE_PCI)
 				goto bad;
 			/*
 			 * If the card generates interrupts, read IRQ number
@@ -151,25 +216,19 @@
 			 * read base address registers, again pcibios_fixup() can
 			 * tweak these
 			 */
-			for (reg = 0; reg < 6; reg++) {
-				pcibios_read_config_dword(bus->number, devfn, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
-				dev->base_address[reg] = (l == 0xffffffff) ? 0 : l;
-			}
+			pci_read_bases(dev, 6);
 			pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS, &l);
 			dev->rom_address = (l == 0xffffffff) ? 0 : l;
 			break;
 		case PCI_HEADER_TYPE_BRIDGE:		    /* bridge header */
-			if (class >> 8 != PCI_CLASS_BRIDGE_PCI)
+			if (class != PCI_CLASS_BRIDGE_PCI)
 				goto bad;
-			for (reg = 0; reg < 2; reg++) {
-				pcibios_read_config_dword(bus->number, devfn, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
-				dev->base_address[reg] = (l == 0xffffffff) ? 0 : l;
-			}
+			pci_read_bases(dev, 2);
 			pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l);
 			dev->rom_address = (l == 0xffffffff) ? 0 : l;
 			break;
 		case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
-			if (class >> 16 != PCI_BASE_CLASS_BRIDGE)
+			if (class != PCI_CLASS_BRIDGE_CARDBUS)
 				goto bad;
 			for (reg = 0; reg < 2; reg++) {
 				pcibios_read_config_dword(bus->number, devfn, PCI_CB_MEMORY_BASE_0 + (reg << 3), &l);
@@ -201,8 +260,8 @@
 		 * Now insert it into the list of devices held
 		 * by the parent bus.
 		 */
-		dev->sibling = bus->devices;
-		bus->devices = dev;
+		*bus_last = dev;
+		bus_last = &dev->sibling;
 
 #if 0
 		/*
@@ -217,7 +276,7 @@
 		/*
 		 * If it's a bridge, scan the bus behind it.
 		 */
-		if (class >> 8 == PCI_CLASS_BRIDGE_PCI) {
+		if (class == PCI_CLASS_BRIDGE_PCI) {
 			unsigned int buses;
 			unsigned short cr;
 
diff -u --recursive --new-file v2.1.99/linux/drivers/pci/pcisyms.c linux/drivers/pci/pcisyms.c
--- v2.1.99/linux/drivers/pci/pcisyms.c	Thu Apr 23 20:21:33 1998
+++ linux/drivers/pci/pcisyms.c	Sun May  3 11:30:01 1998
@@ -1,5 +1,5 @@
 /*
- *	$Id: pcisyms.c,v 1.4 1998/04/17 16:34:19 mj Exp $
+ *	$Id: pcisyms.c,v 1.7 1998/05/02 19:20:06 mj Exp $
  *
  *	PCI Bus Services -- Exported Symbols
  *
@@ -16,6 +16,12 @@
 EXPORT_SYMBOL(pcibios_write_config_byte);
 EXPORT_SYMBOL(pcibios_write_config_word);
 EXPORT_SYMBOL(pcibios_write_config_dword);
+EXPORT_SYMBOL(pci_read_config_byte);
+EXPORT_SYMBOL(pci_read_config_word);
+EXPORT_SYMBOL(pci_read_config_dword);
+EXPORT_SYMBOL(pci_write_config_byte);
+EXPORT_SYMBOL(pci_write_config_word);
+EXPORT_SYMBOL(pci_write_config_dword);
 EXPORT_SYMBOL(pci_devices);
 EXPORT_SYMBOL(pci_root);
 EXPORT_SYMBOL(pci_find_class);
diff -u --recursive --new-file v2.1.99/linux/drivers/pci/proc.c linux/drivers/pci/proc.c
--- v2.1.99/linux/drivers/pci/proc.c	Sat Apr 25 18:13:11 1998
+++ linux/drivers/pci/proc.c	Wed May  6 10:56:04 1998
@@ -57,7 +57,7 @@
 	 * undefined locations (think of Intel PIIX4 as a typical example).
 	 */
 
-	if (fsuser())
+	if (capable(CAP_SYS_ADMIN))
 		size = PCI_CFG_SPACE_SIZE;
 	else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
 		size = 128;
diff -u --recursive --new-file v2.1.99/linux/drivers/pci/quirks.c linux/drivers/pci/quirks.c
--- v2.1.99/linux/drivers/pci/quirks.c	Sat May  2 14:19:53 1998
+++ linux/drivers/pci/quirks.c	Sun May  3 11:30:01 1998
@@ -1,5 +1,5 @@
 /*
- * $Id: quirks.c,v 1.3 1998/02/06 19:51:42 mj Exp $
+ * $Id: quirks.c,v 1.5 1998/05/02 19:24:14 mj Exp $
  *
  * PCI Chipset-Specific Quirks
  *
@@ -7,8 +7,7 @@
  *
  * This is the right place for all special fixups for on-board
  * devices not depending on system architecture -- for example
- * bus bridges. The only thing implemented in this release is
- * the bridge optimization, but others might appear later.
+ * bus bridges.
  */
 
 #include <linux/config.h>
@@ -88,21 +87,19 @@
 		printk("    %s: ", bridge_optimization[i].type);
 		bmap = &bridge_mapping[pos + i];
 		if (!bmap->addr) {
-			printk("Not supported.");
+			printk("Not supported.\n");
 		} else {
-			pcibios_read_config_byte(dev->bus->number, dev->devfn, bmap->addr, &val);
+			pci_read_config_byte(dev, bmap->addr, &val);
 			if ((val & bmap->mask) == bmap->value)
-				printk("%s.", bridge_optimization[i].on);
+				printk("%s.\n", bridge_optimization[i].on);
 			else {
-				printk("%s.", bridge_optimization[i].off);
-				pcibios_write_config_byte(dev->bus->number, dev->devfn,
-							  bmap->addr,
-							  (val & (0xff - bmap->mask))
-							  + bmap->value);
-				printk("Changed!  Now %s.", bridge_optimization[i].on);
+				printk("%s", bridge_optimization[i].off);
+				pci_write_config_byte(dev,
+						      bmap->addr,
+						      (val & (0xff - bmap->mask)) + bmap->value);
+				printk(" -> %s.\n", bridge_optimization[i].on);
 			}
 		}
-		printk("\n");
 	}
 }
 
@@ -113,27 +110,18 @@
    which can cause problems in combination with the 82441FX/PPro MTRRs */
 __initfunc(static void quirk_passive_release(struct pci_dev *dev, int arg))
 {
-	struct pci_dev *piix3;
+	struct pci_dev *d = NULL;
 	unsigned char dlc;
 
 	/* We have to make sure a particular bit is set in the PIIX3
 	   ISA bridge, so we have to go out and find it. */
-	for (piix3 = pci_devices; ; piix3 = piix3->next) {
-		if (!piix3)
-			return;
-
-		if (piix3->vendor == PCI_VENDOR_ID_INTEL
-		    && piix3->device == PCI_DEVICE_ID_INTEL_82371SB_0)
-			break;
-	}	
-
-	pcibios_read_config_byte(piix3->bus->number, piix3->devfn, 0x82, &dlc);
-
-	if (!(dlc & 1<<1)) {
-		printk("PIIX3: Enabling Passive Release\n");
-		dlc |= 1<<1;
-		pcibios_write_config_byte(piix3->bus->number, piix3->devfn, 
-					  0x82, dlc);
+	while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
+		pci_read_config_byte(d, 0x82, &dlc);
+		if (!(dlc & 1<<1)) {
+			printk("PIIX3: Enabling Passive Release\n");
+			dlc |= 1<<1;
+			pci_write_config_byte(d, 0x82, dlc);
+		}
 	}
 }
 
@@ -141,7 +129,7 @@
 typedef void (*quirk_handler)(struct pci_dev *, int);
 
 /*
- * Mpping from quirk handler functions to names.
+ * Mapping from quirk handler functions to names.
  */
 
 struct quirk_name {
@@ -185,6 +173,7 @@
 	{ PCI_VENDOR_ID_UMC,	PCI_DEVICE_ID_UMC_UM8891A,	quirk_bridge,	0x01 },
 	{ PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82424,	quirk_bridge,	0x00 },
 	{ PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82434,	quirk_bridge,	0x00 },
+	{ PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82430,	quirk_bridge,	0x00 },
 #endif
 	{ PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_passive_release,	0x00 },
 };
diff -u --recursive --new-file v2.1.99/linux/drivers/sbus/char/rtc.c linux/drivers/sbus/char/rtc.c
--- v2.1.99/linux/drivers/sbus/char/rtc.c	Mon Jan 12 15:15:45 1998
+++ linux/drivers/sbus/char/rtc.c	Wed May  6 10:56:04 1998
@@ -91,7 +91,7 @@
 
 
 	case RTCSET:
-		if (!suser())
+		if (!capable(CAP_SYS_TIME))
 			return -EPERM;
 
 		copy_from_user_ret(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time), -EFAULT);
diff -u --recursive --new-file v2.1.99/linux/drivers/sbus/char/vfc_dev.c linux/drivers/sbus/char/vfc_dev.c
--- v2.1.99/linux/drivers/sbus/char/vfc_dev.c	Thu Apr 23 20:21:34 1998
+++ linux/drivers/sbus/char/vfc_dev.c	Wed May  6 10:56:04 1998
@@ -205,7 +205,7 @@
 	unsigned char *buffer;
 	int ret;
 
-	if(!suser()) return -EPERM;
+	if(!capable(CAP_SYS_ADMIN)) return -EPERM;
 
 	switch(cmd) {
 	case VFC_I2C_SEND:
diff -u --recursive --new-file v2.1.99/linux/drivers/sbus/char/zs.c linux/drivers/sbus/char/zs.c
--- v2.1.99/linux/drivers/sbus/char/zs.c	Thu Apr 23 20:21:34 1998
+++ linux/drivers/sbus/char/zs.c	Wed May  6 10:56:04 1998
@@ -1265,7 +1265,7 @@
 		return -EFAULT;
 	old_info = *info;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.type != info->type) ||
 		    (new_serial.close_delay != info->close_delay) ||
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- v2.1.99/linux/drivers/scsi/ide-scsi.c	Tue Apr 14 14:29:22 1998
+++ linux/drivers/scsi/ide-scsi.c	Wed May  6 14:42:54 1998
@@ -260,7 +260,7 @@
 	struct request *rq = hwgroup->rq;
 	idescsi_pc_t *pc = (idescsi_pc_t *) rq->buffer;
 	int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
-	u8 *scsi_buf = pc->scsi_cmd->request_buffer;
+	u8 *scsi_buf;
 
 	if (rq->cmd != IDESCSI_PC_RQ) {
 		ide_end_request (uptodate, hwgroup);
@@ -282,6 +282,7 @@
 			printk ("ide-scsi: %s: suc %lu", drive->name, pc->scsi_cmd->serial_number);
 			if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) {
 				printk(", rst = ");
+				scsi_buf = pc->scsi_cmd->request_buffer;
 				hexdump(scsi_buf, IDE_MIN(16, pc->scsi_cmd->request_bufflen));
 			} else printk("\n");
 		}
@@ -326,7 +327,7 @@
 	if ((status & DRQ_STAT) == 0) {					/* No more interrupts */
 		if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
 			printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred);
-		ide_sti();
+		ide__sti();
 		if (status & ERR_STAT)
 			rq->errors++;
 		idescsi_end_request (1, HWGROUP(drive));
@@ -345,7 +346,18 @@
 		if ( temp > pc->request_transfer) {
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
-				idescsi_discard_data (drive,bcount);
+				temp = pc->buffer_size - pc->actually_transferred;
+				if (temp) {
+					clear_bit(PC_WRITING, &pc->flags);
+					if (pc->sg)
+						idescsi_input_buffers(drive, pc, temp);
+					else
+						atapi_input_bytes(drive, pc->current_position, temp);
+					printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount);
+				}
+				pc->actually_transferred += temp;
+				pc->current_position += temp;
+				idescsi_discard_data (drive,bcount - temp);
 				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc));
 				return;
 			}
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
--- v2.1.99/linux/drivers/scsi/ppa.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/scsi/ppa.c	Thu May  7 14:58:42 1998
@@ -50,13 +50,6 @@
 #include  "ppa.h"
 #include <linux/parport.h>
 
-#ifdef CONFIG_KMOD
-#include  <linux/kmod.h>
-#ifndef PARPORT_MODULES
-#define PARPORT_MODULES "parport_pc"
-#endif
-#endif
-
 #define NO_HOSTS 4
 static ppa_struct ppa_hosts[NO_HOSTS] =
 {PPA_EMPTY, PPA_EMPTY, PPA_EMPTY, PPA_EMPTY};
@@ -98,7 +91,6 @@
 	return 1;
     }
 
-    PPA_BASE(host_no) = ppa_hosts[host_no].dev->port->base;
     if (ppa_hosts[host_no].cur_cmd)
 	ppa_hosts[host_no].cur_cmd->SCp.phase++;
     return 0;
@@ -130,12 +122,8 @@
     nhosts = 0;
     try_again = 0;
 
-#ifdef CONFIG_KMOD
-    if (!pb) {
-	request_module(PARPORT_MODULES);
+    if (!pb)
 	pb = parport_enumerate();
-    }
-#endif
 
     if (!pb) {
 	printk("ppa: parport reports no devices.\n");
@@ -155,7 +143,7 @@
 	if (ppa_pb_claim(i))
 	    while (ppa_hosts[i].p_busy)
 		schedule(); /* Whe can safe schedule() here */
-	ppb = PPA_BASE(i);
+	ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base;
 	w_ctr(ppb, 0x0c);
 	modes = ppa_hosts[i].dev->port->modes;
 
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.1.99/linux/drivers/scsi/scsi.c	Sat May  2 14:19:53 1998
+++ linux/drivers/scsi/scsi.c	Mon May  4 10:46:11 1998
@@ -1605,6 +1605,7 @@
       if( SCpnt == NULL )
           return;
       
+      spin_lock_irqsave(&io_request_lock, flags);
       atomic_inc(&recursion_depth);
       
       SCnext = SCpnt->bh_next;
@@ -1696,6 +1697,7 @@
       } /* for(; SCpnt...) */
 
       atomic_dec(&recursion_depth);
+      spin_unlock_irqrestore(&io_request_lock, flags);
 
   } /* while(1==1) */
 
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c
--- v2.1.99/linux/drivers/scsi/scsi_error.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/scsi/scsi_error.c	Sat May  2 17:58:13 1998
@@ -159,7 +159,7 @@
  *
  * Notes:
  */
-void scsi_times_out (Scsi_Cmnd * SCpnt)
+static void do_scsi_times_out (Scsi_Cmnd * SCpnt)
 {
 
     /* 
@@ -222,6 +222,15 @@
     }
 }
 
+void scsi_times_out (Scsi_Cmnd * SCpnt)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	do_scsi_times_out(SCpnt);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
 /*
  * Function     scsi_block_when_processing_errors
  *
@@ -264,6 +273,9 @@
 STATIC
 void scsi_eh_times_out (Scsi_Cmnd * SCpnt)
 {
+  unsigned long flags;
+
+  spin_lock_irqsave(&io_request_lock, flags);
   SCpnt->request.rq_status = RQ_SCSI_DONE;
   SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
   SCpnt->eh_state = SCSI_STATE_TIMEOUT;
@@ -273,7 +285,8 @@
   if (SCpnt->host->eh_action != NULL)
     up(SCpnt->host->eh_action);
   else
-    panic("Missing scsi error handler thread");
+    printk("Missing scsi error handler thread\n");
+  spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 
@@ -446,6 +459,11 @@
   return SCpnt->eh_state;
 }
 
+/*
+ * This would normally need to get the IO request lock,
+ * but as it doesn't actually touch anything that needs
+ * to be locked we can avoid the lock here..
+ */
 STATIC
 void scsi_sleep_done (struct semaphore * sem)
 {
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- v2.1.99/linux/drivers/scsi/scsi_ioctl.c	Sat May  2 14:19:53 1998
+++ linux/drivers/scsi/scsi_ioctl.c	Wed May  6 10:56:05 1998
@@ -17,8 +17,13 @@
 #include "hosts.h"
 #include <scsi/scsi_ioctl.h>
 
-#define MAX_RETRIES 5   
-#define MAX_TIMEOUT (9 * HZ)
+#define NORMAL_RETRIES 5   
+#define NORMAL_TIMEOUT (10 * HZ)
+#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
+#define START_STOP_TIMEOUT (60 * HZ)
+#define MOVE_MEDIUM_TIMEOUT (5 * 60 * HZ)
+#define READ_ELEMENT_STATUS_TIMEOUT (5 * 60 * HZ)
+
 #define MAX_BUF PAGE_SIZE
 
 #define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -61,7 +66,7 @@
 /*
  * 
  * The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host.
- * The MAX_TIMEOUT and MAX_RETRIES  variables are used.  
+ * The NORMAL_TIMEOUT and NORMAL_RETRIES  variables are used.  
  * 
  * dev is the SCSI device struct ptr, *(int *) arg is the length of the
  * input data, if any, not including the command string & counts, 
@@ -94,7 +99,8 @@
     }
 }   
 
-static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
+static int ioctl_internal_command(Scsi_Device *dev, char * cmd,
+				  int timeout, int retries)
 {
     unsigned long flags;
     int result;
@@ -107,9 +113,7 @@
 	struct semaphore sem = MUTEX_LOCKED;
 	SCpnt->request.sem = &sem;
 	spin_lock_irqsave(&io_request_lock, flags);
-	scsi_do_cmd(SCpnt,  cmd, NULL,  0,
-		    scsi_ioctl_done,  MAX_TIMEOUT,
-		    MAX_RETRIES);
+	scsi_do_cmd(SCpnt,  cmd, NULL,  0, scsi_ioctl_done,  timeout, retries);
 	spin_unlock_irqrestore(&io_request_lock, flags);
 	down(&sem);
         SCpnt->request.sem = NULL;
@@ -250,21 +254,24 @@
     switch (opcode)
       {
       case FORMAT_UNIT:
-	timeout =  2 * 60 * 60 * HZ; /* 2 Hours */
+ 	timeout = FORMAT_UNIT_TIMEOUT;
 	retries = 1;
 	break;
       case START_STOP:
-	timeout =  2 * 60 * HZ;	/* 2 minutes */
-	retries = 1;
+ 	timeout = START_STOP_TIMEOUT;
+ 	retries = NORMAL_RETRIES;
 	break;
       case MOVE_MEDIUM:
+ 	timeout = MOVE_MEDIUM_TIMEOUT;
+ 	retries = NORMAL_RETRIES;
+ 	break;
       case READ_ELEMENT_STATUS:
-	timeout =  5 * 60 * HZ;	/* 5 minutes */
-	retries = 1;
+ 	timeout = READ_ELEMENT_STATUS_TIMEOUT;
+ 	retries = NORMAL_RETRIES;
 	break;
       default:
-	timeout = MAX_TIMEOUT;
-	retries = MAX_RETRIES;
+ 	timeout = NORMAL_TIMEOUT;
+ 	retries = NORMAL_RETRIES;
 	break;
       }
 
@@ -372,13 +379,13 @@
         put_user( dev->host->host_no, (int *) arg);
 	return 0;
     case SCSI_IOCTL_TAGGED_ENABLE:
-	if(!suser())  return -EACCES;
+	if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 	if(!dev->tagged_supported) return -EINVAL;
 	dev->tagged_queue = 1;
 	dev->current_tag = 1;
 	return 0;
     case SCSI_IOCTL_TAGGED_DISABLE:
-	if(!suser())  return -EACCES;
+	if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 	if(!dev->tagged_supported) return -EINVAL;
 	dev->tagged_queue = 0;
 	dev->current_tag = 0;
@@ -386,7 +393,7 @@
     case SCSI_IOCTL_PROBE_HOST:
 	return ioctl_probe(dev->host, arg);
     case SCSI_IOCTL_SEND_COMMAND:
-	if(!suser())  return -EACCES;
+	if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 	return scsi_ioctl_send_command((Scsi_Device *) dev,
 				       (Scsi_Ioctl_Command *) arg);
     case SCSI_IOCTL_DOORLOCK:
@@ -395,7 +402,8 @@
 	scsi_cmd[1] = dev->lun << 5;
 	scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 	scsi_cmd[4] = SCSI_REMOVAL_PREVENT;
-	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
+	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+				      NORMAL_TIMEOUT, NORMAL_RETRIES);
 	break;
     case SCSI_IOCTL_DOORUNLOCK:
 	if (!dev->removable || !dev->lockable) return 0;
@@ -403,13 +411,31 @@
 	scsi_cmd[1] = dev->lun << 5;
 	scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 	scsi_cmd[4] = SCSI_REMOVAL_ALLOW;
-	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
+	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+				      NORMAL_TIMEOUT, NORMAL_RETRIES);
     case SCSI_IOCTL_TEST_UNIT_READY:
 	scsi_cmd[0] = TEST_UNIT_READY;
 	scsi_cmd[1] = dev->lun << 5;
 	scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 	scsi_cmd[4] = 0;
-	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
+	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+				      NORMAL_TIMEOUT, NORMAL_RETRIES);
+	break;
+    case SCSI_IOCTL_START_UNIT:
+	scsi_cmd[0] = START_STOP;
+	scsi_cmd[1] = dev->lun << 5;
+	scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
+	scsi_cmd[4] = 1;
+	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+				      START_STOP_TIMEOUT, NORMAL_RETRIES);
+	break;
+    case SCSI_IOCTL_STOP_UNIT:
+	scsi_cmd[0] = START_STOP;
+	scsi_cmd[1] = dev->lun << 5;
+	scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
+	scsi_cmd[4] = 0;
+	return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+				      START_STOP_TIMEOUT, NORMAL_RETRIES);
 	break;
     default :           
 	if (dev->host->hostt->ioctl)
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c
--- v2.1.99/linux/drivers/scsi/scsi_syms.c	Thu Jan  8 20:35:43 1998
+++ linux/drivers/scsi/scsi_syms.c	Sun May  3 11:30:49 1998
@@ -65,6 +65,7 @@
 EXPORT_SYMBOL(print_Scsi_Cmnd);
 EXPORT_SYMBOL(scsi_block_when_processing_errors);
 EXPORT_SYMBOL(scsi_mark_host_reset);
+EXPORT_SYMBOL(scsi_ioctl_send_command);
 #if defined(CONFIG_SCSI_LOGGING) /* { */
 EXPORT_SYMBOL(scsi_logging_level);
 #endif
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.1.99/linux/drivers/scsi/sd.c	Fri Apr 10 13:03:49 1998
+++ linux/drivers/scsi/sd.c	Fri May  1 11:19:58 1998
@@ -1060,8 +1060,15 @@
     }
 
     inode.i_rdev = full_dev;  /* This is all we really need here */
-    retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
 
+    /* Using Start/Stop enables differentiation between drive with
+     * no cartridge loaded - NOT READY, drive with changed cartridge -
+     * UNIT ATTENTION, or with same cartridge - GOOD STATUS.
+     * This also handles drives that auto spin down. eg iomega jaz 1GB
+     * as this will spin up the drive.
+     */
+    retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_START_UNIT, 0);
+    
     if(retval){ /* Unable to test, unit probably not ready.  This usually
 		 * means there is no disc in the drive.  Mark as changed,
 		 * and we will figure it out later once the drive is
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c
--- v2.1.99/linux/drivers/scsi/sd_ioctl.c	Sun Jan  4 10:40:16 1998
+++ linux/drivers/scsi/sd_ioctl.c	Wed May  6 10:56:08 1998
@@ -79,7 +79,7 @@
 	return 0;
 
     case BLKRASET:
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 	if(!(inode->i_rdev)) return -EINVAL;
 	if(arg > 0xff) return -EINVAL;
@@ -96,13 +96,15 @@
 	return 0;
 
     case BLKFLSBUF:
-	if(!suser())  return -EACCES;
+	if(!capable(CAP_SYS_ADMIN))  return -EACCES;
 	if(!(inode->i_rdev)) return -EINVAL;
 	fsync_dev(inode->i_rdev);
 	invalidate_buffers(inode->i_rdev);
 	return 0;
 	
     case BLKRRPART: /* Re-read partition tables */
+        if (!capable(CAP_SYS_ADMIN))
+                return -EACCES;
 	return revalidate_scsidisk(dev, 1);
 
     RO_IOCTLS(dev, arg);
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.1.99/linux/drivers/scsi/sr_ioctl.c	Thu Feb 12 20:56:10 1998
+++ linux/drivers/scsi/sr_ioctl.c	Wed May  6 10:56:05 1998
@@ -106,8 +106,8 @@
 	    break;
 	case ILLEGAL_REQUEST:
             if (!quiet)
-                printk("sr%d: CDROM (ioctl) reports ILLEGAL REQUEST.\n",
-                       target);
+		printk(KERN_ERR "sr%d: CDROM (ioctl) reports ILLEGAL "
+		       "REQUEST.\n", target);
             if (SCpnt->sense_buffer[12] == 0x20 &&
                 SCpnt->sense_buffer[13] == 0x00) {
                 /* sense: Invalid command operation code */
@@ -121,7 +121,7 @@
 #endif
 	    break;
 	default:
-	    printk("sr%d: CDROM (ioctl) error, command: ", target);
+	    printk(KERN_ERR "sr%d: CDROM (ioctl) error, command: ", target);
 	    print_command(sr_cmd);
 	    print_sense("sr", SCpnt);
             err = -EIO;
@@ -792,7 +792,7 @@
 	return 0;
 
     case BLKRASET:
-	if(!suser())
+	if(!capable(CAP_SYS_ADMIN))
         	return -EACCES;
 	if(!(cdi->dev))
         	return -EINVAL;
@@ -804,7 +804,7 @@
     RO_IOCTLS(cdi->dev,arg);
 
     case BLKFLSBUF:
-	if(!suser())
+	if(!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 	if(!(cdi->dev))
 		return -EINVAL;
diff -u --recursive --new-file v2.1.99/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v2.1.99/linux/drivers/scsi/st.c	Tue Apr 14 14:29:24 1998
+++ linux/drivers/scsi/st.c	Wed May  6 10:56:05 1998
@@ -2831,7 +2831,7 @@
      if (i)
 	 return (-EFAULT);
 
-     if (mtc.mt_op == MTSETDRVBUFFER && !suser()) {
+     if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
        printk(KERN_WARNING "st%d: MTSETDRVBUFFER only allowed for root.\n", dev);
        return (-EPERM);
      }
diff -u --recursive --new-file v2.1.99/linux/drivers/sgi/char/sgiserial.c linux/drivers/sgi/char/sgiserial.c
--- v2.1.99/linux/drivers/sgi/char/sgiserial.c	Mon Feb 23 18:12:08 1998
+++ linux/drivers/sgi/char/sgiserial.c	Wed May  6 10:56:05 1998
@@ -1201,7 +1201,7 @@
 	copy_from_user(&new_serial,new_info,sizeof(new_serial));
 	old_info = *info;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.type != info->type) ||
 		    (new_serial.close_delay != info->close_delay) ||
diff -u --recursive --new-file v2.1.99/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v2.1.99/linux/drivers/sound/Makefile	Wed Apr  8 19:36:27 1998
+++ linux/drivers/sound/Makefile	Mon May  4 17:39:39 1998
@@ -76,6 +76,9 @@
 
 ifeq ($(CONFIG_GUS),y)
 L_OBJS += gus.o
+  ifeq ($(CONFIG_GUSMAX),y)
+    CONFIG_MSS = y
+  endif
 else
   ifeq ($(CONFIG_GUS),m)
     M_OBJS += gus.o
diff -u --recursive --new-file v2.1.99/linux/drivers/sound/sound_syms.c linux/drivers/sound/sound_syms.c
--- v2.1.99/linux/drivers/sound/sound_syms.c	Wed Apr  8 19:36:27 1998
+++ linux/drivers/sound/sound_syms.c	Mon May  4 11:52:58 1998
@@ -26,6 +26,7 @@
 EXPORT_SYMBOL(note_to_freq);
 EXPORT_SYMBOL(compute_finetune);
 EXPORT_SYMBOL(seq_copy_to_input);
+EXPORT_SYMBOL(seq_input_event);
 EXPORT_SYMBOL(sequencer_init);
 EXPORT_SYMBOL(sequencer_timer);
 
@@ -61,6 +62,7 @@
 EXPORT_SYMBOL(sound_timer_init);
 EXPORT_SYMBOL(sound_timer_interrupt);
 EXPORT_SYMBOL(sound_timer_syncinterval);
+EXPORT_SYMBOL(sound_timer_devs);
 
 /* Locking */
 EXPORT_SYMBOL(sound_locker);
diff -u --recursive --new-file v2.1.99/linux/drivers/sound/sscape.c linux/drivers/sound/sscape.c
--- v2.1.99/linux/drivers/sound/sscape.c	Mon Feb 23 18:12:09 1998
+++ linux/drivers/sound/sscape.c	Mon May  4 11:53:54 1998
@@ -970,7 +970,7 @@
 	if (mss)
 		unload_ss_ms_sound(&config);
 	SOUND_LOCK_END;
-	unload_sscape(&config);
+	unload_sscape(&mpu_config);
 }
 
 #endif
diff -u --recursive --new-file v2.1.99/linux/fs/affs/namei.c linux/fs/affs/namei.c
--- v2.1.99/linux/fs/affs/namei.c	Tue Mar 10 10:03:33 1998
+++ linux/fs/affs/namei.c	Wed May  6 10:56:05 1998
@@ -245,7 +245,7 @@
 	if (S_ISDIR(inode->i_mode))
 		goto unlink_done;
 	if (current->fsuid != inode->i_uid &&
-	    current->fsuid != dir->i_uid && !fsuser())
+	    current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto unlink_done;
 
 	if ((retval = affs_remove_header(bh,inode)) < 0)
@@ -363,7 +363,7 @@
 
 	retval = -EPERM;
         if (current->fsuid != inode->i_uid &&
-            current->fsuid != dir->i_uid && !fsuser())
+            current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto rmdir_done;
 	if (inode->i_dev != dir->i_dev)
 		goto rmdir_done;
diff -u --recursive --new-file v2.1.99/linux/fs/attr.c linux/fs/attr.c
--- v2.1.99/linux/fs/attr.c	Sun Jan  4 00:53:41 1998
+++ linux/fs/attr.c	Wed May  6 10:56:05 1998
@@ -27,28 +27,28 @@
 	/* Make sure a caller can chown. */
 	if ((ia_valid & ATTR_UID) &&
 	    (current->fsuid != inode->i_uid ||
-	     attr->ia_uid != inode->i_uid) && !fsuser())
+	     attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
 		goto error;
 
 	/* Make sure caller can chgrp. */
 	if ((ia_valid & ATTR_GID) &&
 	    (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) &&
-	    !fsuser())
+	    !capable(CAP_CHOWN))
 		goto error;
 
 	/* Make sure a caller can chmod. */
 	if (ia_valid & ATTR_MODE) {
-		if ((current->fsuid != inode->i_uid) && !fsuser())
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			goto error;
 		/* Also check the setgid bit! */
 		if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
-				inode->i_gid) && !fsuser())
+				inode->i_gid) && !capable(CAP_FSETID))
 			attr->ia_mode &= ~S_ISGID;
 	}
 
 	/* Check for setting the inode time. */
 	if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) {
-		if (current->fsuid != inode->i_uid && !fsuser())
+		if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
 			goto error;
 	}
 fine:
@@ -75,7 +75,7 @@
 		inode->i_ctime = attr->ia_ctime;
 	if (ia_valid & ATTR_MODE) {
 		inode->i_mode = attr->ia_mode;
-		if (!in_group_p(inode->i_gid) && !fsuser())
+		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
 			inode->i_mode &= ~S_ISGID;
 	}
 	mark_inode_dirty(inode);
diff -u --recursive --new-file v2.1.99/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.1.99/linux/fs/autofs/root.c	Mon Apr  6 17:41:00 1998
+++ linux/fs/autofs/root.c	Wed May  6 10:56:05 1998
@@ -478,7 +478,7 @@
 	     _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
 		return -ENOTTY;
 	
-	if ( !autofs_oz_mode(sbi) && !fsuser() )
+	if ( !autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
 		return -EPERM;
 	
 	switch(cmd) {
diff -u --recursive --new-file v2.1.99/linux/fs/buffer.c linux/fs/buffer.c
--- v2.1.99/linux/fs/buffer.c	Wed Apr  8 19:36:28 1998
+++ linux/fs/buffer.c	Wed May  6 10:56:05 1998
@@ -1871,7 +1871,7 @@
 	int i, error = -EPERM;
 
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		goto out;
 
 	if (func == 1) {
diff -u --recursive --new-file v2.1.99/linux/fs/coda/Makefile linux/fs/coda/Makefile
--- v2.1.99/linux/fs/coda/Makefile	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/Makefile	Mon May  4 17:09:22 1998
@@ -4,7 +4,7 @@
 
 O_TARGET := coda.o
 O_OBJS   := psdev.o cache.o cnode.o inode.o dir.o file.o upcall.o coda_linux.o\
-            symlink.o pioctl.o sysctl.o
+            symlink.o pioctl.o sysctl.o stats.o
 M_OBJS   := $(O_TARGET)
 
 # If you want debugging output, please uncomment the following line
diff -u --recursive --new-file v2.1.99/linux/fs/coda/cache.c linux/fs/coda/cache.c
--- v2.1.99/linux/fs/coda/cache.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/cache.c	Mon May  4 17:09:22 1998
@@ -32,9 +32,6 @@
 static struct coda_cache * coda_cache_find(struct inode *inode);
 
 
-/* Keep various stats */
-struct cfsnc_statistics cfsnc_stat;
-
 /* insert a acl-cache entry in sb list */
 static void coda_ccinsert(struct coda_cache *el, struct super_block *sb)
 {
@@ -295,41 +292,3 @@
 
 
 
-int
-cfsnc_nc_info(char *buffer, char **start, off_t offset, int length, int dummy)
-{
-        int len=0;
-        off_t begin;
-	
-	/* 	cfsnc_gather_stats(); */
-
-	/* this works as long as we are below 1024 characters! */    
-	len += sprintf(buffer,"Coda minicache statistics\n\n");
-	len += sprintf(buffer+len, "cfsnc_hits : %d\n", cfsnc_stat.hits);
-	len += sprintf(buffer+len, "cfsnc_misses : %d\n", cfsnc_stat.misses);
-	len += sprintf(buffer+len, "cfsnc_enters : %d\n", cfsnc_stat.enters);
-	len += sprintf(buffer+len, "cfsnc_dbl_enters : %d\n", cfsnc_stat.dbl_enters);
-	len += sprintf(buffer+len, "cfsnc_long_name_enters : %d\n", cfsnc_stat.long_name_enters);
-	len += sprintf(buffer+len, "cfsnc_long_name_lookups : %d\n", cfsnc_stat.long_name_lookups);
-	len += sprintf(buffer+len, "cfsnc_long_remove : %d\n", cfsnc_stat.long_remove);
-	len += sprintf(buffer+len, "cfsnc_lru_rm : %d\n", cfsnc_stat.lru_rm);
-	len += sprintf(buffer+len, "cfsnc_zapPfids : %d\n", cfsnc_stat.zapPfids);
-	len += sprintf(buffer+len, "cfsnc_zapFids : %d\n", cfsnc_stat.zapFids);
-	len += sprintf(buffer+len, "cfsnc_zapFile : %d\n", cfsnc_stat.zapFile);
-	len += sprintf(buffer+len, "cfsnc_zapUsers : %d\n", cfsnc_stat.zapUsers);
-	len += sprintf(buffer+len, "cfsnc_Flushes : %d\n", cfsnc_stat.Flushes);
-	len += sprintf(buffer+len, "cfsnc_SumLen : %d\n", cfsnc_stat.Sum_bucket_len);
-	len += sprintf(buffer+len, "cfsnc_Sum2Len : %d\n", cfsnc_stat.Sum2_bucket_len);
-	len += sprintf(buffer+len,  "cfsnc_# 0 len : %d\n", cfsnc_stat.Num_zero_len);
-	len += sprintf(buffer+len,  "cfsnc_MaxLen : %d\n", cfsnc_stat.Max_bucket_len);
-	len += sprintf(buffer+len,  "cfsnc_SearchLen : %d\n", cfsnc_stat.Search_len);
-       	begin =  offset;
-       	*start = buffer + begin;
-       	len -= begin;
-	
-        if(len>length)
-                len = length;
-	if (len< 0)
-		len = 0;
-        return len;
-} 
diff -u --recursive --new-file v2.1.99/linux/fs/coda/coda_linux.c linux/fs/coda/coda_linux.c
--- v2.1.99/linux/fs/coda/coda_linux.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/coda_linux.c	Mon May  4 17:09:22 1998
@@ -7,6 +7,7 @@
  * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
  */
 
+#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff -u --recursive --new-file v2.1.99/linux/fs/coda/dir.c linux/fs/coda/dir.c
--- v2.1.99/linux/fs/coda/dir.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/dir.c	Mon May  4 17:09:22 1998
@@ -23,6 +23,7 @@
 #include <linux/coda_psdev.h>
 #include <linux/coda_fs_i.h>
 #include <linux/coda_cache.h>
+#include <linux/coda_proc.h>
 
 /* dir inode-ops */
 static int coda_create(struct inode *dir, struct dentry *new, int mode);
@@ -179,6 +180,8 @@
         int error;
  
         ENTRY;
+	coda_vfs_stat.permission++;
+	coda_permission_stat.count++;
 
         if ( mask == 0 ) {
                 EXIT;
@@ -187,6 +190,7 @@
 
 	if ( coda_access_cache == 1 ) {
 		if ( coda_cache_check(inode, mask) ) {
+			coda_permission_stat.hit_count++;
 			return 0; 
 		}
 	}
@@ -221,6 +225,8 @@
 	struct ViceFid newfid;
 	struct coda_vattr attrs;
 
+	coda_vfs_stat.create++;
+
 	CDEBUG(D_INODE, "name: %s, length %d, mode %o\n",name, length, mode);
 
         if (!dir || !S_ISDIR(dir->i_mode)) {
@@ -274,6 +280,8 @@
 	struct ViceFid newfid;
 
 
+	coda_vfs_stat.mkdir++;
+
 	if (!dir || !S_ISDIR(dir->i_mode)) {
 		printk("coda_mkdir: inode is NULL or not a directory\n");
 		return -ENOENT;
@@ -329,6 +337,7 @@
 	int error;
 
         ENTRY;
+	coda_vfs_stat.link++;
 
 	if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
 		return -EPERM;
@@ -373,6 +382,7 @@
         int error=0;
         
         ENTRY;
+	coda_vfs_stat.symlink++;
 
 	if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
 		return -EPERM;
@@ -414,6 +424,7 @@
 	int len = de->d_name.len;
 
 	ENTRY;
+	coda_vfs_stat.unlink++;
 
         dircnp = ITOC(dir);
         CHECK_CNODE(dircnp);
@@ -446,6 +457,8 @@
 	int len = de->d_name.len;
         int error, rehash = 0;
 
+	coda_vfs_stat.rmdir++;
+
 	if (!dir || !S_ISDIR(dir->i_mode)) {
 		printk("coda_rmdir: inode is NULL or not a directory\n");
 		return -ENOENT;
@@ -502,6 +515,8 @@
         struct coda_inode_info *new_cnp, *old_cnp;
         int error, rehash = 0, update = 1;
 ENTRY;
+	coda_vfs_stat.rename++;
+
         old_cnp = ITOC(old_dir);
         CHECK_CNODE(old_cnp);
         new_cnp = ITOC(new_dir);
@@ -565,6 +580,7 @@
 	struct inode *inode=file->f_dentry->d_inode;
 
         ENTRY;
+	coda_vfs_stat.readdir++;
 
         if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode)) {
                 printk("coda_readdir: inode is NULL or not a directory\n");
@@ -606,6 +622,7 @@
 	unsigned short coda_flags = coda_flags_to_cflags(flags);
 
         ENTRY;
+	coda_vfs_stat.open++;
         
         CDEBUG(D_SPECIAL, "OPEN inode number: %ld, flags %o.\n", 
 	       f->f_dentry->d_inode->i_ino, flags);
@@ -659,6 +676,7 @@
 	unsigned short cflags = coda_flags_to_cflags(flags);
 
         ENTRY;
+	coda_vfs_stat.release++;
 
         cnp =ITOC(i);
         CHECK_CNODE(cnp);
diff -u --recursive --new-file v2.1.99/linux/fs/coda/file.c linux/fs/coda/file.c
--- v2.1.99/linux/fs/coda/file.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/file.c	Mon May  4 17:09:22 1998
@@ -23,6 +23,7 @@
 #include <linux/coda_fs_i.h>
 #include <linux/coda_psdev.h>
 #include <linux/coda_cache.h>
+#include <linux/coda_proc.h>
 
 /* file operations */
 static int coda_readpage(struct file *file, struct page * page);
@@ -83,6 +84,7 @@
         struct coda_inode_info *cii;
 
         ENTRY;
+	coda_vfs_stat.readpage++;
         
         cii = ITOC(coda_inode);
 
@@ -108,6 +110,8 @@
         struct coda_inode_info *cii;
 	int res;
 
+	coda_vfs_stat.file_mmap++;
+
         ENTRY;
 	cii = ITOC(file->f_dentry->d_inode);
 	cii->c_mmcount++;
@@ -126,7 +130,9 @@
         struct file  cont_file;
 	struct dentry cont_dentry;
         int result = 0;
-        ENTRY;
+
+	ENTRY;
+	coda_vfs_stat.file_read++;
 
         cnp = ITOC(coda_inode);
         CHECK_CNODE(cnp);
@@ -167,6 +173,7 @@
         int result = 0;
 
         ENTRY;
+	coda_vfs_stat.file_write++;
 
         cnp = ITOC(coda_inode);
         CHECK_CNODE(cnp);
@@ -205,6 +212,7 @@
 	struct dentry cont_dentry;
         int result = 0;
         ENTRY;
+	coda_vfs_stat.fsync++;
 
 	if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||
 	      S_ISLNK(coda_inode->i_mode)))
diff -u --recursive --new-file v2.1.99/linux/fs/coda/psdev.c linux/fs/coda/psdev.c
--- v2.1.99/linux/fs/coda/psdev.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/psdev.c	Mon May  4 17:09:22 1998
@@ -44,7 +44,7 @@
 #include <linux/coda_fs_i.h>
 #include <linux/coda_psdev.h>
 #include <linux/coda_cache.h>
-#include <linux/coda_sysctl.h>
+#include <linux/coda_proc.h>
 
 
 /*
@@ -401,19 +401,106 @@
 
 #ifdef CONFIG_PROC_FS
 
-struct proc_dir_entry proc_coda = {
+struct proc_dir_entry proc_sys_root = {
+        PROC_SYS, 3, "sys",                     /* inode, name */
+        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,   /* mode, nlink, uid, gid */
+        0, &proc_dir_inode_operations,          /* size, ops */
+        NULL, NULL,                             /* get_info, fill_inode */
+        NULL,                                   /* next */
+        NULL, NULL                              /* parent, subdir */
+};
+
+struct proc_dir_entry proc_fs_coda = {
+        PROC_FS_CODA, 4, "coda",
+        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+        0, &proc_dir_inode_operations,
+	NULL, NULL,
+	NULL,
+	NULL, NULL
+};
+
+struct proc_dir_entry proc_sys_coda = {
         0, 4, "coda",
-        S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR, 2, 0, 0,
-        0, &proc_net_inode_operations,
+        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+        0, &proc_dir_inode_operations,
+	NULL, NULL,
+	NULL,
+	NULL, NULL
+};
 
+struct proc_dir_entry proc_fs = {
+        PROC_FS, 2, "fs",
+        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+        0, &proc_dir_inode_operations,
+	NULL, NULL,
+	NULL,
+	NULL, NULL
 };
 
+#if 0
 struct proc_dir_entry proc_coda_ncstats =  {
                 0 , 12, "coda-ncstats",
                 S_IFREG | S_IRUGO, 1, 0, 0,
                 0, &proc_net_inode_operations,
                 cfsnc_nc_info
         };
+#endif
+
+struct proc_dir_entry proc_coda_vfs =  {
+                PROC_VFS_STATS , 9, "vfs_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_vfs_stats_get_info
+        };
+
+struct proc_dir_entry proc_coda_vfs_control =  {
+                0 , 9, "vfs_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_vfs_stats_get_info
+        };
+
+struct proc_dir_entry proc_coda_upcall =  {
+                PROC_UPCALL_STATS , 12, "upcall_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_upcall_stats_get_info
+        };
+
+struct proc_dir_entry proc_coda_upcall_control =  {
+                0 , 12, "upcall_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_upcall_stats_get_info
+        };
+
+struct proc_dir_entry proc_coda_permission =  {
+                PROC_PERMISSION_STATS , 16, "permission_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_permission_stats_get_info
+        };
+
+struct proc_dir_entry proc_coda_permission_control =  {
+                0 , 16, "permission_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_permission_stats_get_info
+        };
+
+struct proc_dir_entry proc_coda_cache_inv =  {
+                PROC_CACHE_INV_STATS , 15, "cache_inv_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_cache_inv_stats_get_info
+        };
+
+struct proc_dir_entry proc_coda_cache_inv_control =  {
+                0 , 15, "cache_inv_stats",
+                S_IFREG | S_IRUGO, 1, 0, 0,
+                0, &proc_net_inode_operations,
+                coda_cache_inv_stats_get_info
+        };
 
 #endif
 
@@ -429,9 +516,27 @@
 	memset(coda_super_info, 0, sizeof(coda_super_info));
 	memset(&coda_callstats, 0, sizeof(coda_callstats));
 
+	reset_coda_vfs_stats();
+	reset_coda_upcall_stats();
+	reset_coda_permission_stats();
+	reset_coda_cache_inv_stats();
+
 #ifdef CONFIG_PROC_FS
-	proc_register(&proc_root,&proc_coda);
-	proc_register(&proc_coda, &proc_coda_ncstats);
+	proc_register(&proc_root,&proc_fs);
+	proc_register(&proc_fs,&proc_fs_coda);
+	proc_register(&proc_fs_coda,&proc_coda_vfs);
+	proc_register(&proc_fs_coda,&proc_coda_upcall);
+	proc_register(&proc_fs_coda,&proc_coda_permission);
+	proc_register(&proc_fs_coda,&proc_coda_cache_inv);
+#if 0
+	proc_register(&proc_fs_coda, &proc_coda_ncstats);
+#endif
+	proc_register(&proc_sys_root,&proc_sys_coda);
+	proc_register(&proc_sys_coda,&proc_coda_vfs_control);
+	proc_register(&proc_sys_coda,&proc_coda_upcall_control);
+	proc_register(&proc_sys_coda,&proc_coda_permission_control);
+	proc_register(&proc_sys_coda,&proc_coda_cache_inv_control);
+
 	coda_sysctl_init();
 #endif 
 	return 0;
@@ -476,8 +581,22 @@
 
 #if CONFIG_PROC_FS
         coda_sysctl_clean();
-        proc_unregister(&proc_coda, proc_coda_ncstats.low_ino);
-	proc_unregister(&proc_root, proc_coda.low_ino);
+
+        proc_unregister(&proc_sys_coda, proc_coda_cache_inv_control.low_ino);
+        proc_unregister(&proc_sys_coda, proc_coda_permission_control.low_ino);
+        proc_unregister(&proc_sys_coda, proc_coda_upcall_control.low_ino);
+	proc_unregister(&proc_sys_coda,proc_coda_vfs_control.low_ino);
+	proc_unregister(&proc_sys_root, proc_sys_coda.low_ino);
+
+#if 0
+	proc_unregister(&proc_fs_coda, proc_coda_ncstats.low_ino);
+#endif
+        proc_unregister(&proc_fs_coda, proc_coda_cache_inv.low_ino);
+        proc_unregister(&proc_fs_coda, proc_coda_permission.low_ino);
+        proc_unregister(&proc_fs_coda, proc_coda_upcall.low_ino);
+        proc_unregister(&proc_fs_coda, proc_coda_vfs.low_ino);
+	proc_unregister(&proc_fs, proc_fs_coda.low_ino);
+	proc_unregister(&proc_root, proc_fs.low_ino);
 #endif 
 }
 
diff -u --recursive --new-file v2.1.99/linux/fs/coda/stats.c linux/fs/coda/stats.c
--- v2.1.99/linux/fs/coda/stats.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/coda/stats.c	Tue May  5 10:52:17 1998
@@ -0,0 +1,416 @@
+/*
+ * stats.c
+ * 
+ * CODA operation statistics
+ *
+ * (c) March, 1998 Zhanyong Wan <zhanyong.wan@yale.edu>
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/sysctl.h>
+#include <linux/swapctl.h>
+#include <linux/proc_fs.h>
+#include <linux/malloc.h>
+#include <linux/stat.h>
+#include <linux/ctype.h>
+#include <asm/bitops.h>
+#include <asm/segment.h>
+#include <asm/uaccess.h>
+#include <linux/utsname.h>
+
+#include <linux/coda.h>
+#include <linux/coda_linux.h>
+#include <linux/coda_fs_i.h>
+#include <linux/coda_psdev.h>
+#include <linux/coda_cache.h>
+#include <linux/coda_proc.h>
+
+struct coda_vfs_stats		coda_vfs_stat;
+struct coda_permission_stats	coda_permission_stat;
+struct coda_cache_inv_stats	coda_cache_inv_stat;
+struct coda_upcall_stats_entry coda_upcall_stat[CFS_NCALLS];
+
+/* keep this in sync with coda.h! */
+char *coda_upcall_names[] = {
+	"totals      ",   /*  0 */
+	"noop        ",   /*  1 */
+	"root        ",   /*  2 */
+	"sync        ",   /*  3 */
+	"open        ",   /*  4 */
+	"close       ",   /*  5 */
+	"ioctl       ",   /*  6 */
+	"getattr     ",   /*  7 */
+	"setattr     ",   /*  8 */
+	"access      ",   /*  9 */
+	"lookup      ",   /* 10 */
+	"create      ",   /* 11 */
+	"remove      ",   /* 12 */
+	"link        ",   /* 13 */
+	"rename      ",   /* 14 */
+	"mkdir       ",   /* 15 */
+	"rmdir       ",   /* 16 */
+	"readdir     ",   /* 17 */
+	"symlink     ",   /* 18 */
+	"readlink    ",   /* 19 */
+	"fsync       ",   /* 20 */
+	"inactive    ",   /* 21 */
+	"vget        ",   /* 22 */
+	"signal      ",   /* 23 */
+	"replace     ",   /* 24 */
+	"flush       ",   /* 25 */
+	"purgeuser   ",   /* 26 */
+	"zapfile     ",   /* 27 */
+	"zapdir      ",   /* 28 */
+	"zapvnode    ",   /* 28 */
+	"purgefid    ",   /* 30 */
+	"open_by_path"    /* 31 */
+};
+
+
+
+
+void reset_coda_vfs_stats( void )
+{
+	memset( &coda_vfs_stat, 0, sizeof( coda_vfs_stat ) );
+}
+
+#if 0
+static void reset_upcall_entry( struct coda_upcall_stats_entry * pentry )
+{
+	pentry->count = 0;
+	pentry->time_sum = pentry->time_squared_sum = 0;
+}
+#endif
+
+void reset_coda_upcall_stats( void )
+{
+	memset( &coda_upcall_stat, 0, sizeof( coda_upcall_stat ) );
+}
+
+void reset_coda_permission_stats( void )
+{
+	memset( &coda_permission_stat, 0, sizeof( coda_permission_stat ) );
+}
+
+void reset_coda_cache_inv_stats( void )
+{
+	memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) );
+}
+
+
+void do_time_stats( struct coda_upcall_stats_entry * pentry, 
+		    unsigned long runtime )
+{
+	
+	unsigned long time = runtime * 1000 /HZ;	/* time in ms */
+	CDEBUG(D_SPECIAL, "time: %ld\n", time);
+
+	if ( pentry->count == 0 ) {
+		pentry->time_sum = pentry->time_squared_sum = 0;
+	}
+	
+	pentry->count++;
+	pentry->time_sum += time;
+	pentry->time_squared_sum += time*time;
+}
+
+
+
+void coda_upcall_stats(int opcode, long unsigned runtime) 
+{
+	struct coda_upcall_stats_entry * pentry;
+	
+	if ( opcode < 0 || opcode > CFS_NCALLS - 1) {
+		printk("Nasty opcode %d passed to coda_upcall_stats\n",
+		       opcode);
+		return;
+	}
+		
+	pentry = &coda_upcall_stat[opcode];
+	do_time_stats(pentry, runtime);
+
+        /* fill in the totals */
+	pentry = &coda_upcall_stat[0];
+	do_time_stats(pentry, runtime);
+
+}
+
+unsigned long get_time_average( const struct coda_upcall_stats_entry * pentry )
+{
+	return ( pentry->count == 0 ) ? 0 : pentry->time_sum / pentry->count;
+}
+
+static inline unsigned long absolute( unsigned long x )
+{
+	return x >= 0 ? x : -x;
+}
+
+static unsigned long sqr_root( unsigned long x )
+{
+	unsigned long y = x, r;
+	int n_bit = 0;
+  
+	if ( x == 0 )
+		return 0;
+	if ( x < 0)
+		x = -x;
+
+	while ( y ) {
+		y >>= 1;
+		n_bit++;
+	}
+  
+	r = 1 << (n_bit/2);
+  
+	while ( 1 ) {
+		r = (r + x/r)/2;
+		if ( r*r <= x && x < (r+1)*(r+1) )
+			break;
+	}
+  
+	return r;
+}
+
+unsigned long get_time_std_deviation( const struct coda_upcall_stats_entry * pentry )
+{
+	unsigned long time_avg;
+  
+	if ( pentry->count <= 1 )
+		return 0;
+  
+	time_avg = get_time_average( pentry );
+	return 
+	        sqr_root( (pentry->time_squared_sum / pentry->count) - 
+			    time_avg * time_avg );
+}
+
+int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
+			     void * buffer, size_t * lenp )
+{
+	if ( write ) {
+		reset_coda_vfs_stats();
+	}
+  
+	*lenp = 0;
+	return 0;
+}
+
+int do_reset_coda_upcall_stats( ctl_table * table, int write, 
+				struct file * filp, void * buffer, 
+				size_t * lenp )
+{
+	if ( write ) {
+		reset_coda_upcall_stats();
+	}
+  
+	*lenp = 0;
+	return 0;
+}
+
+int do_reset_coda_permission_stats( ctl_table * table, int write, 
+				    struct file * filp, void * buffer, 
+				    size_t * lenp )
+{
+	if ( write ) {
+		reset_coda_permission_stats();
+	}
+  
+	*lenp = 0;
+	return 0;
+}
+
+int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
+				   struct file * filp, void * buffer, 
+				   size_t * lenp )
+{
+	if ( write ) {
+		reset_coda_cache_inv_stats();
+	}
+  
+	*lenp = 0;
+	return 0;
+}
+
+int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
+			     int length, int dummy )
+{
+	int len=0;
+	off_t begin;
+	struct coda_vfs_stats * ps = & coda_vfs_stat;
+  
+  /* this works as long as we are below 1024 characters! */
+	len += sprintf( buffer,
+			"Coda VFS statistics\n"
+			"===================\n\n"
+			"File Operations:\n"
+			"\tfile_read\t%9d\n"
+			"\tfile_write\t%9d\n"
+			"\tfile_mmap\t%9d\n"
+			"\topen\t\t%9d\n"
+			"\trelase\t\t%9d\n"
+			"\tfsync\t\t%9d\n\n"
+			"Dir Operations:\n"
+			"\treaddir\t\t%9d\n\n"
+			"Inode Operations\n"
+			"\tcreate\t\t%9d\n"
+			"\tlookup\t\t%9d\n"
+			"\tlink\t\t%9d\n"
+			"\tunlink\t\t%9d\n"
+			"\tsymlink\t\t%9d\n"
+			"\tmkdir\t\t%9d\n"
+			"\trmdir\t\t%9d\n"
+			"\trename\t\t%9d\n"
+			"\tpermission\t%9d\n"
+			"\treadpage\t%9d\n",
+
+			/* file operations */
+			ps->file_read,
+			ps->file_write,
+			ps->file_mmap,
+			ps->open,
+			ps->release,
+			ps->fsync,
+
+			/* dir operations */
+			ps->readdir,
+		  
+			/* inode operations */
+			ps->create,
+			ps->lookup,
+			ps->link,
+			ps->unlink,
+			ps->symlink,
+			ps->mkdir,
+			ps->rmdir,
+			ps->rename,
+			ps->permission,
+			ps->readpage );
+  
+	begin = offset;
+	*start = buffer + begin;
+	len -= begin;
+
+	if ( len > length )
+		len = length;
+	if ( len < 0 )
+		len = 0;
+
+	return len;
+}
+
+int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
+				int length, int dummy )
+{
+	int len=0;
+	int i;
+	off_t begin;
+	off_t pos = 0;
+	char tmpbuf[80];
+	int tmplen = 0;
+
+	ENTRY;
+	/* this works as long as we are below 1024 characters! */
+	if ( offset < 80 ) 
+		len += sprintf( buffer,"%-79s\n",	"Coda upcall statistics");
+	if ( offset < 160) 
+		len += sprintf( buffer + len,"%-79s\n",	"======================");
+	if ( offset < 240) 
+		len += sprintf( buffer + len,"%-79s\n",	"upcall\t\t    count\tavg time(ms)\tstd deviation(ms)");
+	if ( offset < 320) 
+		len += sprintf( buffer + len,"%-79s\n",	"------\t\t    -----\t------------\t-----------------");
+	pos = 320; 
+	for ( i = 0 ; i < CFS_NCALLS ; i++ ) {
+		tmplen += sprintf(tmpbuf,"%s\t%9d\t%10ld\t%10ld", 
+				  coda_upcall_names[i],
+				  coda_upcall_stat[i].count, 
+				  get_time_average(&coda_upcall_stat[i]),
+				  coda_upcall_stat[i].time_squared_sum);
+		pos += 80;
+		if ( pos < offset ) 
+			continue; 
+		len += sprintf(buffer + len, "%-79s\n", tmpbuf);
+		if ( len >= length ) 
+			break; 
+	}
+  
+	begin = len- (pos - offset);
+	*start = buffer + begin;
+	len -= begin;
+
+	if ( len > length )
+		len = length;
+	if ( len < 0 )
+		len = 0;
+	EXIT;
+	return len;
+}
+
+int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
+				    int length, int dummy )
+{
+	int len=0;
+	off_t begin;
+	struct coda_permission_stats * ps = & coda_permission_stat;
+  
+	/* this works as long as we are below 1024 characters! */
+	len += sprintf( buffer,
+			"Coda permission statistics\n"
+			"==========================\n\n"
+			"count\t\t%9d\n"
+			"hit count\t%9d\n",
+
+			ps->count,
+			ps->hit_count );
+  
+	begin = offset;
+	*start = buffer + begin;
+	len -= begin;
+
+	if ( len > length )
+		len = length;
+	if ( len < 0 )
+		len = 0;
+
+	return len;
+}
+
+int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
+				   int length, int dummy )
+{
+	int len=0;
+	off_t begin;
+	struct coda_cache_inv_stats * ps = & coda_cache_inv_stat;
+  
+	/* this works as long as we are below 1024 characters! */
+	len += sprintf( buffer,
+			"Coda cache invalidation statistics\n"
+			"==================================\n\n"
+			"flush\t\t%9d\n"
+			"purge user\t%9d\n"
+			"zap_dir\t\t%9d\n"
+			"zap_file\t%9d\n"
+			"zap_vnode\t%9d\n"
+			"purge_fid\t%9d\n"
+			"replace\t\t%9d\n",
+			ps->flush,
+			ps->purge_user,
+			ps->zap_dir,
+			ps->zap_file,
+			ps->zap_vnode,
+			ps->purge_fid,
+			ps->replace );
+  
+	begin = offset;
+	*start = buffer + begin;
+	len -= begin;
+
+	if ( len > length )
+		len = length;
+	if ( len < 0 )
+		len = 0;
+
+	return len;
+}
+
diff -u --recursive --new-file v2.1.99/linux/fs/coda/symlink.c linux/fs/coda/symlink.c
--- v2.1.99/linux/fs/coda/symlink.c	Tue Mar 10 10:03:33 1998
+++ linux/fs/coda/symlink.c	Mon May  4 17:09:22 1998
@@ -23,6 +23,7 @@
 #include <linux/coda_psdev.h>
 #include <linux/coda_fs_i.h>
 #include <linux/coda_cache.h>
+#include <linux/coda_proc.h>
 
 static int coda_readlink(struct dentry *de, char *buffer, int length);
 static struct dentry *coda_follow_link(struct dentry *, struct dentry *);
@@ -60,7 +61,7 @@
         ENTRY;
 
         cp = ITOC(inode);
-        CHECK_CNODE(cp);
+	coda_vfs_stat.readlink++;
 
         /* the maximum length we receive is len */
         if ( length > CFS_MAXPATHLEN ) 
@@ -93,11 +94,11 @@
 	unsigned int len;
 	char mem[CFS_MAXPATHLEN];
 	char *path;
-ENTRY;
+	ENTRY;
 	CDEBUG(D_INODE, "(%x/%ld)\n", inode->i_dev, inode->i_ino);
 	
         cnp = ITOC(inode);
-        CHECK_CNODE(cnp);
+	coda_vfs_stat.follow_link++;
 
 	len = CFS_MAXPATHLEN;
 	error = venus_readlink(inode->i_sb, &(cnp->c_fid), mem, &len);
diff -u --recursive --new-file v2.1.99/linux/fs/coda/sysctl.c linux/fs/coda/sysctl.c
--- v2.1.99/linux/fs/coda/sysctl.c	Tue Mar 10 10:03:33 1998
+++ linux/fs/coda/sysctl.c	Mon May  4 17:09:22 1998
@@ -26,7 +26,7 @@
 #include <linux/coda_fs_i.h>
 #include <linux/coda_psdev.h>
 #include <linux/coda_cache.h>
-#include <linux/coda_sysctl.h>
+#include <linux/coda_proc.h>
 extern int coda_debug;
 /* extern int cfsnc_use; */
 extern int coda_print_entry;
@@ -47,6 +47,10 @@
 #define CODA_TIMEOUT    3       /* timeout on upcalls to become intrble */
 #define CODA_MC         4       /* use/do not use the access cache */
 #define CODA_HARD       5       /* mount type "hard" or "soft" */
+#define CODA_VFS 	 6       /* vfs statistics */
+#define CODA_UPCALL 	 7       /* upcall statistics */
+#define CODA_PERMISSION	 8       /* permission statistics */
+#define CODA_CACHE_INV 	 9       /* cache invalidation statistics */
 
 
 
@@ -56,6 +60,10 @@
  	{CODA_MC, "accesscache", &coda_access_cache, sizeof(int), 0644, NULL, &coda_dointvec}, 
  	{CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &coda_dointvec},
  	{CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &coda_dointvec},
+ 	{CODA_VFS, "vfs_stats", NULL, 0, 0644, NULL, &do_reset_coda_vfs_stats},
+ 	{CODA_UPCALL, "upcall_stats", NULL, 0, 0644, NULL, &do_reset_coda_upcall_stats},
+ 	{CODA_PERMISSION, "permission_stats", NULL, 0, 0644, NULL, &do_reset_coda_permission_stats},
+ 	{CODA_CACHE_INV, "cache_inv_stats", NULL, 0, 0644, NULL, &do_reset_coda_cache_inv_stats},
 	{ 0 }
 };
 
diff -u --recursive --new-file v2.1.99/linux/fs/coda/upcall.c linux/fs/coda/upcall.c
--- v2.1.99/linux/fs/coda/upcall.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/upcall.c	Mon May  4 17:09:22 1998
@@ -37,6 +37,11 @@
 #include <linux/coda_psdev.h>
 #include <linux/coda_fs_i.h>
 #include <linux/coda_cache.h>
+#include <linux/coda_proc.h> 
+
+
+static int  coda_upcall(struct coda_sb_info *mntinfo, int inSize, int *outSize, 
+		       union inputArgs *buffer);
 
 #define UPARG(op)\
 do {\
@@ -68,10 +73,11 @@
         union inputArgs *inp;
         union outputArgs *outp;
         int insize, outsize, error;
-ENTRY;
+	ENTRY;
 
         insize = SIZE(root);
         UPARG(CFS_ROOT);
+
 	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 	
 	if (error) {
@@ -92,7 +98,7 @@
 {
         union inputArgs *inp;
         union outputArgs *outp;
-        int insize, outsize, error;
+	        int insize, outsize, error;
 ENTRY;
         insize = SIZE(getattr); 
 	UPARG(CFS_GETATTR);
@@ -458,8 +464,8 @@
 int venus_fsync(struct super_block *sb, struct ViceFid *fid)
 {
         union inputArgs *inp;
-        union outputArgs *outp;
-        int insize, outsize, error;
+        union outputArgs *outp; 
+	int insize, outsize, error;
 	
 	insize=SIZE(fsync);
 	UPARG(CFS_FSYNC);
@@ -476,8 +482,8 @@
 int venus_access(struct super_block *sb, struct ViceFid *fid, int mask)
 {
         union inputArgs *inp;
-        union outputArgs *outp;
-        int insize, outsize, error;
+        union outputArgs *outp; 
+	int insize, outsize, error;
 
 	insize = SIZE(access);
 	UPARG(CFS_ACCESS);
@@ -497,8 +503,8 @@
 		 unsigned int cmd, struct PioctlData *data)
 {
         union inputArgs *inp;
-        union outputArgs *outp;
-        int insize, outsize, error;
+        union outputArgs *outp;  
+	int insize, outsize, error;
 	int iocsize;
 
 	insize = VC_MAXMSGSIZE;
@@ -583,11 +589,13 @@
  * reply and return Venus' error, also POSITIVE. 
  * 
  */
-static inline void coda_waitfor_upcall(struct vmsg *vmp)
+static inline unsigned long coda_waitfor_upcall(struct vmsg *vmp)
 {
 	struct wait_queue	wait = { current, NULL };
+	unsigned long posttime;
 
 	vmp->vm_posttime = jiffies;
+	posttime = jiffies;
 
 	add_wait_queue(&vmp->vm_sleep, &wait);
 	for (;;) {
@@ -616,13 +624,17 @@
 	remove_wait_queue(&vmp->vm_sleep, &wait);
 	current->state = TASK_RUNNING;
 
-	return;
+	CDEBUG(D_SPECIAL, "posttime: %ld, returned: %ld\n", posttime, jiffies-posttime);
+	return 	(jiffies - posttime);
+
 }
 
 
-int coda_upcall(struct coda_sb_info *sbi, int inSize, int *outSize, 
+static int coda_upcall(struct coda_sb_info *sbi, 
+		int inSize, int *outSize, 
 		union inputArgs *buffer) 
 {
+	unsigned long runtime; 
 	struct vcomm *vcommp;
 	union outputArgs *out;
 	struct vmsg *vmp;
@@ -635,7 +647,6 @@
 	}
 	vcommp = sbi->sbi_vcomm;
 
-	clstats(((union inputArgs *)buffer)->ih.opcode);
 
 	if (!vcomm_open(vcommp))
                 return(ENODEV);
@@ -670,7 +681,8 @@
 	 * ENODEV.  */
 
 	/* Go to sleep.  Wake up on signals only after the timeout. */
-	coda_waitfor_upcall(vmp);
+	runtime = coda_waitfor_upcall(vmp);
+	coda_upcall_stats(((union inputArgs *)buffer)->ih.opcode, runtime);
 
 	CDEBUG(D_TIMING, "opc: %d time: %ld uniq: %d size: %d\n",
 	       vmp->vm_opcode, jiffies - vmp->vm_posttime, 
diff -u --recursive --new-file v2.1.99/linux/fs/dcache.c linux/fs/dcache.c
--- v2.1.99/linux/fs/dcache.c	Sat May  2 14:19:53 1998
+++ linux/fs/dcache.c	Sat May  2 14:07:52 1998
@@ -430,12 +430,17 @@
  * more memory, but aren't really sure how much. So we
  * carefully try to free a _bit_ of our dcache, but not
  * too much.
+ *
+ * Priority:
+ *   0 - very urgent: schrink everything
+ *  ...
+ *   6 - base-level: try to shrink a bit.
  */
-void shrink_dcache_memory(void)
+void shrink_dcache_memory(int priority, unsigned int gfp_mask)
 {
 	int count = select_dcache(32, 8);
 	if (count)
-		prune_dcache(count);
+		prune_dcache((count << 6) >> priority);
 }
 
 #define NAME_ALLOC_LEN(len)	((len+16) & ~15)
diff -u --recursive --new-file v2.1.99/linux/fs/dquot.c linux/fs/dquot.c
--- v2.1.99/linux/fs/dquot.c	Tue Mar 10 10:03:33 1998
+++ linux/fs/dquot.c	Wed May  6 10:56:05 1998
@@ -375,7 +375,8 @@
 	if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
 		return(QUOTA_OK);
 	if (dquot->dq_ihardlimit &&
-	   (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit && !fsuser()) {
+	   (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit && 
+	    !capable(CAP_SYS_RESOURCE)) {
 		if ((dquot->dq_flags & DQ_INODES) == 0 &&
                      need_print_warning(type, dquot)) {
 			sprintf(quotamessage, "%s: write failed, %s file limit reached\r\n",
@@ -387,7 +388,8 @@
 	}
 	if (dquot->dq_isoftlimit &&
 	   (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
-	    dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime && !fsuser()) {
+	    dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime && 
+	    !capable(CAP_SYS_RESOURCE)) {
                 if (need_print_warning(type, dquot)) {
 			sprintf(quotamessage, "%s: warning, %s file quota exceeded too long.\r\n",
 		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
@@ -397,7 +399,8 @@
 	}
 	if (dquot->dq_isoftlimit &&
 	   (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
-	    dquot->dq_itime == 0 && !fsuser()) {
+	    dquot->dq_itime == 0 && 
+	    !capable(CAP_SYS_RESOURCE)) {
                 if (need_print_warning(type, dquot)) {
 			sprintf(quotamessage, "%s: warning, %s file quota exceeded\r\n",
 		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
@@ -413,7 +416,8 @@
 	if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
 		return(QUOTA_OK);
 	if (dquot->dq_bhardlimit &&
-	   (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit && !fsuser()) {
+	   (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit && 
+	    !capable(CAP_SYS_RESOURCE)) {
 		if ((dquot->dq_flags & DQ_BLKS) == 0 &&
                      need_print_warning(type, dquot)) {
 			sprintf(quotamessage, "%s: write failed, %s disk limit reached.\r\n",
@@ -425,7 +429,8 @@
 	}
 	if (dquot->dq_bsoftlimit &&
 	   (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
-	    dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime && !fsuser()) {
+	    dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime && 
+	    !capable(CAP_SYS_RESOURCE)) {
                 if (need_print_warning(type, dquot)) {
 			sprintf(quotamessage, "%s: write failed, %s disk quota exceeded too long.\r\n",
 		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
@@ -435,7 +440,8 @@
 	}
 	if (dquot->dq_bsoftlimit &&
 	   (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
-	    dquot->dq_btime == 0 && !fsuser()) {
+	    dquot->dq_btime == 0 && 
+	    !capable(CAP_SYS_RESOURCE)) {
                 if (need_print_warning(type, dquot)) {
 			sprintf(quotamessage, "%s: warning, %s disk quota exceeded\r\n",
 		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
@@ -1039,11 +1045,12 @@
 			break;
 		case Q_GETQUOTA:
 			if (((type == USRQUOTA && current->uid != id) ||
-			     (type == GRPQUOTA && in_group_p(id))) && !fsuser())
+			     (type == GRPQUOTA && in_group_p(id))) && 
+			    !capable(CAP_SYS_ADMIN))
 				goto out;
 			break;
 		default:
-			if (!fsuser())
+			if (!capable(CAP_SYS_ADMIN))
 				goto out;
 	}
 
diff -u --recursive --new-file v2.1.99/linux/fs/exec.c linux/fs/exec.c
--- v2.1.99/linux/fs/exec.c	Mon Apr  6 17:41:00 1998
+++ linux/fs/exec.c	Wed May  6 11:01:46 1998
@@ -419,6 +419,7 @@
 	retval = new_page_tables(current);
 	if (retval)
 		goto fail_restore;
+	activate_context(current);
 	up(&mm->mmap_sem);
 	mmput(old_mm);
 	return 0;
@@ -564,7 +565,7 @@
 int prepare_binprm(struct linux_binprm *bprm)
 {
 	int mode;
-	int retval,id_change;
+	int retval,id_change,cap_raised;
 	struct inode * inode = bprm->dentry->d_inode;
 
 	mode = inode->i_mode;
@@ -584,7 +585,7 @@
 
 	bprm->e_uid = current->euid;
 	bprm->e_gid = current->egid;
-	id_change = 0;
+	id_change = cap_raised = 0;
 
 	/* Set-uid? */
 	if (mode & S_ISUID) {
@@ -630,21 +631,25 @@
 			cap_set_full(bprm->cap_effective);
 	}
 
-        /* We use a conservative definition of suid for capabilities.
-         * The process is suid if the permitted set is not a subset of
-         * the current permitted set after the exec call.
-         *         new permitted set = forced | (allowed & inherited)
-         *                       pP' = fP     | (fI      & pI)
-         */
-
-        if ((bprm->cap_permitted.cap |
-	     (current->cap_inheritable.cap &
-	      bprm->cap_inheritable.cap)) &
-	    ~current->cap_permitted.cap) {
-		id_change = 1;
+        /* Only if pP' is _not_ a subset of pP, do we consider there
+         * has been a capability related "change of capability".  In
+         * such cases, we need to check that the elevation of
+         * privilege does not go against other system constraints.
+         * The new Permitted set is defined below -- see (***). */
+	{
+		kernel_cap_t working =
+			cap_combine(bprm->cap_permitted,
+				    cap_intersect(bprm->cap_inheritable,
+						  current->cap_inheritable));
+		if (!cap_issubset(working, current->cap_permitted)) {
+			cap_raised = 1;
+		}
 	}
 
-	if (id_change) {
+
+
+
+	if (id_change || cap_raised) {
 		/* We can't suid-execute if we're sharing parts of the executable */
 		/* or if we're being traced (or if suid execs are not allowed)    */
 		/* (current->mm->count > 1 is ok, as we'll get a new mm anyway)   */
@@ -653,8 +658,10 @@
 		    || (current->fs->count > 1)
 		    || (atomic_read(&current->sig->count) > 1)
 		    || (current->files->count > 1)) {
-			if (!suser())
-				return -EPERM;
+ 			if (id_change && !capable(CAP_SETUID))
+ 				return -EPERM;
+ 			if (cap_raised && !capable(CAP_SETPCAP))
+  				return -EPERM;
 		}
 	}
 
@@ -669,7 +676,7 @@
  * The formula used for evolving capabilities is:
  *
  *       pI' = pI
- *       pP' = fP | (fI & pI)
+ * (***) pP' = fP | (fI & pI)
  *       pE' = pP' & fE          [NB. fE is 0 or ~0]
  *
  * I=Inheritable, P=Permitted, E=Effective // p=process, f=file
@@ -678,11 +685,18 @@
 
 void compute_creds(struct linux_binprm *bprm) 
 {
-	int new_permitted = bprm->cap_permitted.cap |
-		(bprm->cap_inheritable.cap & current->cap_inheritable.cap);
-
-	current->cap_permitted.cap = new_permitted;
-	current->cap_effective.cap = new_permitted & bprm->cap_effective.cap;
+	/* For init, we want to retain the capabilities set
+         * in the init_task struct. Thus we skip the usual
+         * capability rules */
+	if (current->pid != 1) {
+		int new_permitted = bprm->cap_permitted.cap |
+			(bprm->cap_inheritable.cap & 
+			current->cap_inheritable.cap);
+
+		current->cap_permitted.cap = new_permitted;
+		current->cap_effective.cap = new_permitted & 
+						bprm->cap_effective.cap;
+	}
 	
         /* AUD: Audit candidate if current->cap_effective is set */
 
diff -u --recursive --new-file v2.1.99/linux/fs/ext2/acl.c linux/fs/ext2/acl.c
--- v2.1.99/linux/fs/ext2/acl.c	Sun Dec 21 17:41:24 1997
+++ linux/fs/ext2/acl.c	Wed May  6 10:56:08 1998
@@ -51,8 +51,11 @@
 	 * Access is always granted for root. We now check last,
          * though, for BSD process accounting correctness
 	 */
-	if (((mode & mask & S_IRWXO) == mask) || fsuser())
+	if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
 		return 0;
-	else
-		return -EACCES;
+	if ((mask == S_IROTH) ||
+	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
+		if (capable(CAP_DAC_READ_SEARCH))
+			return 0;
+	return -EACCES;
 }
diff -u --recursive --new-file v2.1.99/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
--- v2.1.99/linux/fs/ext2/balloc.c	Mon Apr  6 17:41:00 1998
+++ linux/fs/ext2/balloc.c	Wed May  6 10:56:05 1998
@@ -383,7 +383,8 @@
 	if (le32_to_cpu(es->s_free_blocks_count) <= le32_to_cpu(es->s_r_blocks_count) &&
 	    ((sb->u.ext2_sb.s_resuid != current->fsuid) &&
 	     (sb->u.ext2_sb.s_resgid == 0 ||
-	      !in_group_p (sb->u.ext2_sb.s_resgid)) && !fsuser())) {
+	      !in_group_p (sb->u.ext2_sb.s_resgid)) && 
+	     !capable(CAP_SYS_RESOURCE))) {
 		unlock_super (sb);
 		return 0;
 	}
diff -u --recursive --new-file v2.1.99/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.1.99/linux/fs/ext2/file.c	Wed Apr  8 19:36:28 1998
+++ linux/fs/ext2/file.c	Wed May  6 10:56:05 1998
@@ -144,7 +144,7 @@
 
 	/* was any of the uid bits set? */
 	mode &= inode->i_mode;
-	if (mode && !suser()) {
+	if (mode && !capable(CAP_FSETID)) {
 		inode->i_mode &= ~mode;
 		mark_inode_dirty(inode);
 	}
diff -u --recursive --new-file v2.1.99/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.1.99/linux/fs/ext2/inode.c	Mon Apr  6 17:41:00 1998
+++ linux/fs/ext2/inode.c	Wed May  6 10:56:05 1998
@@ -726,9 +726,9 @@
 	     (ATTR_FLAG_APPEND | ATTR_FLAG_IMMUTABLE)) ^
 	    (inode->u.ext2_i.i_flags &
 	     (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL))) {
-		if (!fsuser())
+		if (!capable(CAP_LINUX_IMMUTABLE))
 			goto out;
-	} else if ((current->fsuid != inode->i_uid) && !fsuser())
+	} else if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 		goto out;
 
 	retval = inode_change_ok(inode, iattr);
diff -u --recursive --new-file v2.1.99/linux/fs/ext2/ioctl.c linux/fs/ext2/ioctl.c
--- v2.1.99/linux/fs/ext2/ioctl.c	Mon Apr  6 17:41:00 1998
+++ linux/fs/ext2/ioctl.c	Wed May  6 10:56:05 1998
@@ -39,10 +39,11 @@
 		    (inode->u.ext2_i.i_flags &
 		     (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL))) {
 			/* This test looks nicer. Thanks to Pauline Middelink */
-			if (!fsuser())
+			if (!capable(CAP_LINUX_IMMUTABLE))
 				return -EPERM;
 		} else
-			if ((current->fsuid != inode->i_uid) && !fsuser())
+			if ((current->fsuid != inode->i_uid) && 
+			    !capable(CAP_FOWNER))
 				return -EPERM;
 		if (IS_RDONLY(inode))
 			return -EROFS;
@@ -70,7 +71,7 @@
 	case EXT2_IOC_GETVERSION:
 		return put_user(inode->u.ext2_i.i_version, (int *) arg);
 	case EXT2_IOC_SETVERSION:
-		if ((current->fsuid != inode->i_uid) && !fsuser())
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
 		if (IS_RDONLY(inode))
 			return -EROFS;
diff -u --recursive --new-file v2.1.99/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.1.99/linux/fs/ext2/namei.c	Sat May  2 14:19:53 1998
+++ linux/fs/ext2/namei.c	Wed May  6 10:56:05 1998
@@ -631,7 +631,7 @@
 	retval = -EPERM;
 	if ((dir->i_mode & S_ISVTX) && 
 	    current->fsuid != inode->i_uid &&
-	    current->fsuid != dir->i_uid && !fsuser())
+	    current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rmdir;
 	if (inode == dir)	/* we may not delete ".", but "../dir" is ok */
 		goto end_rmdir;
@@ -725,7 +725,7 @@
 		goto end_unlink;
 	if ((dir->i_mode & S_ISVTX) &&
 	    current->fsuid != inode->i_uid &&
-	    current->fsuid != dir->i_uid && !fsuser())
+	    current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto end_unlink;
 
 	retval = -EIO;
@@ -923,7 +923,7 @@
 	retval = -EPERM;
 	if ((old_dir->i_mode & S_ISVTX) && 
 	    current->fsuid != old_inode->i_uid &&
-	    current->fsuid != old_dir->i_uid && !fsuser())
+	    current->fsuid != old_dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rename;
 	if (IS_APPEND(old_inode) || IS_IMMUTABLE(old_inode))
 		goto end_rename;
@@ -964,7 +964,7 @@
 	if (new_inode) {
 		if ((new_dir->i_mode & S_ISVTX) &&
 		    current->fsuid != new_inode->i_uid &&
-		    current->fsuid != new_dir->i_uid && !fsuser())
+		    current->fsuid != new_dir->i_uid && !capable(CAP_FOWNER))
 			goto end_rename;
 		if (IS_APPEND(new_inode) || IS_IMMUTABLE(new_inode))
 			goto end_rename;
diff -u --recursive --new-file v2.1.99/linux/fs/minix/namei.c linux/fs/minix/namei.c
--- v2.1.99/linux/fs/minix/namei.c	Thu Feb 12 20:56:12 1998
+++ linux/fs/minix/namei.c	Wed May  6 10:56:05 1998
@@ -416,7 +416,7 @@
 
         if ((dir->i_mode & S_ISVTX) &&
             current->fsuid != inode->i_uid &&
-            current->fsuid != dir->i_uid && !fsuser())
+            current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rmdir;
 	if (inode->i_dev != dir->i_dev)
 		goto end_rmdir;
@@ -482,7 +482,7 @@
 	}
 	if ((dir->i_mode & S_ISVTX) &&
 	    current->fsuid != inode->i_uid &&
-	    current->fsuid != dir->i_uid && !fsuser())
+	    current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto end_unlink;
 	if (de->inode != inode->i_ino) {
 		retval = -ENOENT;
@@ -641,7 +641,7 @@
 	retval = -EPERM;
 	if ((old_dir->i_mode & S_ISVTX) && 
 	    current->fsuid != old_inode->i_uid &&
-	    current->fsuid != old_dir->i_uid && !fsuser())
+	    current->fsuid != old_dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rename;
 	new_inode = new_dentry->d_inode;
 	new_bh = minix_find_entry(new_dir, new_dentry->d_name.name,
@@ -673,7 +673,7 @@
 	retval = -EPERM;
 	if (new_inode && (new_dir->i_mode & S_ISVTX) && 
 	    current->fsuid != new_inode->i_uid &&
-	    current->fsuid != new_dir->i_uid && !fsuser())
+	    current->fsuid != new_dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rename;
 	if (S_ISDIR(old_inode->i_mode)) {
 		retval = -ENOTDIR;
diff -u --recursive --new-file v2.1.99/linux/fs/namei.c linux/fs/namei.c
--- v2.1.99/linux/fs/namei.c	Sat May  2 14:19:53 1998
+++ linux/fs/namei.c	Wed May  6 10:56:08 1998
@@ -43,17 +43,24 @@
  *
  * The new code replaces the old recursive symlink resolution with
  * an iterative one (in case of non-nested symlink chains).  It does
- * this by looking up the symlink name from the particular filesystem,
- * and then follows this name as if it were a user-supplied one.  This
- * is done solely in the VFS level, such that <fs>_follow_link() is not
- * used any more and could be removed in future.  As a side effect,
- * dir_namei(), _namei() and follow_link() are now replaced with a single
- * function lookup_dentry() that can handle all the special cases of the former
- * code.
+ * this with calls to <fs>_follow_link().
+ * As a side effect, dir_namei(), _namei() and follow_link() are now 
+ * replaced with a single function lookup_dentry() that can handle all 
+ * the special cases of the former code.
  *
  * With the new dcache, the pathname is stored at each inode, at least as
  * long as the refcount of the inode is positive.  As a side effect, the
  * size of the dcache depends on the inode cache and thus is dynamic.
+ *
+ * [29-Apr-1998 C. Scott Ananian] Updated above description of symlink
+ * resolution to correspond with current state of the code.
+ *
+ * Note that the symlink resolution is not *completely* iterative.
+ * There is still a significant amount of tail- and mid- recursion in
+ * the algorithm.  Also, note that <fs>_readlink() is not used in
+ * lookup_dentry(): lookup_dentry() on the result of <fs>_readlink()
+ * may return different results than <fs>_follow_link().  Many virtual
+ * filesystems (including /proc) exhibit this behavior.
  */
 
 /* [24-Feb-97 T. Schoebel-Theuer] Side effects caused by new implementation:
@@ -191,8 +198,13 @@
 		mode >>= 6;
 	else if (in_group_p(inode->i_gid))
 		mode >>= 3;
-	if (((mode & mask & 0007) == mask) || fsuser())
+	if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
 		return 0;
+	/* read and search access */
+	if ((mask == S_IROTH) ||
+	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
+		if (capable(CAP_DAC_READ_SEARCH))
+			return 0;
 	return -EACCES;
 }
 
@@ -699,7 +711,7 @@
 
 	lock_kernel();
 	error = -EPERM;
-	if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !fsuser()))
+	if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !capable(CAP_SYS_ADMIN)))
 		goto out;
 	error = -EINVAL;
 	switch (mode & S_IFMT) {
diff -u --recursive --new-file v2.1.99/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- v2.1.99/linux/fs/nfsd/nfsctl.c	Mon Jan 12 14:39:48 1998
+++ linux/fs/nfsd/nfsctl.c	Wed May  6 10:56:05 1998
@@ -148,7 +148,7 @@
 	if (!initialized)
 		nfsd_init();
 	err = -EPERM;
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		goto done;
 	}
 	err = -EFAULT;
diff -u --recursive --new-file v2.1.99/linux/fs/open.c linux/fs/open.c
--- v2.1.99/linux/fs/open.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/open.c	Wed May  6 12:50:40 1998
@@ -285,12 +285,14 @@
 
 /*
  * access() needs to use the real uid/gid, not the effective uid/gid.
- * We do this by temporarily setting fsuid/fsgid to the wanted values
+ * We do this by temporarily clearing all FS-related capabilities and
+ * switching the fsuid/fsgid around to the real ones.
  */
 asmlinkage int sys_access(const char * filename, int mode)
 {
 	struct dentry * dentry;
 	int old_fsuid, old_fsgid;
+	kernel_cap_t old_cap;
 	int res = -EINVAL;
 
 	lock_kernel();
@@ -298,9 +300,15 @@
 		goto out;
 	old_fsuid = current->fsuid;
 	old_fsgid = current->fsgid;
+	old_cap = current->cap_effective;
+
 	current->fsuid = current->uid;
 	current->fsgid = current->gid;
 
+	/* Clear the capabilities if we switch to a non-root user */
+	if (current->uid)
+		cap_clear(current->cap_effective);
+
 	dentry = namei(filename);
 	res = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
@@ -310,6 +318,7 @@
 
 	current->fsuid = old_fsuid;
 	current->fsgid = old_fsgid;
+	current->cap_effective = old_cap;
 out:
 	unlock_kernel();
 	return res;
@@ -411,7 +420,7 @@
 		goto dput_and_out;
 
 	error = -EPERM;
-	if (!fsuser())
+	if (!capable(CAP_SYS_CHROOT))
 		goto dput_and_out;
 
 	/* exchange dentries */
@@ -833,7 +842,7 @@
 	int ret = -EPERM;
 
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_TTY_CONFIG))
 		goto out;
 	/* If there is a controlling tty, hang it up */
 	if (current->tty)
diff -u --recursive --new-file v2.1.99/linux/fs/pipe.c linux/fs/pipe.c
--- v2.1.99/linux/fs/pipe.c	Thu Mar 26 15:57:05 1998
+++ linux/fs/pipe.c	Mon May  4 18:02:09 1998
@@ -54,7 +54,7 @@
 		}
 	} else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
 		if (PIPE_EMPTY(*inode)) {
-			if (!PIPE_WRITERS(*inode))
+			if (!PIPE_WRITERS(*inode) || !count)
 				return 0;
 		}
 		if (signal_pending(current))
diff -u --recursive --new-file v2.1.99/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.1.99/linux/fs/proc/array.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/proc/array.c	Wed May  6 11:01:45 1998
@@ -764,6 +764,17 @@
 	return buffer;
 }
 
+extern inline char *task_cap(struct task_struct *p, char *buffer)
+{
+    return buffer + sprintf(buffer, "CapInh:\t%016x\n"
+			    "CapPrm:\t%016x\n"
+			    "CapEff:\t%016x\n",
+			    p->cap_inheritable.cap,
+			    p->cap_permitted.cap,
+			    p->cap_effective.cap);
+}
+
+
 static int get_status(int pid, char * buffer)
 {
 	char * orig = buffer;
@@ -778,6 +789,7 @@
 	buffer = task_state(tsk, buffer);
 	buffer = task_mem(tsk, buffer);
 	buffer = task_sig(tsk, buffer);
+	buffer = task_cap(tsk, buffer);
 	return buffer - orig;
 }
 
diff -u --recursive --new-file v2.1.99/linux/fs/proc/inode.c linux/fs/proc/inode.c
--- v2.1.99/linux/fs/proc/inode.c	Thu Apr 23 20:21:37 1998
+++ linux/fs/proc/inode.c	Wed May  6 10:56:08 1998
@@ -145,8 +145,13 @@
 		mode >>= 6;
 	else if (in_group_p(inode->i_gid))
 		mode >>= 3;
-	if (((mode & mask & 0007) == mask) || fsuser())
+	if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
 		return 0;
+	/* read and search access */
+	if ((mask == S_IROTH) ||
+	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
+		if (capable(CAP_DAC_READ_SEARCH))
+			return 0;
 	return -EACCES;
 }
 
diff -u --recursive --new-file v2.1.99/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- v2.1.99/linux/fs/smbfs/proc.c	Tue Mar 10 10:03:34 1998
+++ linux/fs/smbfs/proc.c	Wed May  6 10:56:05 1998
@@ -630,7 +630,8 @@
 		goto out;
 
 	error = -EACCES;
-	if (current->uid != server->mnt->mounted_uid && !suser())
+	if (current->uid != server->mnt->mounted_uid && 
+	    !capable(CAP_SYS_ADMIN))
 		goto out;
 
 	error = -EBADF;
diff -u --recursive --new-file v2.1.99/linux/fs/super.c linux/fs/super.c
--- v2.1.99/linux/fs/super.c	Mon Apr  6 17:41:01 1998
+++ linux/fs/super.c	Wed May  6 10:56:05 1998
@@ -743,7 +743,7 @@
 	struct dentry * dentry;
 	int retval;
 
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	lock_kernel();
@@ -985,7 +985,7 @@
 	struct file dummy;	/* allows read-write or read-only flag */
 
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		goto out;
 	if ((new_flags &
 	     (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
diff -u --recursive --new-file v2.1.99/linux/fs/sysv/namei.c linux/fs/sysv/namei.c
--- v2.1.99/linux/fs/sysv/namei.c	Thu Feb 12 20:56:12 1998
+++ linux/fs/sysv/namei.c	Wed May  6 10:56:06 1998
@@ -419,7 +419,7 @@
 
         if ((dir->i_mode & S_ISVTX) &&
             current->fsuid != inode->i_uid &&
-            current->fsuid != dir->i_uid && !fsuser())
+            current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rmdir;
 	if (inode->i_dev != dir->i_dev)
 		goto end_rmdir;
@@ -484,7 +484,7 @@
 	}
 	if ((dir->i_mode & S_ISVTX) &&
 	    current->fsuid != inode->i_uid &&
-	    current->fsuid != dir->i_uid && !fsuser())
+	    current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
 		goto end_unlink;
 	if (de->inode != inode->i_ino) {
 		retval = -ENOENT;
@@ -643,7 +643,7 @@
 	retval = -EPERM;
 	if ((old_dir->i_mode & S_ISVTX) && 
 	    current->fsuid != old_inode->i_uid &&
-	    current->fsuid != old_dir->i_uid && !fsuser())
+	    current->fsuid != old_dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rename;
 	new_inode = new_dentry->d_inode;
 	new_bh = sysv_find_entry(new_dir, new_dentry->d_name.name,
@@ -675,7 +675,7 @@
 	retval = -EPERM;
 	if (new_inode && (new_dir->i_mode & S_ISVTX) && 
 	    current->fsuid != new_inode->i_uid &&
-	    current->fsuid != new_dir->i_uid && !fsuser())
+	    current->fsuid != new_dir->i_uid && !capable(CAP_FOWNER))
 		goto end_rename;
 	if (S_ISDIR(old_inode->i_mode)) {
 		retval = -ENOTDIR;
diff -u --recursive --new-file v2.1.99/linux/fs/umsdos/namei.c linux/fs/umsdos/namei.c
--- v2.1.99/linux/fs/umsdos/namei.c	Wed Apr  8 19:36:28 1998
+++ linux/fs/umsdos/namei.c	Wed May  6 10:56:06 1998
@@ -350,14 +350,14 @@
     Printk (("ret %d ",ret));
     if (ret == 0){
       /* check sticky bit on old_dir */
-      if ( !(old_dir->i_mode & S_ISVTX) || fsuser() ||
+      if ( !(old_dir->i_mode & S_ISVTX) || capable(CAP_FOWNER) ||
 	   current->fsuid == old_info.entry.uid ||
 	   current->fsuid == old_dir->i_uid ) {
 	/* Does new_name already exist? */
 	PRINTK(("new findentry "));
 	ret = umsdos_findentry(new_dir,&new_info,0);
 	if (ret != 0 || /* if destination file exists, are we allowed to replace it ? */
-	    !(new_dir->i_mode & S_ISVTX) || fsuser() ||
+	    !(new_dir->i_mode & S_ISVTX) || capable(CAP_FOWNER) ||
 	    current->fsuid == new_info.entry.uid ||
 	    current->fsuid == new_dir->i_uid ) {
 	  PRINTK (("new newentry "));
@@ -933,7 +933,7 @@
         umsdos_real_lookup (dir, tdentry);	/* fill inode part */
 	Printk (("isempty %d i_count %d ",empty,sdir->i_count));
 				/* check sticky bit */
-	if ( !(dir->i_mode & S_ISVTX) || fsuser() ||
+	if ( !(dir->i_mode & S_ISVTX) || capable(CAP_FOWNER) ||
 	     current->fsuid == sdir->i_uid ||
 	     current->fsuid == dir->i_uid ) {
 	  if (empty == 1){
@@ -1024,7 +1024,7 @@
       if (ret == 0){
 	Printk (("UMSDOS_unlink %.*s ",info.fake.len,info.fake.fname));
 				/* check sticky bit */
-	if ( !(dir->i_mode & S_ISVTX) || fsuser() ||
+	if ( !(dir->i_mode & S_ISVTX) || capable(CAP_FOWNER) ||
 	     current->fsuid == info.entry.uid ||
 	     current->fsuid == dir->i_uid ) {
 	  if (info.entry.flags & UMSDOS_HLINK){
diff -u --recursive --new-file v2.1.99/linux/include/asm-alpha/ide.h linux/include/asm-alpha/ide.h
--- v2.1.99/linux/include/asm-alpha/ide.h	Thu Mar 27 14:40:06 1997
+++ linux/include/asm-alpha/ide.h	Wed May  6 14:42:54 1998
@@ -19,7 +19,7 @@
 #define MAX_HWIFS	4
 #endif
 
-#define ide_sti()	sti()
+#define ide__sti()	__sti()
 
 static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
diff -u --recursive --new-file v2.1.99/linux/include/asm-alpha/mmu_context.h linux/include/asm-alpha/mmu_context.h
--- v2.1.99/linux/include/asm-alpha/mmu_context.h	Wed Apr  1 20:11:53 1998
+++ linux/include/asm-alpha/mmu_context.h	Tue May  5 21:33:33 1998
@@ -109,8 +109,24 @@
 #endif
 }
 
-#define init_new_context(mm)	do { } while(0)
+extern inline void init_new_context(struct mm_struct *mm)
+{
+	mm->context = 0;
+}
+
 #define destroy_context(mm)	do { } while(0)
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ * Ideally this would be an extern inline function, but reload_context
+ * is declared in pgtable.h, which includes this file. :-(
+ */
+#define activate_context(tsk)		\
+	do {				\
+		get_mmu_context(tsk);	\
+		reload_context(tsk);	\
+	} while (0)
 
 #endif
 
diff -u --recursive --new-file v2.1.99/linux/include/asm-arm/ide.h linux/include/asm-arm/ide.h
--- v2.1.99/linux/include/asm-arm/ide.h	Tue Jan 20 16:39:42 1998
+++ linux/include/asm-arm/ide.h	Wed May  6 14:42:54 1998
@@ -19,7 +19,7 @@
 #define MAX_HWIFS	4
 #endif
 
-#define ide_sti()	sti()
+#define ide__sti()	__sti()
 
 #include <asm/arch/ide.h>
 
diff -u --recursive --new-file v2.1.99/linux/include/asm-arm/mmu_context.h linux/include/asm-arm/mmu_context.h
--- v2.1.99/linux/include/asm-arm/mmu_context.h	Tue Jan 20 16:39:42 1998
+++ linux/include/asm-arm/mmu_context.h	Tue May  5 21:33:34 1998
@@ -13,5 +13,6 @@
 
 #define init_new_context(mm)	do { } while(0)
 #define destroy_context(mm)	do { } while(0)
+#define activate_context(tsk)	do { } while(0)
 
 #endif
diff -u --recursive --new-file v2.1.99/linux/include/asm-i386/ide.h linux/include/asm-i386/ide.h
--- v2.1.99/linux/include/asm-i386/ide.h	Wed Apr  1 20:11:54 1998
+++ linux/include/asm-i386/ide.h	Wed May  6 14:42:54 1998
@@ -19,7 +19,7 @@
 #define MAX_HWIFS	6
 #endif
 
-#define ide_sti()	sti()
+#define ide__sti()	__sti()
 
 static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
diff -u --recursive --new-file v2.1.99/linux/include/asm-i386/mmu_context.h linux/include/asm-i386/mmu_context.h
--- v2.1.99/linux/include/asm-i386/mmu_context.h	Mon Dec 30 03:03:12 1996
+++ linux/include/asm-i386/mmu_context.h	Tue May  5 21:33:33 1998
@@ -8,5 +8,6 @@
 
 #define init_new_context(mm)	do { } while(0)
 #define destroy_context(mm)	do { } while(0)
+#define activate_context(tsk)	do { } while(0)
 
 #endif
diff -u --recursive --new-file v2.1.99/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h
--- v2.1.99/linux/include/asm-i386/spinlock.h	Mon Jan 12 16:43:09 1998
+++ linux/include/asm-i386/spinlock.h	Wed May  6 14:42:54 1998
@@ -3,6 +3,10 @@
 
 #ifndef __SMP__
 
+#define DEBUG_SPINLOCKS	0	/* 0 == no debugging, 1 == maintain lock state, 2 == full debug */
+
+#if (DEBUG_SPINLOCKS < 1)
+
 /*
  * Your basic spinlocks, allowing only a single CPU anywhere
  */
@@ -11,7 +15,7 @@
 
 #define spin_lock_init(lock)	do { } while(0)
 #define spin_lock(lock)		do { } while(0)
-#define spin_trylock(lock)	do { } while(0)
+#define spin_trylock(lock)	(1)
 #define spin_unlock_wait(lock)	do { } while(0)
 #define spin_unlock(lock)	do { } while(0)
 #define spin_lock_irq(lock)	cli()
@@ -22,6 +26,52 @@
 #define spin_unlock_irqrestore(lock, flags) \
 	restore_flags(flags)
 
+#elif (DEBUG_SPINLOCKS < 2)
+
+typedef struct {
+	volatile unsigned int lock;
+} spinlock_t;
+#define SPIN_LOCK_UNLOCKED { 0 }
+
+#define spin_lock_init(x)	do { (x)->lock = 0; } while (0)
+#define spin_trylock(lock)	(!test_and_set_bit(0,(lock)))
+
+#define spin_lock(x)		do { (x)->lock = 1; } while (0)
+#define spin_unlock_wait(x)	do { } while (0)
+#define spin_unlock(x)		do { (x)->lock = 0; } while (0)
+#define spin_lock_irq(x)	do { cli(); spin_lock(x); } while (0)
+#define spin_unlock_irq(x)	do { spin_unlock(x); sti(); } while (0)
+
+#define spin_lock_irqsave(x, flags) \
+	do { save_flags(flags); spin_lock_irq(x); } while (0)
+#define spin_unlock_irqrestore(x, flags) \
+	do { spin_unlock(x); restore_flags(flags); } while (0)
+
+#else /* (DEBUG_SPINLOCKS >= 2) */
+
+typedef struct {
+	volatile unsigned int lock;
+	volatile unsigned int babble;
+	const char *module;
+} spinlock_t;
+#define SPIN_LOCK_UNLOCKED { 0, 25, __BASE_FILE__ }
+
+#include <linux/kernel.h>
+
+#define spin_lock_init(x)	do { (x)->lock = 0; } while (0)
+#define spin_trylock(lock)	(!test_and_set_bit(0,(lock)))
+
+#define spin_lock(x)		do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s: spin_lock(%s:%p) already locked\n", __BASE_FILE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1; restore_flags(__spinflags);} while (0)
+#define spin_unlock_wait(x)	do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s: spin_unlock_wait(%s:%p) deadlock\n", __BASE_FILE__, (x)->module, (x));(x)->babble--;} restore_flags(__spinflags);} while (0)
+#define spin_unlock(x)		do {unsigned long __spinflags; save_flags(__spinflags); cli(); if (!(x)->lock&&(x)->babble) {printk("%s: spin_unlock(%s:%p) not locked\n", __BASE_FILE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; restore_flags(__spinflags);} while (0)
+#define spin_lock_irq(x)	do {cli(); if ((x)->lock&&(x)->babble) {printk("%s: spin_lock_irq(%s:%p) already locked\n", __BASE_FILE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1;} while (0)
+#define spin_unlock_irq(x)	do {cli(); if ((x)->lock&&(x)->babble) {printk("%s: spin_lock(%s:%p) already locked\n", __BASE_FILE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1; sti();} while (0)
+
+#define spin_lock_irqsave(x,flags)      do {save_flags(flags); cli(); if ((x)->lock&&(x)->babble) {printk("%s: spin_lock_irqsave(%s:%p) already locked\n", __BASE_FILE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1;} while (0)
+#define spin_unlock_irqrestore(x,flags) do {cli(); if (!(x)->lock&&(x)->babble) {printk("%s: spin_unlock_irqrestore(%s:%p) not locked\n", __BASE_FILE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; restore_flags(flags);} while (0)
+
+#endif	/* DEBUG_SPINLOCKS */
+
 /*
  * Read-write spinlocks, allowing multiple readers
  * but only one writer.
@@ -53,13 +103,10 @@
 #define write_unlock_irqrestore(lock, flags) \
 	restore_flags(flags)
 
-#else
+#else	/* __SMP__ */
 
 /*
- * Simple spin lock operations.  There are two variants, one clears IRQ's
- * on the local processor, one does not.
- *
- * We make no fairness assumptions. They have a cost.
+ * Your basic spinlocks, allowing only a single CPU anywhere
  */
 
 typedef struct {
@@ -69,6 +116,13 @@
 #define SPIN_LOCK_UNLOCKED { 0 }
 
 #define spin_lock_init(x)	do { (x)->lock = 0; } while(0)
+/*
+ * Simple spin lock operations.  There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions. They have a cost.
+ */
+
 #define spin_unlock_wait(x)	do { barrier(); } while(((volatile spinlock_t *)(x))->lock)
 
 typedef struct { unsigned long a[100]; } __dummy_lock_t;
@@ -176,5 +230,5 @@
 #define write_unlock_irqrestore(lock, flags) \
 	do { write_unlock(lock); __restore_flags(flags); } while (0)
 
-#endif /* SMP */
+#endif /* __SMP__ */
 #endif /* __ASM_SPINLOCK_H */
diff -u --recursive --new-file v2.1.99/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.1.99/linux/include/asm-i386/unistd.h	Wed Apr  8 19:36:29 1998
+++ linux/include/asm-i386/unistd.h	Wed May  6 11:01:45 1998
@@ -189,6 +189,8 @@
 #define __NR_pwrite		181
 #define __NR_chown		182
 #define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
diff -u --recursive --new-file v2.1.99/linux/include/asm-m68k/ide.h linux/include/asm-m68k/ide.h
--- v2.1.99/linux/include/asm-m68k/ide.h	Thu Mar 26 15:57:05 1998
+++ linux/include/asm-m68k/ide.h	Wed May  6 14:42:54 1998
@@ -424,17 +424,17 @@
  * works. (Roman)
  */
 #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA)
-#define	ide_sti()					\
+#define	ide__sti()					\
     do {						\
-	if (!in_interrupt()) sti();			\
+	if (!in_interrupt()) __sti();			\
     } while(0)
 #elif defined(CONFIG_ATARI)
-#define	ide_sti()						\
+#define	ide__sti()						\
     do {							\
 	if (!MACH_IS_ATARI || !in_interrupt()) sti();		\
     } while(0)
 #else /* !defined(CONFIG_ATARI) */
-#define	ide_sti()	sti()
+#define	ide__sti()	__sti()
 #endif
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.1.99/linux/include/asm-m68k/mmu_context.h linux/include/asm-m68k/mmu_context.h
--- v2.1.99/linux/include/asm-m68k/mmu_context.h	Mon Dec 30 03:03:13 1996
+++ linux/include/asm-m68k/mmu_context.h	Tue May  5 21:33:34 1998
@@ -8,5 +8,6 @@
 
 #define init_new_context(mm)	do { } while(0)
 #define destroy_context(mm)	do { } while(0)
+#define activate_context(tsk)	do { } while(0)
 
 #endif
diff -u --recursive --new-file v2.1.99/linux/include/asm-mips/ide.h linux/include/asm-mips/ide.h
--- v2.1.99/linux/include/asm-mips/ide.h	Thu Jun 26 12:33:39 1997
+++ linux/include/asm-mips/ide.h	Wed May  6 14:42:54 1998
@@ -19,7 +19,7 @@
 #define MAX_HWIFS	4
 #endif
 
-#define ide_sti()	sti()
+#define ide__sti()	__sti()
 
 static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
diff -u --recursive --new-file v2.1.99/linux/include/asm-mips/mmu_context.h linux/include/asm-mips/mmu_context.h
--- v2.1.99/linux/include/asm-mips/mmu_context.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/mmu_context.h	Tue May  5 21:33:33 1998
@@ -62,4 +62,14 @@
 	mm->context = 0;
 }
 
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+extern inline activate_context(struct task_struct *tsk)
+{
+	get_mmu_context(tsk);
+	/* XXX here we presumably need to set some cpu register - paulus. */
+}
+
 #endif /* __ASM_MIPS_MMU_CONTEXT_H */
diff -u --recursive --new-file v2.1.99/linux/include/asm-ppc/ide.h linux/include/asm-ppc/ide.h
--- v2.1.99/linux/include/asm-ppc/ide.h	Thu Apr 23 20:21:37 1998
+++ linux/include/asm-ppc/ide.h	Wed May  6 14:42:54 1998
@@ -26,7 +26,7 @@
 #define SUPPORT_VLB_SYNC	0
 
 
-#define ide_sti()	sti()
+#define ide__sti()	__sti()
 
 typedef unsigned int ide_ioreg_t;
 void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq);
diff -u --recursive --new-file v2.1.99/linux/include/asm-ppc/mmu_context.h linux/include/asm-ppc/mmu_context.h
--- v2.1.99/linux/include/asm-ppc/mmu_context.h	Sat Apr 25 18:13:12 1998
+++ linux/include/asm-ppc/mmu_context.h	Tue May  5 21:33:34 1998
@@ -22,9 +22,20 @@
 #ifdef CONFIG_8xx
 #define NO_CONTEXT      16
 #define LAST_CONTEXT    15
+#define MUNGE_CONTEXT(n)        (n)
+
 #else
+
+/* PPC 6xx, 7xx CPUs */
 #define NO_CONTEXT      0
 #define LAST_CONTEXT    0xfffff
+
+/*
+ * Allocating context numbers this way tends to spread out
+ * the entries in the hash table better than a simple linear
+ * allocation.
+ */
+#define MUNGE_CONTEXT(n)        (((n) * 897) & LAST_CONTEXT)
 #endif
 
 extern int next_mmu_context;
@@ -36,17 +47,6 @@
 #define set_context(context)    do { } while (0)
 #endif
 
-#ifndef CONFIG_8xx
-/*
- * Allocating context numbers this way tends to spread out
- * the entries in the hash table better than a simple linear
- * allocation.
- */
-#define MUNGE_CONTEXT(n)        (((n) * 897) & LAST_CONTEXT)
-#else
-#define MUNGE_CONTEXT(n)        (n)
-#endif
-
 /*
  * Get a new mmu context for task tsk if necessary.
  */
@@ -57,8 +57,6 @@
 		if (next_mmu_context == LAST_CONTEXT)		\
 			mmu_context_overflow();			\
 		mm->context = MUNGE_CONTEXT(++next_mmu_context);\
-	 	if ( tsk == current )                           \
-			set_context(mm->context);               \
 	}							\
 } while (0)
 
@@ -70,11 +68,17 @@
 /*
  * We're finished using the context for an address space.
  */
-#ifdef CONFIG_8xx
 #define destroy_context(mm)     ((mm)->context = NO_CONTEXT)
-#else
-#define destroy_context(mm)     do { } while (0)
-#endif
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+extern inline void activate_context(struct task_struct *tsk)
+{
+	get_mmu_context(tsk);
+	set_context(tsk->mm->context);
+}
 
 /*
  * compute the vsid from the context and segment
diff -u --recursive --new-file v2.1.99/linux/include/asm-sparc/mmu_context.h linux/include/asm-sparc/mmu_context.h
--- v2.1.99/linux/include/asm-sparc/mmu_context.h	Thu Apr 23 20:21:38 1998
+++ linux/include/asm-sparc/mmu_context.h	Tue May  5 21:33:34 1998
@@ -22,4 +22,11 @@
 
 #define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm)
 
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ * XXX this presumably needs a sensible implementation - paulus.
+ */
+#define activate_context(tsk)	do { } while(0)
+
 #endif /* !(__SPARC_MMU_CONTEXT_H) */
diff -u --recursive --new-file v2.1.99/linux/include/asm-sparc64/ide.h linux/include/asm-sparc64/ide.h
--- v2.1.99/linux/include/asm-sparc64/ide.h	Thu Apr 23 20:21:38 1998
+++ linux/include/asm-sparc64/ide.h	Wed May  6 14:42:54 1998
@@ -15,7 +15,7 @@
 #undef  MAX_HWIFS
 #define MAX_HWIFS	2
 
-#define	ide_sti()	sti()
+#define	ide__sti()	__sti()
 
 static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
@@ -38,7 +38,7 @@
 	for ( ; i < 10; i++)
 		*p++ = 0;
 	/* PCI code needs to figure out this. */
-	if(irq != NULL)
+	if (irq != NULL)
 		*irq = 0;
 }
 
diff -u --recursive --new-file v2.1.99/linux/include/asm-sparc64/mmu_context.h linux/include/asm-sparc64/mmu_context.h
--- v2.1.99/linux/include/asm-sparc64/mmu_context.h	Mon Jan 12 15:15:58 1998
+++ linux/include/asm-sparc64/mmu_context.h	Tue May  5 21:33:34 1998
@@ -72,6 +72,12 @@
 	  : "o4");
 }
 
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+#define activate_context(tsk)	get_mmu_context(tsk)
+
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(__SPARC64_MMU_CONTEXT_H) */
diff -u --recursive --new-file v2.1.99/linux/include/linux/blk.h linux/include/linux/blk.h
--- v2.1.99/linux/include/linux/blk.h	Wed Apr  1 20:11:54 1998
+++ linux/include/linux/blk.h	Thu May  7 18:14:38 1998
@@ -95,7 +95,7 @@
 #endif
 
 #define RO_IOCTLS(dev,where) \
-  case BLKROSET: { int __val;  if (!suser()) return -EACCES; \
+  case BLKROSET: { int __val;  if (!capable(CAP_SYS_ADMIN)) return -EACCES; \
 		   if (get_user(__val, (int *)(where))) return -EFAULT; \
 		   set_device_ro((dev),__val); return 0; } \
   case BLKROGET: { int __val = (is_read_only(dev) != 0) ; \
@@ -411,14 +411,20 @@
 
 #ifdef IDE_DRIVER
 void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup) {
-	struct request *req = hwgroup->rq;
+	int nsect;
+	struct buffer_head *bh;
+	struct request *req;
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_request_lock,flags);
+	req = hwgroup->rq;
 #else
 static void end_request(int uptodate) {
-	struct request *req = CURRENT;
-#endif /* IDE_DRIVER */
-	struct buffer_head * bh;
 	int nsect;
+	struct buffer_head *bh;
+	struct request *req = CURRENT;
 
+#endif /* IDE_DRIVER */
 	req->errors = 0;
 	if (!uptodate) {
 		printk("end_request: I/O error, dev %s, sector %lu\n",
@@ -443,6 +449,9 @@
 				printk("end_request: buffer-list destroyed\n");
 			}
 			req->buffer = bh->b_data;
+#ifdef IDE_DRIVER
+			spin_unlock_irqrestore(&io_request_lock,flags);
+#endif /* IDE_DRIVER */
 			return;
 		}
 	}
@@ -461,6 +470,9 @@
 		up(req->sem);
 	req->rq_status = RQ_INACTIVE;
 	wake_up(&wait_for_request);
+#ifdef IDE_DRIVER
+	spin_unlock_irqrestore(&io_request_lock,flags);
+#endif /* IDE_DRIVER */
 }
 #endif /* defined(IDE_DRIVER) && !defined(_IDE_C) */
 #endif /* ! SCSI_BLK_MAJOR(MAJOR_NR) */
diff -u --recursive --new-file v2.1.99/linux/include/linux/capability.h linux/include/linux/capability.h
--- v2.1.99/linux/include/linux/capability.h	Sat Apr 25 18:13:12 1998
+++ linux/include/linux/capability.h	Thu May  7 18:14:25 1998
@@ -17,19 +17,33 @@
    kernel might be somewhat backwards compatible, but don't bet on
    it. */
 
+/* XXX - Note, cap_t, is defined by POSIX to be an "opaque" pointer to
+   a set of three capability sets.  The transposition of 3*the
+   following structure to such a composite is better handled in a user
+   library since the draft standard requires the use of malloc/free
+   etc.. */
+ 
 #define _LINUX_CAPABILITY_VERSION  0x19980330
 
-typedef struct _user_cap_struct {
+typedef struct __user_cap_header_struct {
 	__u32 version;
-	__u32 size;
-	__u8  cap[1];
-} *cap_t;
-
+	int pid;
+} *cap_user_header_t;
+ 
+typedef struct __user_cap_data_struct {
+        __u32 effective;
+        __u32 permitted;
+        __u32 inheritable;
+} *cap_user_data_t;
+  
 #ifdef __KERNEL__
 
 typedef struct kernel_cap_struct {
-	int cap;
+	__u32 cap;
 } kernel_cap_t;
+  
+#define _USER_CAP_HEADER_SIZE  (2*sizeof(__u32))
+#define _KERNEL_CAP_T_SIZE     (sizeof(kernel_cap_t))
 
 #endif
 
@@ -46,13 +60,13 @@
 
 /* Override all DAC access, including ACL execute access if
    [_POSIX_ACL] is defined. Excluding DAC access covered by
-   CAP_LINUX_IMMUTABLE */
+   CAP_LINUX_IMMUTABLE. */
 
 #define CAP_DAC_OVERRIDE     1
 
 /* Overrides all DAC restrictions regarding read and search on files
    and directories, including ACL restrictions if [_POSIX_ACL] is
-   defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE */
+   defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
 
 #define CAP_DAC_READ_SEARCH  2
     
@@ -82,10 +96,13 @@
 #define CAP_KILL             5
 
 /* Allows setgid(2) manipulation */
+/* Allows setgroups(2) */
+/* Allows forged gids on socket credentials passing. */
 
 #define CAP_SETGID           6
 
-/* Allows setuid(2) manipulation */
+/* Allows set*uid(2) manipulation (including fsuid). */
+/* Allows forged pids on socket credentials passing. */
 
 #define CAP_SETUID           7
 
@@ -112,9 +129,17 @@
 #define CAP_NET_BROADCAST    11
 
 /* Allow interface configuration */
-/* Allow configuring of firewall stuff */
+/* Allow administration of IP firewall, masquerading and accounting */
 /* Allow setting debug option on sockets */
 /* Allow modification of routing tables */
+/* Allow setting arbitrary process / process group ownership on
+   sockets */
+/* Allow binding to any address for transparent proxying */
+/* Allow setting TOS (type of service) */
+/* Allow setting promiscuous mode */
+/* Allow clearing driver statistics */
+/* Allow multicasting */
+/* Allow read/write of device-specific registers */
 
 #define CAP_NET_ADMIN        12
 
@@ -123,7 +148,9 @@
 
 #define CAP_NET_RAW          13
 
-/* Allow locking of segments in memory */
+/* Allow locking of shared memory segments */
+/* Allow mlock and mlockall (which doesn't really have anything to do
+   with IPC) */
 
 #define CAP_IPC_LOCK         14
 
@@ -153,9 +180,42 @@
 
 /* Allow configuration of the secure attention key */
 /* Allow administration of the random device */
-/* Allow device administration */
+/* Allow device administration (mknod)*/
 /* Allow examination and configuration of disk quotas */
-/* System Admin functions: mount et al */
+/* Allow configuring the kernel's syslog (printk behaviour) */
+/* Allow sending a signal to any process */
+/* Allow setting the domainname */
+/* Allow setting the hostname */
+/* Allow calling bdflush() */
+/* Allow mount() and umount(), setting up new smb connection */
+/* Allow some autofs root ioctls */
+/* Allow nfsservctl */
+/* Allow VM86_REQUEST_IRQ */
+/* Allow to read/write pci config on alpha */
+/* Allow irix_prctl on mips (setstacksize) */
+/* Allow flushing all cache on m68k (sys_cacheflush) */
+/* Allow removing semaphores */
+/* Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
+   and shared memory */
+/* Allow locking/unlocking of shared memory segment */
+/* Allow turning swap on/off */
+/* Allow forged pids on socket credentials passing */
+/* Allow setting readahead and flushing buffers on block devices */
+/* Allow setting geometry in floppy driver */
+/* Allow turning DMA on/off in xd driver */
+/* Allow administration of md devices (mostly the above, but some
+   extra ioctls) */
+/* Allow tuning the ide driver */
+/* Allow access to the nvram device */
+/* Allow administration of apm_bios, serial and bttv (TV) device */
+/* Allow manufacturer commands in isdn CAPI support driver */
+/* Allow reading non-standardized portions of pci configuration space */
+/* Allow DDI debug ioctl on sbpcd driver */
+/* Allow setting up serial ports */
+/* Allow sending raw qic-117 commands */
+/* Allow enabling/disabling tagged queuing on SCSI controllers and sending
+   arbitrary SCSI commands */
+/* Allow setting encryption key on loopback filesystem */
 
 #define CAP_SYS_ADMIN        21
 
@@ -163,19 +223,34 @@
 
 #define CAP_SYS_BOOT         22
 
-/* Allow use of renice() on others, and raising of priority */
+/* Allow raising priority and setting priority on other (different
+   UID) processes */
+/* Allow use of FIFO and round-robin (realtime) scheduling on own
+   processes and setting the scheduling algorithm used by another
+   process. */
 
 #define CAP_SYS_NICE         23
 
-/* Override resource limits */
+/* Override resource limits. Set resource limits. */
+/* Override quota limits. */
+/* Override reserved space on ext2 filesystem */
+/* NOTE: ext2 honors fsuid when checking for resource overrides, so 
+   you can override using fsuid too */
+/* Override size restrictions on IPC message queues */
+/* Allow more than 64hz interrupts from the real-time clock */
+/* Override max number of consoles on console allocation */
+/* Override max number of keymaps */
 
 #define CAP_SYS_RESOURCE     24
 
 /* Allow manipulation of system clock */
+/* Allow irix_stime on mips */
+/* Allow setting the real-time clock */
 
 #define CAP_SYS_TIME         25
 
 /* Allow configuration of tty devices */
+/* Allow vhangup() of tty */
 
 #define CAP_SYS_TTY_CONFIG   26
 
@@ -187,17 +262,48 @@
 
 #define CAP_EMPTY_SET       {  0 }
 #define CAP_FULL_SET        { ~0 }
+#define CAP_INIT_EFF_SET    { ~0 & ~CAP_TO_MASK(CAP_SETPCAP) }
+#define CAP_INIT_INH_SET    { ~0 & ~CAP_TO_MASK(CAP_SETPCAP) }
 
 #define CAP_TO_MASK(x) (1 << (x))
-#define cap_raise(c, flag)   (c.cap |=  CAP_TO_MASK(flag))
-#define cap_lower(c, flag)   (c.cap &= ~CAP_TO_MASK(flag))
-#define cap_raised(c, flag)  (c.cap &   CAP_TO_MASK(flag))
-
-#define cap_isclear(c) (!c.cap)
-
-#define cap_copy(dest,src) do { (dest).cap = (src).cap; } while(0)
-#define cap_clear(c)       do {  c.cap =  0; } while(0)
-#define cap_set_full(c)    do {  c.cap = ~0; } while(0)
+#define cap_raise(c, flag)   ((c).cap |=  CAP_TO_MASK(flag))
+#define cap_lower(c, flag)   ((c).cap &= ~CAP_TO_MASK(flag))
+#define cap_raised(c, flag)  ((c).cap &   CAP_TO_MASK(flag))
+
+static inline kernel_cap_t cap_combine(kernel_cap_t a, kernel_cap_t b)
+{
+     kernel_cap_t dest;
+     dest.cap = a.cap | b.cap;
+     return dest;
+}
+
+static inline kernel_cap_t cap_intersect(kernel_cap_t a, kernel_cap_t b)
+{
+     kernel_cap_t dest;
+     dest.cap = a.cap & b.cap;
+     return dest;
+}
+
+static inline kernel_cap_t cap_drop(kernel_cap_t a, kernel_cap_t drop)
+{
+     kernel_cap_t dest;
+     dest.cap = a.cap & ~drop.cap;
+     return dest;
+}
+
+static inline kernel_cap_t cap_invert(kernel_cap_t c)
+{
+     kernel_cap_t dest;
+     dest.cap = ~c.cap;
+     return dest;
+}
+
+#define cap_isclear(c)       (!(c).cap)
+#define cap_issubset(a,set)  (!((a).cap & ~(set).cap))
+
+#define cap_clear(c)         do { (c).cap =  0; } while(0)
+#define cap_set_full(c)      do { (c).cap = ~0; } while(0)
+#define cap_mask(c,mask)     do { (c).cap &= (mask).cap; } while(0)
 
 #define cap_is_fs_cap(c)     ((c) & CAP_FS_MASK)
 
diff -u --recursive --new-file v2.1.99/linux/include/linux/coda_proc.h linux/include/linux/coda_proc.h
--- v2.1.99/linux/include/linux/coda_proc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/coda_proc.h	Mon May  4 17:09:22 1998
@@ -0,0 +1,144 @@
+/*
+ * coda_statis.h
+ * 
+ * CODA operation statistics
+ *
+ * (c) March, 1998
+ * by Michihiro Kuramochi, Zhenyu Xia and Zhanyong Wan
+ * zhanyong.wan@yale.edu
+ *
+ */
+
+#ifndef _CODA_PROC_H
+#define _CODA_PROC_H
+
+void coda_sysctl_init(void);
+void coda_sysctl_clean(void);
+void coda_upcall_stats(int opcode, unsigned long jiffies);
+
+#include <linux/sysctl.h>
+#include <linux/coda_fs_i.h>
+#include <linux/coda.h>
+
+/* these four files are presented to show the result of the statistics:
+ *
+ *	/proc/fs/coda/vfs_stats
+ *		      upcall_stats
+ *		      permission_stats
+ *		      cache_inv_stats
+ *
+ * these four files are presented to reset the statistics to 0:
+ *
+ *	/proc/sys/coda/vfs_stats
+ *		       upcall_stats
+ *		       permission_stats
+ *		       cache_inv_stats
+ */
+
+/* VFS operation statistics */
+struct coda_vfs_stats 
+{
+	/* file operations */
+	int file_read;
+	int file_write;
+	int file_mmap;
+	int open;
+	int release;
+	int fsync;
+
+	/* dir operations */
+	int readdir;
+  
+	/* inode operations */
+	int create;
+	int lookup;
+	int link;
+	int unlink;
+	int symlink;
+	int mkdir;
+	int rmdir;
+	int rename;
+	int permission;
+	int readpage;
+
+	/* symlink operatoins*/
+	int follow_link;
+	int readlink;
+};
+
+struct coda_upcall_stats_entry 
+{
+  int count;
+  unsigned long time_sum;
+  unsigned long time_squared_sum;
+};
+
+
+
+/* cache hits for permissions statistics */
+struct coda_permission_stats 
+{
+	int count;
+	int hit_count;
+};
+
+/* cache invalidation statistics */
+struct coda_cache_inv_stats
+{
+	int flush;
+	int purge_user;
+	int zap_dir;
+	int zap_file;
+	int zap_vnode;
+	int purge_fid;
+	int replace;
+};
+
+/* these global variables hold the actual statistics data */
+extern struct coda_vfs_stats		coda_vfs_stat;
+extern struct coda_permission_stats	coda_permission_stat;
+extern struct coda_cache_inv_stats	coda_cache_inv_stat;
+
+/* reset statistics to 0 */
+void reset_coda_vfs_stats( void );
+void reset_coda_upcall_stats( void );
+void reset_coda_permission_stats( void );
+void reset_coda_cache_inv_stats( void );
+
+/* some utitlities to make it easier for you to do statistics for time */
+void do_time_stats( struct coda_upcall_stats_entry * pentry, 
+		    unsigned long jiffy );
+/*
+double get_time_average( const struct coda_upcall_stats_entry * pentry );
+double get_time_std_deviation( const struct coda_upcall_stats_entry * pentry );
+*/
+unsigned long get_time_average( const struct coda_upcall_stats_entry * pentry );
+unsigned long get_time_std_deviation( const struct coda_upcall_stats_entry * pentry );
+
+/* like coda_dointvec, these functions are to be registered in the ctl_table
+ * data structure for /proc/sys/... files 
+ */
+int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
+			     void * buffer, size_t * lenp );
+int do_reset_coda_upcall_stats( ctl_table * table, int write, 
+				struct file * filp, void * buffer, 
+				size_t * lenp );
+int do_reset_coda_permission_stats( ctl_table * table, int write, 
+				    struct file * filp, void * buffer, 
+				    size_t * lenp );
+int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
+				   struct file * filp, void * buffer, 
+				   size_t * lenp );
+
+/* these functions are called to form the content of /proc/fs/coda/... files */
+int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
+			     int length, int dummy );
+int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
+				int length, int dummy );
+int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
+				    int length, int dummy );
+int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
+				   int length, int dummy );
+
+
+#endif /* _CODA_PROC_H */
diff -u --recursive --new-file v2.1.99/linux/include/linux/coda_psdev.h linux/include/linux/coda_psdev.h
--- v2.1.99/linux/include/linux/coda_psdev.h	Mon Feb 23 18:12:11 1998
+++ linux/include/linux/coda_psdev.h	Mon May  4 17:09:22 1998
@@ -94,8 +94,6 @@
 int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
 		 unsigned int cmd, struct PioctlData *data);
 int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb);
-int coda_upcall(struct coda_sb_info *mntinfo, int inSize, 
-		int *outSize, union inputArgs *buffer);
 int venus_fsync(struct super_block *sb, struct ViceFid *fid);
 
 
diff -u --recursive --new-file v2.1.99/linux/include/linux/coda_sysctl.h linux/include/linux/coda_sysctl.h
--- v2.1.99/linux/include/linux/coda_sysctl.h	Sun Dec  7 11:51:01 1997
+++ linux/include/linux/coda_sysctl.h	Wed Dec 31 16:00:00 1969
@@ -1,10 +0,0 @@
-/*
- * Sysctl operations for Coda.
- * Original version: (C) 1996 Peter Braam 
- * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University
- *
- * Carnegie Mellon encourages users of this code to contribute improvements
- * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
- */
-void coda_sysctl_init(void);
-void coda_sysctl_clean(void);
diff -u --recursive --new-file v2.1.99/linux/include/linux/dcache.h linux/include/linux/dcache.h
--- v2.1.99/linux/include/linux/dcache.h	Wed Jan 14 16:57:09 1998
+++ linux/include/linux/dcache.h	Sat May  2 17:42:39 1998
@@ -131,7 +131,7 @@
 
 /* dcache memory management */
 extern int  select_dcache(int, int);
-extern void shrink_dcache_memory(void);
+extern void shrink_dcache_memory(int, unsigned int);
 extern void check_dcache_memory(void);
 extern void free_inode_memory(int);	/* defined in fs/inode.c */
 
diff -u --recursive --new-file v2.1.99/linux/include/linux/hdreg.h linux/include/linux/hdreg.h
--- v2.1.99/linux/include/linux/hdreg.h	Fri Feb  6 15:32:54 1998
+++ linux/include/linux/hdreg.h	Thu May  7 18:14:25 1998
@@ -45,7 +45,7 @@
 #define WIN_VERIFY		0x40
 #define WIN_FORMAT		0x50
 #define WIN_INIT		0x60
-#define WIN_SEEK 		0x70
+#define WIN_SEEK		0x70
 #define WIN_DIAGNOSE		0x90
 #define WIN_SPECIFY		0x91	/* set drive geometry translation */
 #define WIN_SETIDLE1		0xE3
@@ -101,12 +101,13 @@
 #define HDIO_GETGEO		0x0301	/* get device geometry */
 #define HDIO_GET_UNMASKINTR	0x0302	/* get current unmask setting */
 #define HDIO_GET_MULTCOUNT	0x0304	/* get current IDE blockmode setting */
-#define HDIO_GET_IDENTITY 	0x0307	/* get IDE identification info */
-#define HDIO_GET_KEEPSETTINGS 	0x0308	/* get keep-settings-on-reset flag */
-#define HDIO_GET_32BIT 		0x0309	/* get current io_32bit setting */
+#define HDIO_OBSOLETE_IDENTITY	0x0307	/* OBSOLETE, DO NOT USE: returns 142 bytes */
+#define HDIO_GET_KEEPSETTINGS	0x0308	/* get keep-settings-on-reset flag */
+#define HDIO_GET_32BIT		0x0309	/* get current io_32bit setting */
 #define HDIO_GET_NOWERR		0x030a	/* get ignore-write-error flag */
 #define HDIO_GET_DMA		0x030b	/* get use-dma flag */
 #define HDIO_GET_NICE		0x030c	/* get nice flags */
+#define HDIO_GET_IDENTITY	0x030d	/* get IDE identification info */
 #define HDIO_DRIVE_CMD		0x031f	/* execute a special drive command */
 
 /* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
diff -u --recursive --new-file v2.1.99/linux/include/linux/icmpv6.h linux/include/linux/icmpv6.h
--- v2.1.99/linux/include/linux/icmpv6.h	Fri Feb  6 15:33:34 1998
+++ linux/include/linux/icmpv6.h	Thu May  7 18:15:10 1998
@@ -138,9 +138,12 @@
 						    __u32 info, 
 						    struct device *dev);
 
-extern void				icmpv6_init(struct net_proto_family *ops);
+extern int				icmpv6_init(struct net_proto_family *ops);
 extern int				icmpv6_err_convert(int type, int code,
 							   int *err);
+extern void				icmpv6_cleanup(void);
+extern void				icmpv6_param_prob(struct sk_buff *skb,
+							  int code, void *pos);
 #endif
 
 #endif
diff -u --recursive --new-file v2.1.99/linux/include/linux/ipv6.h linux/include/linux/ipv6.h
--- v2.1.99/linux/include/linux/ipv6.h	Fri Feb  6 15:33:34 1998
+++ linux/include/linux/ipv6.h	Thu May  7 18:15:10 1998
@@ -42,6 +42,24 @@
 	 */
 };
 
+
+struct ipv6_opt_hdr {
+	__u8 		nexthdr;
+	__u8 		hdrlen;
+	/* 
+	 * TLV encoded option data follows.
+	 */
+};
+
+#define ipv6_destopt_hdr ipv6_opt_hdr
+#define ipv6_hopopt_hdr  ipv6_opt_hdr
+
+#ifdef __KERNEL__
+#define ipv6_optlen(p)  (((p)->hdrlen+1) << 3)
+#endif
+
+
+
 /*
  *	routing header type 0 (used in cmsghdr struct)
  */
@@ -95,12 +113,12 @@
 
 	/* 
 	 * protocol options 
-	 * usualy carried in IPv6 extension headers
+	 * usually carried in IPv6 extension headers
 	 */
 
 	struct ipv6_rt_hdr		*srcrt;	/* Routing Header */
-
 };
+
 
 #endif
 
diff -u --recursive --new-file v2.1.99/linux/include/linux/lp.h linux/include/linux/lp.h
--- v2.1.99/linux/include/linux/lp.h	Thu Feb 12 20:56:13 1998
+++ linux/include/linux/lp.h	Thu May  7 14:56:58 1998
@@ -20,11 +20,14 @@
 #define LP_EXIST 0x0001
 #define LP_SELEC 0x0002
 #define LP_BUSY	 0x0004
+#define LP_BUSY_BIT_POS 2
 #define LP_OFFL	 0x0008
 #define LP_NOPA  0x0010
 #define LP_ERR   0x0020
 #define LP_ABORT 0x0040
+#ifdef LP_NEED_CAREFUL
 #define LP_CAREFUL 0x0080
+#endif
 #define LP_ABORTOPEN 0x0100
 
 /* timeout for each character.  This is relative to bus cycles -- it
@@ -67,14 +70,18 @@
 			    or 0 for polling (no IRQ) */
 #define LPGETIRQ 0x0606  /* get the current IRQ number */
 #define LPWAIT   0x0608  /* corresponds to LP_INIT_WAIT */
+#ifdef LP_NEED_CAREFUL
 #define LPCAREFUL   0x0609  /* call with TRUE arg to require out-of-paper, off-
 			    line, and error indicators good on all writes,
 			    FALSE to ignore them.  Default is ignore. */
+#endif
 #define LPABORTOPEN 0x060a  /* call with TRUE arg to abort open() on error,
 			    FALSE to ignore error.  Default is ignore.  */
 #define LPGETSTATUS 0x060b  /* return LP_S(minor) */
 #define LPRESET     0x060c  /* reset printer */
+#ifdef LP_STATS
 #define LPGETSTATS  0x060d  /* get statistics (struct lp_stats) */
+#endif
 #define LPGETFLAGS  0x060e  /* get status flags */
 
 /* timeout for printk'ing a timeout, in jiffies (100ths of a second).
@@ -90,11 +97,14 @@
 #define LP_WAIT(minor)	lp_table[(minor)].wait		/* strobe wait */
 #define LP_IRQ(minor)	lp_table[(minor)].dev->port->irq /* interrupt # */
 							/* 0 means polled */
+#ifdef LP_STATS
 #define LP_STAT(minor)	lp_table[(minor)].stats		/* statistics area */
+#endif
 #define LP_BUFFER_SIZE 256
 
 #define LP_BASE(x)	lp_table[(x)].dev->port->base
 
+#ifdef LP_STATS
 struct lp_stats {
 	unsigned long chars;
 	unsigned long sleeps;
@@ -103,6 +113,7 @@
 	unsigned int meanwait;
 	unsigned int mdev;
 };
+#endif
 
 struct lp_struct {
 	struct pardevice *dev;
@@ -111,10 +122,13 @@
 	unsigned int time;
 	unsigned int wait;
 	char *lp_buffer;
+#ifdef LP_STATS
 	unsigned int lastcall;
 	unsigned int runchars;
-	unsigned int waittime;
 	struct lp_stats stats;
+#endif
+	struct wait_queue *wait_q;
+	unsigned int last_error;
 };
 
 /*
@@ -160,7 +174,7 @@
  */
 #define LP_DELAY 	50
 
-#define LP_POLLING(minor) (lp_table[(minor)].dev->port->irq == PARPORT_IRQ_NONE)
+#define LP_POLLED(minor) (lp_table[(minor)].dev->port->irq == PARPORT_IRQ_NONE)
 #define LP_PREEMPTED(minor) (lp_table[(minor)].dev->port->waithead != NULL)
 
 /*
diff -u --recursive --new-file v2.1.99/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.1.99/linux/include/linux/pci.h	Thu Apr 23 20:21:38 1998
+++ linux/include/linux/pci.h	Mon May  4 13:24:12 1998
@@ -1,5 +1,5 @@
 /*
- *	$Id: pci.h,v 1.67 1998/04/16 20:48:33 mj Exp $
+ *	$Id: pci.h,v 1.70 1998/05/02 19:20:03 mj Exp $
  *
  *	PCI defines and function prototypes
  *	Copyright 1994, Drew Eckhardt
@@ -275,6 +275,7 @@
  */
 #define PCI_VENDOR_ID_COMPAQ		0x0e11
 #define PCI_DEVICE_ID_COMPAQ_1280	0x3033
+#define PCI_DEVICE_ID_COMPAQ_TRIFLEX	0x4000
 #define PCI_DEVICE_ID_COMPAQ_SMART2P	0xae10
 #define PCI_DEVICE_ID_COMPAQ_NETEL100	0xae32
 #define PCI_DEVICE_ID_COMPAQ_NETEL10	0xae34
@@ -303,10 +304,14 @@
 #define PCI_DEVICE_ID_ATI_210888CX	0x4358
 #define PCI_DEVICE_ID_ATI_215GB		0x4742
 #define PCI_DEVICE_ID_ATI_215GD		0x4744
+#define PCI_DEVICE_ID_ATI_215GI		0x4749
 #define PCI_DEVICE_ID_ATI_215GP		0x4750
+#define PCI_DEVICE_ID_ATI_215GQ		0x4751
 #define PCI_DEVICE_ID_ATI_215GT		0x4754
 #define PCI_DEVICE_ID_ATI_215GTB	0x4755
 #define PCI_DEVICE_ID_ATI_210888GX	0x4758
+#define PCI_DEVICE_ID_ATI_215LG		0x4c47
+#define PCI_DEVICE_ID_ATI_264LT		0x4c54
 #define PCI_DEVICE_ID_ATI_264VT		0x5654
 
 #define PCI_VENDOR_ID_VLSI		0x1004
@@ -376,7 +381,8 @@
 #define PCI_DEVICE_ID_IBM_MCA		0x0020
 #define PCI_DEVICE_ID_IBM_82351		0x0022
 #define PCI_DEVICE_ID_IBM_SERVERAID	0x002e
-#define PCI_DEVICE_ID_IBM_MPEG2		0x007d
+#define PCI_DEVICE_ID_IBM_TR_WAKE	0x003e
+#define PCI_DEVICE_ID_IBM_3780IDSP	0x007d
 
 #define PCI_VENDOR_ID_WD		0x101c
 #define PCI_DEVICE_ID_WD_7197		0x3296
@@ -408,6 +414,7 @@
 #define PCI_DEVICE_ID_CT_65548		0x00dc
 #define PCI_DEVICE_ID_CT_65550		0x00e0
 #define PCI_DEVICE_ID_CT_65554		0x00e4
+#define PCI_DEVICE_ID_CT_65555		0x00e5
 
 #define PCI_VENDOR_ID_MIRO		0x1031
 #define PCI_DEVICE_ID_MIRO_36050	0x5601
@@ -419,9 +426,11 @@
 #define PCI_DEVICE_ID_FD_36C70		0x0000
 
 #define PCI_VENDOR_ID_SI		0x1039
-#define PCI_DEVICE_ID_SI_6201		0x0001
+#define PCI_DEVICE_ID_SI_5591_AGP	0x0001
 #define PCI_DEVICE_ID_SI_6202		0x0002
 #define PCI_DEVICE_ID_SI_503		0x0008
+#define PCI_DEVICE_ID_SI_ACPI		0x0009
+#define PCI_DEVICE_ID_SI_5597_VGA	0x0200
 #define PCI_DEVICE_ID_SI_6205		0x0205
 #define PCI_DEVICE_ID_SI_501		0x0406
 #define PCI_DEVICE_ID_SI_496		0x0496
@@ -430,6 +439,7 @@
 #define PCI_DEVICE_ID_SI_5511		0x5511
 #define PCI_DEVICE_ID_SI_5513		0x5513
 #define PCI_DEVICE_ID_SI_5571		0x5571
+#define PCI_DEVICE_ID_SI_5591		0x5591
 #define PCI_DEVICE_ID_SI_5597		0x5597
 #define PCI_DEVICE_ID_SI_7001		0x7001
 
@@ -493,6 +503,7 @@
 #define PCI_VENDOR_ID_N9		0x105d
 #define PCI_DEVICE_ID_N9_I128		0x2309
 #define PCI_DEVICE_ID_N9_I128_2		0x2339
+#define PCI_DEVICE_ID_N9_I128_T2R	0x493d
 
 #define PCI_VENDOR_ID_UMC		0x1060
 #define PCI_DEVICE_ID_UMC_UM8673F	0x0101
@@ -510,6 +521,7 @@
 
 #define PCI_VENDOR_ID_PICOP		0x1066
 #define PCI_DEVICE_ID_PICOP_PT86C52X	0x0001
+#define PCI_DEVICE_ID_PICOP_PT80C524	0x8002
 
 #define PCI_VENDOR_ID_APPLE		0x106b
 #define PCI_DEVICE_ID_APPLE_BANDIT	0x0001
@@ -538,7 +550,7 @@
 
 #define PCI_VENDOR_ID_CONTAQ		0x1080
 #define PCI_DEVICE_ID_CONTAQ_82C599	0x0600
-#define PCI_DEVICE_ID_CONTAQ_82C693	0xC693
+#define PCI_DEVICE_ID_CONTAQ_82C693	0xc693
 
 #define PCI_VENDOR_ID_FOREX		0x1083
 
@@ -589,7 +601,11 @@
 #define PCI_VENDOR_ID_PLX		0x10b5
 #define PCI_DEVICE_ID_PLX_9080		0x9080
 
+#define PCI_VENDOR_ID_MADGE		0x10b6
+#define PCI_DEVICE_ID_MADGE_MK2		0x0002
+
 #define PCI_VENDOR_ID_3COM		0x10b7
+#define PCI_DEVICE_ID_3COM_3C339	0x3390
 #define PCI_DEVICE_ID_3COM_3C590	0x5900
 #define PCI_DEVICE_ID_3COM_3C595TX	0x5950
 #define PCI_DEVICE_ID_3COM_3C595T4	0x5951
@@ -597,6 +613,8 @@
 #define PCI_DEVICE_ID_3COM_3C900TPO	0x9000
 #define PCI_DEVICE_ID_3COM_3C900COMBO	0x9001
 #define PCI_DEVICE_ID_3COM_3C905TX	0x9050
+#define PCI_DEVICE_ID_3COM_3C905T4	0x9051
+#define PCI_DEVICE_ID_3COM_3C905B_TX	0x9055
 
 #define PCI_VENDOR_ID_SMC		0x10b8
 #define PCI_DEVICE_ID_SMC_EPIC100	0x0005
@@ -618,6 +636,7 @@
 #define PCI_DEVICE_ID_AL_M5219		0x5219
 #define PCI_DEVICE_ID_AL_M5229		0x5229
 #define PCI_DEVICE_ID_AL_M5237		0x5237
+#define PCI_DEVICE_ID_AL_M7101		0x7101
 
 #define PCI_VENDOR_ID_MITSUBISHI	0x10ba
 
@@ -635,6 +654,10 @@
 #define PCI_DEVICE_ID_ASP_ABP940U	0x1300
 #define PCI_DEVICE_ID_ASP_ABP940UW	0x2300
 
+#define PCI_VENDOR_ID_MACRONIX		0x10d9
+#define PCI_DEVICE_ID_MACRONIX_MX98713	0x0512
+#define PCI_DEVICE_ID_MACRONIX_MX987x5	0x0531
+
 #define PCI_VENDOR_ID_CERN		0x10dc
 #define PCI_DEVICE_ID_CERN_SPSB_PMC	0x0001
 #define PCI_DEVICE_ID_CERN_SPSB_PCI	0x0002
@@ -654,6 +677,7 @@
 
 #define PCI_VENDOR_ID_AMCC		0x10e8
 #define PCI_DEVICE_ID_AMCC_MYRINET	0x8043
+#define PCI_DEVICE_ID_AMCC_PARASTATION	0x8062
 #define PCI_DEVICE_ID_AMCC_S5933	0x807d
 #define PCI_DEVICE_ID_AMCC_S5933_HEPC3	0x809c
 
@@ -664,6 +688,7 @@
 #define PCI_VENDOR_ID_REALTEK		0x10ec
 #define PCI_DEVICE_ID_REALTEK_8029	0x8029
 #define PCI_DEVICE_ID_REALTEK_8129	0x8129
+#define PCI_DEVICE_ID_REALTEK_8139	0x8139
 
 #define PCI_VENDOR_ID_TRUEVISION	0x10fa
 #define PCI_DEVICE_ID_TRUEVISION_T1000	0x000c
@@ -686,6 +711,7 @@
 #define PCI_DEVICE_ID_VIA_82C595_97	0x1595
 #define PCI_DEVICE_ID_VIA_82C586_2	0x3038
 #define PCI_DEVICE_ID_VIA_82C586_3	0x3040
+#define PCI_DEVICE_ID_VIA_86C100A	0x6100
 #define PCI_DEVICE_ID_VIA_82C597_1	0x8597
 
 #define PCI_VENDOR_ID_VORTEX		0x1119
@@ -734,6 +760,7 @@
 #define PCI_DEVICE_ID_IMAGINGTECH_ICPCI	0x0000
 
 #define PCI_VENDOR_ID_PHILIPS		0x1131
+#define PCI_DEVICE_ID_PHILIPS_SAA7145	0x7145
 #define PCI_DEVICE_ID_PHILIPS_SAA7146	0x7146
 
 #define PCI_VENDOR_ID_CYCLONE		0x113c
@@ -756,6 +783,7 @@
 #define PCI_DEVICE_ID_DIGI_CX		0x0006
 #define PCI_DEVICE_ID_DIGI_XRJ		0x0009
 #define PCI_DEVICE_ID_DIGI_EPCJ		0x000a
+#define PCI_DEVICE_ID_DIGI_XR_920	0x0027
 
 #define PCI_VENDOR_ID_MUTECH		0x1159
 #define PCI_DEVICE_ID_MUTECH_MV1000	0x0001
@@ -806,6 +834,9 @@
 #define PCI_DEVICE_ID_ZORAN_36057	0x6057
 #define PCI_DEVICE_ID_ZORAN_36120	0x6120
 
+#define PCI_VENDOR_ID_KINETIC		0x11f4
+#define PCI_DEVICE_ID_KINETIC_2915	0x2915
+
 #define PCI_VENDOR_ID_COMPEX		0x11f6
 #define PCI_DEVICE_ID_COMPEX_ENET100VG4	0x0112
 #define PCI_DEVICE_ID_COMPEX_RL2000	0x1401
@@ -823,7 +854,7 @@
 #define PCI_DEVICE_ID_CYCLOM_Z_Hi	0x0201
 
 #define PCI_VENDOR_ID_ESSENTIAL		0x120f
-#define PCI_DEVICE_ID_ROADRUNNER	0x0001
+#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER	0x0001
 
 #define PCI_VENDOR_ID_O2		0x1217
 #define PCI_DEVICE_ID_O2_6832		0x6832
@@ -835,6 +866,10 @@
 #define PCI_VENDOR_ID_SIGMADES		0x1236
 #define PCI_DEVICE_ID_SIGMADES_6425	0x6401
 
+#define PCI_VENDOR_ID_CCUBE		0x123f
+
+#define PCI_VENDOR_ID_DIPIX		0x1246
+
 #define PCI_VENDOR_ID_STALLION		0x124d
 #define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
 #define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
@@ -847,6 +882,13 @@
 #define PCI_DEVICE_ID_OPTIBASE_VPLEXCC	0x2120
 #define PCI_DEVICE_ID_OPTIBASE_VQUEST	0x2130
 
+#define PCI_VENDOR_ID_SATSAGEM		0x1267
+#define PCI_DEVICE_ID_SATSAGEM_PCR2101	0x5352
+#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
+
+#define PCI_VENDOR_ID_HUGHES		0x1273
+#define PCI_DEVICE_ID_HUGHES_DIRECPC	0x0002
+
 #define PCI_VENDOR_ID_ENSONIQ		0x1274
 #define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI	0x5000
 
@@ -856,6 +898,9 @@
 #define PCI_VENDOR_ID_NVIDIA_SGS	0x12d2
 #define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
 
+#define PCI_VENDOR_ID_CBOARDS		0x1307
+#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
+
 #define PCI_VENDOR_ID_SYMPHONY		0x1c1c
 #define PCI_DEVICE_ID_SYMPHONY_101	0x0001
 
@@ -867,6 +912,7 @@
 #define PCI_DEVICE_ID_3DLABS_500TX	0x0002
 #define PCI_DEVICE_ID_3DLABS_DELTA	0x0003
 #define PCI_DEVICE_ID_3DLABS_PERMEDIA	0x0004
+#define PCI_DEVICE_ID_3DLABS_MX		0x0006
 
 #define PCI_VENDOR_ID_AVANCE		0x4005
 #define PCI_DEVICE_ID_AVANCE_ALG2064	0x2064
@@ -916,6 +962,7 @@
 #define PCI_DEVICE_ID_INTEL_82371MX	0x1234
 #define PCI_DEVICE_ID_INTEL_82437MX	0x1235
 #define PCI_DEVICE_ID_INTEL_82441	0x1237
+#define PCI_DEVICE_ID_INTEL_82380FB	0x124b
 #define PCI_DEVICE_ID_INTEL_82439	0x1250
 #define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
@@ -928,6 +975,9 @@
 #define PCI_DEVICE_ID_INTEL_82371AB_3	0x7113
 #define PCI_DEVICE_ID_INTEL_82443LX_0	0x7180
 #define PCI_DEVICE_ID_INTEL_82443LX_1	0x7181
+#define PCI_DEVICE_ID_INTEL_82443BX_0	0x7190
+#define PCI_DEVICE_ID_INTEL_82443BX_1	0x7191
+#define PCI_DEVICE_ID_INTEL_82443BX_2	0x7192
 #define PCI_DEVICE_ID_INTEL_P6		0x84c4
 #define PCI_DEVICE_ID_INTEL_82450GX	0x84c5
 
@@ -952,6 +1002,7 @@
 #define PCI_DEVICE_ID_ADAPTEC_7882	0x8278
 #define PCI_DEVICE_ID_ADAPTEC_7883	0x8378
 #define PCI_DEVICE_ID_ADAPTEC_7884	0x8478
+#define PCI_DEVICE_ID_ADAPTEC_1030	0x8b78
 
 #define PCI_VENDOR_ID_ATRONICS		0x907f
 #define PCI_DEVICE_ID_ATRONICS_2015	0x2015
@@ -959,6 +1010,9 @@
 #define PCI_VENDOR_ID_HOLTEK		0x9412
 #define PCI_DEVICE_ID_HOLTEK_6565	0x6565
 
+#define PCI_VENDOR_ID_TIGERJET		0xe159
+#define PCI_DEVICE_ID_TIGERJET_300	0x0001
+
 #define PCI_VENDOR_ID_ARK		0xedd8
 #define PCI_DEVICE_ID_ARK_STING		0xa091
 #define PCI_DEVICE_ID_ARK_STINGARK	0xa099
@@ -978,6 +1032,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/types.h>
+
 /*
  * Error values that may be returned by the PCI bios.
  */
@@ -1084,13 +1140,13 @@
 struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
 
 #define pci_present pcibios_present
-#define pci_read_config_byte(dev, where, val) pcibios_read_config_byte(dev->bus->number, dev->devfn, where, val)
-#define pci_read_config_word(dev, where, val) pcibios_read_config_word(dev->bus->number, dev->devfn, where, val)
-#define pci_read_config_dword(dev, where, val) pcibios_read_config_dword(dev->bus->number, dev->devfn, where, val)
-#define pci_write_config_byte(dev, where, val) pcibios_write_config_byte(dev->bus->number, dev->devfn, where, val)
-#define pci_write_config_word(dev, where, val) pcibios_write_config_word(dev->bus->number, dev->devfn, where, val)
-#define pci_write_config_dword(dev, where, val) pcibios_write_config_dword(dev->bus->number, dev->devfn, where, val)
-void pci_set_master(struct pci_dev *);
+int pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val);
+int pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val);
+int pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val);
+int pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val);
+int pci_write_config_word(struct pci_dev *dev, u8 where, u16 val);
+int pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val);
+void pci_set_master(struct pci_dev *dev);
 
 #endif /* __KERNEL__ */
 #endif /* LINUX_PCI_H */
diff -u --recursive --new-file v2.1.99/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.1.99/linux/include/linux/proc_fs.h	Sat May  2 14:19:54 1998
+++ linux/include/linux/proc_fs.h	Thu May  7 18:14:28 1998
@@ -51,6 +51,7 @@
 	PROC_PPC_HTAB,
 	PROC_SOUND,
 	PROC_MTRR, /* whether enabled or not */
+	PROC_FS
 };
 
 enum pid_directory_inos {
@@ -205,6 +206,19 @@
 	PROC_BUS_LAST
 };
 
+enum fs_directory_inos {
+	PROC_FS_CODA = PROC_MCA_LAST,
+	PROC_FS_LAST
+};
+
+enum fs_coda_directory_inos {
+	PROC_VFS_STATS = PROC_MCA_LAST,
+	PROC_UPCALL_STATS,
+	PROC_PERMISSION_STATS,
+	PROC_CACHE_INV_STATS,
+	PROC_CODA_FS_LAST
+};
+
 /* Finally, the dynamically allocatable proc entries are reserved: */
 
 #define PROC_DYNAMIC_FIRST 4096
@@ -365,7 +379,6 @@
 extern struct inode_operations proc_file_inode_operations;
 extern struct inode_operations proc_net_inode_operations;
 extern struct inode_operations proc_netdir_inode_operations;
-extern struct inode_operations proc_scsi_inode_operations;
 extern struct inode_operations proc_openprom_inode_operations;
 extern struct inode_operations proc_mem_inode_operations;
 extern struct inode_operations proc_sys_inode_operations;
@@ -382,8 +395,6 @@
 extern struct inode_operations proc_omirr_inode_operations;
 extern struct inode_operations proc_ppc_htab_inode_operations;
 
-#endif
-
 /*
  * generic.c
  */
@@ -402,3 +413,5 @@
  * proc_devtree.c
  */
 extern void proc_device_tree_init(void);
+
+#endif /* _LINUX_PROC_FS_H */
diff -u --recursive --new-file v2.1.99/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.1.99/linux/include/linux/sched.h	Tue Apr 14 14:29:26 1998
+++ linux/include/linux/sched.h	Thu May  7 18:14:25 1998
@@ -354,7 +354,7 @@
 /* process credentials */					\
 /* uid etc */	0,0,0,0,0,0,0,0,				\
 /* suppl grps*/ 0, {0,},					\
-/* caps */      CAP_FULL_SET, CAP_FULL_SET, CAP_FULL_SET,    \
+/* caps */      CAP_INIT_EFF_SET,CAP_INIT_INH_SET,CAP_FULL_SET, \
 /* rlimits */   INIT_RLIMITS, \
 /* math */	0, \
 /* comm */	"swapper", \
diff -u --recursive --new-file v2.1.99/linux/include/linux/swapctl.h linux/include/linux/swapctl.h
--- v2.1.99/linux/include/linux/swapctl.h	Thu Mar 26 15:57:06 1998
+++ linux/include/linux/swapctl.h	Thu May  7 18:14:25 1998
@@ -50,6 +50,15 @@
 typedef freepages_v1 freepages_t;
 extern freepages_t freepages;
 
+typedef struct pager_daemon_v1
+{
+	unsigned int	tries_base;
+	unsigned int	tries_min;
+	unsigned int	swap_cluster;
+} pager_daemon_v1;
+typedef pager_daemon_v1 pager_daemon_t;
+extern pager_daemon_t pager_daemon;
+
 #define SC_VERSION	1
 #define SC_MAX_VERSION	1
 
diff -u --recursive --new-file v2.1.99/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.1.99/linux/include/linux/sysctl.h	Sat May  2 14:19:54 1998
+++ linux/include/linux/sysctl.h	Sat May  2 17:45:03 1998
@@ -84,7 +84,8 @@
 	VM_BDFLUSH,		/* struct: Control buffer cache flushing */
 	VM_OVERCOMMIT_MEMORY,	/* Turn off the virtual memory safety limit */
 	VM_BUFFERMEM,		/* struct: Set buffer memory thresholds */
-	VM_PAGECACHE		/* struct: Set cache memory thresholds */
+	VM_PAGECACHE,		/* struct: Set cache memory thresholds */
+	VM_PAGERDAEMON		/* struct: Control kswapd behaviour */
 };
 
 
diff -u --recursive --new-file v2.1.99/linux/include/linux/ufs_fs.h linux/include/linux/ufs_fs.h
--- v2.1.99/linux/include/linux/ufs_fs.h	Wed Apr  1 20:11:54 1998
+++ linux/include/linux/ufs_fs.h	Sun May  3 12:03:35 1998
@@ -255,12 +255,12 @@
 			__s32	fs_contigsumsize;/* size of cluster summary array */
 			__s32	fs_maxsymlinklen;/* max length of an internal symlink */
 			__s32	fs_inodefmt;	/* format of on-disk inodes */
-			__u64	fs_maxfilesize;	/* max representable file size */
+			__u32	fs_maxfilesize[2];/* max representable file size */
 			__u32	fs_qbmask[2];	/* ~usb_bmask */
 			__u32	fs_qfmask[2];	/* ~usb_fmask */
 			__s32	fs_state;	/* file system state time stamp */
 		} fs_44;
-	} fs_u  __attribute__ ((packed));
+	} fs_u;
 	__s32	fs_postblformat;	/* format of positional layout tables */
 	__s32	fs_nrpos;		/* number of rotational positions */
 	__s32	fs_postbloff;		/* (__s16) rotation block list head */
diff -u --recursive --new-file v2.1.99/linux/include/net/ipv6.h linux/include/net/ipv6.h
--- v2.1.99/linux/include/net/ipv6.h	Tue Mar 17 22:18:15 1998
+++ linux/include/net/ipv6.h	Thu May  7 18:16:46 1998
@@ -4,7 +4,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>
  *
- *	$Id: ipv6.h,v 1.9 1998/03/08 05:55:20 davem Exp $
+ *	$Id: ipv6.h,v 1.10 1998/04/30 16:24:14 freitag Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -108,6 +108,8 @@
 	struct frag_queue	*prev;
 
 	__u32			id;		/* fragment id		*/
+	struct in6_addr		saddr;
+	struct in6_addr		daddr;
 	struct timer_list	timer;		/* expire timer		*/
 	struct ipv6_frag	*fragments;
 	struct device		*dev;
@@ -247,6 +249,10 @@
 						  int len);
 
 extern void			ipv6opt_free(struct ipv6_options *opt);
+
+extern struct ipv6_opt_hdr *	ipv6_skip_exthdr(struct ipv6_opt_hdr *hdr, 
+					         u8 *nexthdrp, int len);
+
 
 
 /*
diff -u --recursive --new-file v2.1.99/linux/include/net/ndisc.h linux/include/net/ndisc.h
--- v2.1.99/linux/include/net/ndisc.h	Fri Feb  6 15:35:04 1998
+++ linux/include/net/ndisc.h	Thu May  7 18:16:46 1998
@@ -101,6 +101,8 @@
 						   struct icmp6hdr *hdr,
 						   int len);
 
+extern void			igmp6_cleanup(void);
+
 extern __inline__ struct neighbour * ndisc_get_neigh(struct device *dev, struct in6_addr *addr)
 {
 
diff -u --recursive --new-file v2.1.99/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.1.99/linux/include/net/tcp.h	Sat May  2 14:19:54 1998
+++ linux/include/net/tcp.h	Thu May  7 18:16:41 1998
@@ -642,7 +642,7 @@
 
 		/* PMTU discovery event has occurred. */
 		sk->mtu = dst->pmtu;
-		sk->mss = sk->mtu - mss_distance;
+		mss_now = sk->mss = sk->mtu - mss_distance;
 	}
 
 	if(tp->sack_ok && tp->num_sacks)
diff -u --recursive --new-file v2.1.99/linux/include/scsi/scsi_ioctl.h linux/include/scsi/scsi_ioctl.h
--- v2.1.99/linux/include/scsi/scsi_ioctl.h	Sat May  2 14:19:54 1998
+++ linux/include/scsi/scsi_ioctl.h	Fri May  1 11:19:58 1998
@@ -5,6 +5,8 @@
 #define SCSI_IOCTL_TEST_UNIT_READY 2
 #define SCSI_IOCTL_BENCHMARK_COMMAND 3
 #define SCSI_IOCTL_SYNC 4			/* Request synchronous parameters */
+#define SCSI_IOCTL_START_UNIT 5
+#define SCSI_IOCTL_STOP_UNIT 6
 /* The door lock/unlock constants are compatible with Sun constants for
    the cdrom */
 #define SCSI_IOCTL_DOORLOCK 0x5380		/* lock the eject mechanism */
diff -u --recursive --new-file v2.1.99/linux/ipc/msg.c linux/ipc/msg.c
--- v2.1.99/linux/ipc/msg.c	Tue Mar 17 22:18:15 1998
+++ linux/ipc/msg.c	Wed May  6 10:56:06 1998
@@ -477,9 +477,10 @@
 	case IPC_SET:
 		err = -EPERM;
 		if (current->euid != ipcp->cuid && 
-		    current->euid != ipcp->uid && !suser())
+		    current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN))
+		    /* We _could_ check for CAP_CHOWN above, but we don't */
 			goto out;
-		if (tbuf.msg_qbytes > MSGMNB && !suser())
+		if (tbuf.msg_qbytes > MSGMNB && !capable(CAP_SYS_RESOURCE))
 			goto out;
 		msq->msg_qbytes = tbuf.msg_qbytes;
 		ipcp->uid = tbuf.msg_perm.uid;
@@ -492,7 +493,7 @@
 	case IPC_RMID:
 		err = -EPERM;
 		if (current->euid != ipcp->cuid && 
-		    current->euid != ipcp->uid && !suser())
+		    current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN))
 			goto out;
 
 		freeque (id); 
diff -u --recursive --new-file v2.1.99/linux/ipc/sem.c linux/ipc/sem.c
--- v2.1.99/linux/ipc/sem.c	Sun Dec 21 17:11:08 1997
+++ linux/ipc/sem.c	Wed May  6 10:56:06 1998
@@ -482,7 +482,8 @@
 			goto out;
 		break;
 	case IPC_RMID:
-		if (current->euid == ipcp->cuid || current->euid == ipcp->uid || suser()) {
+		if (current->euid == ipcp->cuid || 
+		    current->euid == ipcp->uid || capable(CAP_SYS_ADMIN)) {
 			freeary (id);
 			err = 0;
 			goto out;
@@ -540,7 +541,8 @@
 		update_queue(sma);
 		break;
 	case IPC_SET:
-		if (current->euid == ipcp->cuid || current->euid == ipcp->uid || suser()) {
+		if (current->euid == ipcp->cuid || 
+		    current->euid == ipcp->uid || capable(CAP_SYS_ADMIN)) {
 			ipcp->uid = tbuf.sem_perm.uid;
 			ipcp->gid = tbuf.sem_perm.gid;
 			ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
diff -u --recursive --new-file v2.1.99/linux/ipc/shm.c linux/ipc/shm.c
--- v2.1.99/linux/ipc/shm.c	Wed Apr  1 20:11:54 1998
+++ linux/ipc/shm.c	Wed May  6 10:56:06 1998
@@ -306,7 +306,7 @@
 	switch (cmd) {
 	case SHM_UNLOCK:
 		err = -EPERM;
-		if (!suser())
+		if (!capable(CAP_IPC_LOCK))
 			goto out;
 		err = -EINVAL;
 		if (!(ipcp->mode & SHM_LOCKED))
@@ -318,7 +318,7 @@
 /* Should the pages be faulted in here or leave it to user? */
 /* need to determine interaction with current->swappable */
 		err = -EPERM;
-		if (!suser())
+		if (!capable(CAP_IPC_LOCK))
 			goto out;
 		err = -EINVAL;
 		if (ipcp->mode & SHM_LOCKED)
@@ -347,7 +347,8 @@
 		break;
 	case IPC_SET:
 		if (current->euid == shp->shm_perm.uid ||
-		    current->euid == shp->shm_perm.cuid || suser()) {
+		    current->euid == shp->shm_perm.cuid || 
+		    capable(CAP_SYS_ADMIN)) {
 			ipcp->uid = tbuf.shm_perm.uid;
 			ipcp->gid = tbuf.shm_perm.gid;
 			ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
@@ -359,7 +360,8 @@
 		goto out;
 	case IPC_RMID:
 		if (current->euid == shp->shm_perm.uid ||
-		    current->euid == shp->shm_perm.cuid || suser()) {
+		    current->euid == shp->shm_perm.cuid || 
+		    capable(CAP_SYS_ADMIN)) {
 			shp->shm_perm.mode |= SHM_DEST;
 			if (shp->shm_nattch <= 0)
 				killseg (id);
diff -u --recursive --new-file v2.1.99/linux/ipc/util.c linux/ipc/util.c
--- v2.1.99/linux/ipc/util.c	Tue Mar 17 22:18:15 1998
+++ linux/ipc/util.c	Wed May  6 10:56:06 1998
@@ -47,8 +47,10 @@
 	else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
 		granted_mode >>= 3;
 	/* is there some bit set in requested_mode but not in granted_mode? */
-	if ((requested_mode & ~granted_mode & 0007) && !suser())
+	if ((requested_mode & ~granted_mode & 0007) && 
+	    !capable(CAP_IPC_OWNER))
 		return -1;
+
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.99/linux/kernel/Makefile linux/kernel/Makefile
--- v2.1.99/linux/kernel/Makefile	Tue Mar 17 22:18:15 1998
+++ linux/kernel/Makefile	Wed May  6 11:01:46 1998
@@ -13,7 +13,7 @@
 O_TARGET := kernel.o
 O_OBJS    = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \
 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
-	    sysctl.o acct.o
+	    sysctl.o acct.o capability.o
 
 OX_OBJS  += signal.o
 
diff -u --recursive --new-file v2.1.99/linux/kernel/acct.c linux/kernel/acct.c
--- v2.1.99/linux/kernel/acct.c	Tue Mar 10 10:03:35 1998
+++ linux/kernel/acct.c	Wed May  6 10:56:06 1998
@@ -119,7 +119,7 @@
 	int error = -EPERM;
 
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_PACCT))
 		goto out;
 
 	if (name == (char *)NULL) {
diff -u --recursive --new-file v2.1.99/linux/kernel/capability.c linux/kernel/capability.c
--- v2.1.99/linux/kernel/capability.c	Wed Dec 31 16:00:00 1969
+++ linux/kernel/capability.c	Wed May  6 11:01:46 1998
@@ -0,0 +1,252 @@
+/*
+ * linux/kernel/capability.c
+ *
+ * Copyright (C) 1997  Andrew Main <zefram@fysh.org>
+ * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@transmeta.com>
+ */ 
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/capability.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include <asm/uaccess.h>
+
+static inline void cap_fromuser(kernel_cap_t *k, __u32 *u)
+{
+     copy_from_user(k, u, sizeof(*k));
+}
+
+
+static inline void cap_touser(__u32 *u, const kernel_cap_t *k)
+{
+     copy_to_user(u, k, sizeof(*k));
+}
+
+#ifdef __SMP__
+static spinlock_t task_capability_lock;
+#endif
+
+/*
+ * For sys_getproccap() and sys_setproccap(), any of the three
+ * capability set pointers may be NULL -- indicating that that set is
+ * uninteresting and/or not to be changed.
+ */
+
+asmlinkage int sys_capget(cap_user_header_t header, cap_user_data_t data)
+{
+     int error = -EINVAL, pid;
+     __u32 version;
+     struct task_struct *target;
+
+     if (!access_ok(VERIFY_WRITE, &header->version, sizeof(*header))) {
+             /* not large enough for current header so indicate error */
+             if (access_ok(VERIFY_WRITE, &header->version,
+                           sizeof(header->version))) {
+                     return error;
+             }
+             goto all_done;
+     }
+
+     copy_from_user(&version, &header->version, sizeof(header->version));
+     if (version != _LINUX_CAPABILITY_VERSION) {
+             /* if enough space for kernel version, write that */
+
+     all_done:
+             version = _LINUX_CAPABILITY_VERSION;
+             copy_to_user(&header->version, &version,
+                          sizeof(header->version));
+             return error;
+     }
+
+     if (!access_ok(VERIFY_WRITE, data, sizeof(*data))) {
+             return error;
+     }
+
+     copy_from_user(&pid, &header->pid, sizeof(header->pid));
+     if (pid < 0) {
+             return error;
+     }
+
+     spin_lock(&task_capability_lock);
+
+     if (pid && pid != current->pid) {
+             read_lock(&tasklist_lock);
+             target = find_task_by_pid(pid);  /* identify target of query */
+             if (!target) {
+                     error = -ESRCH;
+                     goto out;
+             }
+     } else {
+             target = current;
+     }
+
+     cap_touser(&data->permitted, &target->cap_permitted);
+     cap_touser(&data->inheritable, &target->cap_inheritable);
+     cap_touser(&data->effective, &target->cap_effective);
+
+     error = 0;
+
+out:
+     if (target != current) {
+             read_unlock(&tasklist_lock);
+     }
+     spin_unlock(&task_capability_lock);
+     return error;
+}
+
+/* set capabilities for all processes in a given process group */
+
+static void cap_set_pg(int pgrp,
+                    kernel_cap_t *effective,
+                    kernel_cap_t *inheritable,
+                    kernel_cap_t *permitted)
+{
+     struct task_struct *target;
+
+     /* FIXME: do we need to have a write lock here..? */
+     read_lock(&tasklist_lock);
+     for_each_task(target) {
+             if (target->pgrp != pgrp)
+                     continue;
+             target->cap_effective   = *effective;
+             target->cap_inheritable = *inheritable;
+             target->cap_permitted   = *permitted;
+     }
+     read_unlock(&tasklist_lock);
+}
+
+/* set capabilities for all processes other than 1 and self */
+
+static void cap_set_all(kernel_cap_t *effective,
+                     kernel_cap_t *inheritable,
+                     kernel_cap_t *permitted)
+{
+     struct task_struct *target;
+
+     /* FIXME: do we need to have a write lock here..? */
+     read_lock(&tasklist_lock);
+     /* ALL means everyone other than self or 'init' */
+     for_each_task(target) {
+             if (target == current || target->pid == 1)
+                     continue;
+             target->cap_effective   = *effective;
+             target->cap_inheritable = *inheritable;
+             target->cap_permitted   = *permitted;
+     }
+     read_unlock(&tasklist_lock);
+}
+
+/*
+ * The restrictions on setting capabilities are specified as:
+ *
+ * [pid is for the 'target' task.  'current' is the calling task.]
+ *
+ * I: any raised capabilities must be a subset of the (old current) Permitted
+ * P: any raised capabilities must be a subset of the (old current) permitted
+ * E: must be set to a subset of (new target) Permitted
+ */
+
+asmlinkage int sys_capset(cap_user_header_t header, const cap_user_data_t data)
+{
+     kernel_cap_t inheritable, permitted, effective;
+     __u32 version;
+     struct task_struct *target;
+     int error = -EINVAL, pid;
+
+     if (!access_ok(VERIFY_WRITE, &header->version, sizeof(*header))) {
+             /* not large enough for current header so indicate error */
+             if (!access_ok(VERIFY_WRITE, &header->version,
+                            sizeof(header->version))) {
+                     return error;
+             }
+             goto all_done;
+     }
+
+     copy_from_user(&version, &header->version, sizeof(header->version));
+     if (version != _LINUX_CAPABILITY_VERSION) {
+
+     all_done:
+             version = _LINUX_CAPABILITY_VERSION;
+             copy_to_user(&header->version, &version,
+                          sizeof(header->version));
+             return error;
+     }
+
+     if (!access_ok(VERIFY_READ, data, sizeof(*data))) {
+             return error;
+     }
+
+     /* may want to set other processes at some point -- for now demand 0 */
+     copy_from_user(&pid, &header->pid, sizeof(pid));
+
+     error = -EPERM;
+     if (pid && !capable(CAP_SETPCAP))
+             return error;
+
+     spin_lock(&task_capability_lock);
+
+     if (pid > 0 && pid != current->pid) {
+             read_lock(&tasklist_lock);
+             target = find_task_by_pid(pid);  /* identify target of query */
+             if (!target) {
+                     error = -ESRCH;
+                     goto out;
+             }
+     } else {
+             target = current;
+     }
+
+     /* copy from userspace */
+     cap_fromuser(&effective, &data->effective);
+     cap_fromuser(&inheritable, &data->inheritable);
+     cap_fromuser(&permitted, &data->permitted);
+
+     /* verify restrictions on target's new Inheritable set */
+     if (!cap_issubset(inheritable,
+                       cap_combine(target->cap_inheritable,
+                                   current->cap_permitted))) {
+             goto out;
+     }
+
+     /* verify restrictions on target's new Permitted set */
+     if (!cap_issubset(permitted,
+                       cap_combine(target->cap_permitted,
+                                   current->cap_permitted))) {
+             goto out;
+     }
+
+     /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
+     if (!cap_issubset(effective, permitted)) {
+             goto out;
+     }
+
+     /* having verified that the proposed changes are legal,
+           we now put them into effect. */
+     error = 0;
+
+     if (pid < 0) {
+             if (pid == -1)  /* all procs other than current and init */
+                     cap_set_all(&effective, &inheritable, &permitted);
+
+             else            /* all procs in process group */
+                     cap_set_pg(-pid, &effective, &inheritable, &permitted);
+             goto spin_out;
+     } else {
+             /* FIXME: do we need to have a write lock here..? */
+             target->cap_effective   = effective;
+             target->cap_inheritable = inheritable;
+             target->cap_permitted   = permitted;
+     }
+
+out:
+     if (target != current) {
+             read_unlock(&tasklist_lock);
+     }
+spin_out:
+     spin_unlock(&task_capability_lock);
+     return error;
+}
diff -u --recursive --new-file v2.1.99/linux/kernel/fork.c linux/kernel/fork.c
--- v2.1.99/linux/kernel/fork.c	Tue Apr 14 14:29:26 1998
+++ linux/kernel/fork.c	Wed May  6 14:42:54 1998
@@ -56,9 +56,7 @@
 	int task_count;
 } *uidhash[UIDHASH_SZ];
 
-#ifdef __SMP__
-static spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
-#endif
+spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
 
 kmem_cache_t *uid_cachep;
 
@@ -154,10 +152,8 @@
 	return -EAGAIN;
 }
 
-#ifdef __SMP__
 /* Protects next_safe and last_pid. */
-static spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED;
-#endif
+spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED;
 
 static int get_pid(unsigned long flags)
 {
diff -u --recursive --new-file v2.1.99/linux/kernel/module.c linux/kernel/module.c
--- v2.1.99/linux/kernel/module.c	Tue Mar 17 22:18:15 1998
+++ linux/kernel/module.c	Wed May  6 10:56:06 1998
@@ -120,7 +120,7 @@
 	struct module *mod;
 
 	lock_kernel();
-	if (!suser()) {
+	if (!capable(CAP_SYS_MODULE)) {
 		error = -EPERM;
 		goto err0;
 	}
@@ -175,7 +175,7 @@
 	struct module_ref *dep;
 
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_MODULE))
 		goto err0;
 	if ((namelen = get_mod_name(name_user, &name)) < 0) {
 		error = namelen;
@@ -366,7 +366,7 @@
 	int something_changed;
 
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_MODULE))
 		goto out;
 
 	if (name_user) {
diff -u --recursive --new-file v2.1.99/linux/kernel/printk.c linux/kernel/printk.c
--- v2.1.99/linux/kernel/printk.c	Tue Apr 14 14:29:26 1998
+++ linux/kernel/printk.c	Wed May  6 10:56:06 1998
@@ -130,7 +130,7 @@
 	int error = -EPERM;
 
 	lock_kernel();
-	if ((type != 3) && !suser())
+	if ((type != 3) && !capable(CAP_SYS_ADMIN))
 		goto out;
 	error = 0;
 	switch (type) {
diff -u --recursive --new-file v2.1.99/linux/kernel/sched.c linux/kernel/sched.c
--- v2.1.99/linux/kernel/sched.c	Wed Apr  1 20:11:54 1998
+++ linux/kernel/sched.c	Wed May  6 10:56:06 1998
@@ -1227,7 +1227,7 @@
 	 
 	newprio = increment;
 	if (increment < 0) {
-		if (!suser())
+		if (!capable(CAP_SYS_NICE))
 			return -EPERM;
 		newprio = -increment;
 		increase = 1;
@@ -1322,10 +1322,11 @@
 		goto out_unlock;
 
 	retval = -EPERM;
-	if ((policy == SCHED_FIFO || policy == SCHED_RR) && !suser())
+	if ((policy == SCHED_FIFO || policy == SCHED_RR) && 
+	    !capable(CAP_SYS_NICE))
 		goto out_unlock;
 	if ((current->euid != p->euid) && (current->euid != p->uid) &&
-	    !suser())
+	    !capable(CAP_SYS_NICE))
 		goto out_unlock;
 
 	retval = 0;
diff -u --recursive --new-file v2.1.99/linux/kernel/signal.c linux/kernel/signal.c
--- v2.1.99/linux/kernel/signal.c	Tue Apr 14 14:29:26 1998
+++ linux/kernel/signal.c	Wed May  6 10:56:06 1998
@@ -235,7 +235,7 @@
 	    && ((sig != SIGCONT) || (current->session != t->session))
 	    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
 	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
-	    && !suser())
+	    && !capable(CAP_SYS_ADMIN))
 		goto out_nolock;
 
 	/* The null signal is a permissions and process existance probe.
diff -u --recursive --new-file v2.1.99/linux/kernel/sys.c linux/kernel/sys.c
--- v2.1.99/linux/kernel/sys.c	Thu Apr 23 20:21:38 1998
+++ linux/kernel/sys.c	Thu May  7 15:34:02 1998
@@ -114,13 +114,13 @@
 		if (!proc_sel(p, which, who))
 			continue;
 		if (p->uid != current->euid &&
-			p->uid != current->uid && !suser()) {
+			p->uid != current->uid && !capable(CAP_SYS_NICE)) {
 			error = EPERM;
 			continue;
 		}
 		if (error == ESRCH)
 			error = 0;
-		if (priority > p->priority && !suser())
+		if (priority > p->priority && !capable(CAP_SYS_NICE))
 			error = EACCES;
 		else
 			p->priority = priority;
@@ -172,7 +172,7 @@
 	char buffer[256];
 
 	/* We only trust the superuser with rebooting the system. */
-	if (!suser())
+	if (!capable(CAP_SYS_BOOT))
 		return -EPERM;
 
 	/* For safety, we require "magic" arguments. */
@@ -273,7 +273,7 @@
 	if (rgid != (gid_t) -1) {
 		if ((old_rgid == rgid) ||
 		    (current->egid==rgid) ||
-		    suser())
+		    capable(CAP_SETGID))
 			current->gid = rgid;
 		else
 			return -EPERM;
@@ -282,7 +282,7 @@
 		if ((old_rgid == egid) ||
 		    (current->egid == egid) ||
 		    (current->sgid == egid) ||
-		    suser())
+		    capable(CAP_SETGID))
 			current->fsgid = current->egid = egid;
 		else {
 			current->gid = old_rgid;
@@ -307,7 +307,7 @@
 {
 	int old_egid = current->egid;
 
-	if (suser())
+	if (capable(CAP_SETGID))
 		current->gid = current->egid = current->sgid = current->fsgid = gid;
 	else if ((gid == current->gid) || (gid == current->sgid))
 		current->egid = current->fsgid = gid;
@@ -319,6 +319,41 @@
 	return 0;
 }
   
+/* 
+ * cap_emulate_setxuid() fixes the effective / permitted capabilities of
+ * a process after a call to setuid, setreuid, or setresuid.
+ *
+ *  1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
+ *  {r,e,s}uid != 0, the permitted and effective capabilities are
+ *  cleared.
+ *
+ *  2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
+ *  capabilities of the process are cleared.
+ *
+ *  3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
+ *  capabilities are set to the permitted capabilities.
+ *
+ *  fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should 
+ *  never happen.
+ *
+ *  -astor 
+ */
+extern inline void cap_emulate_setxuid(int old_ruid, int old_euid, 
+				       int old_suid)
+{
+	if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
+	    (current->uid != 0 && current->euid != 0 && current->suid != 0)) {
+		cap_clear(current->cap_permitted);
+		cap_clear(current->cap_effective);
+	}
+	if (old_euid == 0 && current->euid != 0) {
+		cap_clear(current->cap_effective);
+	}
+	if (old_euid != 0 && current->euid == 0) {
+		current->cap_effective = current->cap_permitted;
+	}
+}
+
 /*
  * Unprivileged users may change the real uid to the effective uid
  * or vice versa.  (BSD-style)
@@ -336,14 +371,15 @@
  */
 asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
 {
-	int old_ruid, old_euid, new_ruid;
+	int old_ruid, old_euid, old_suid, new_ruid;
 
 	new_ruid = old_ruid = current->uid;
 	old_euid = current->euid;
+	old_suid = current->suid;
 	if (ruid != (uid_t) -1) {
 		if ((old_ruid == ruid) || 
 		    (current->euid==ruid) ||
-		    suser())
+		    capable(CAP_SETUID))
 			new_ruid = ruid;
 		else
 			return -EPERM;
@@ -352,7 +388,7 @@
 		if ((old_ruid == euid) ||
 		    (current->euid == euid) ||
 		    (current->suid == euid) ||
-		    suser())
+		    capable(CAP_SETUID))
 			current->fsuid = current->euid = euid;
 		else
 			return -EPERM;
@@ -375,9 +411,16 @@
 		if(new_ruid)
 			charge_uid(current, 1);
 	}
+	
+	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+	}
+
 	return 0;
 }
 
+
+		
 /*
  * setuid() is implemented like SysV w/ SAVED_IDS 
  * 
@@ -392,10 +435,11 @@
 asmlinkage int sys_setuid(uid_t uid)
 {
 	int old_euid = current->euid;
-	int old_ruid, new_ruid;
+	int old_ruid, old_suid, new_ruid;
 
 	old_ruid = new_ruid = current->uid;
-	if (suser())
+	old_suid = current->suid;
+	if (capable(CAP_SETUID))
 		new_ruid = current->euid = current->suid = current->fsuid = uid;
 	else if ((uid == current->uid) || (uid == current->suid))
 		current->fsuid = current->euid = uid;
@@ -412,6 +456,11 @@
 		if(new_ruid)
 			charge_uid(current, 1);
 	}
+
+	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+	}
+
 	return 0;
 }
 
@@ -422,6 +471,9 @@
  */
 asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
 {
+	int old_ruid = current->uid;
+	int old_euid = current->euid;
+	int old_suid = current->suid;
 	if (current->uid != 0 && current->euid != 0 && current->suid != 0) {
 		if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
 		    (ruid != current->euid) && (ruid != current->suid))
@@ -448,6 +500,11 @@
 	}
 	if (suid != (uid_t) -1)
 		current->suid = suid;
+
+	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+	}
+
 	return 0;
 }
 
@@ -515,11 +572,31 @@
 
 	old_fsuid = current->fsuid;
 	if (uid == current->uid || uid == current->euid ||
-	    uid == current->suid || uid == current->fsuid || suser())
+	    uid == current->suid || uid == current->fsuid || 
+	    capable(CAP_SETUID))
 		current->fsuid = uid;
 	if (current->fsuid != old_fsuid)
 		current->dumpable = 0;
 
+	/* We emulate fsuid by essentially doing a scaled-down version
+         * of what we did in setresuid and friends. However, we only
+         * operate on the fs-specific bits of the process' effective
+         * capabilities 
+         *
+         * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
+         *          if not, we might be a bit too harsh here.
+         */
+	
+	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+		if (old_fsuid == 0 && current->fsuid != 0) {
+			current->cap_effective.cap &= ~CAP_FS_MASK;
+		}
+		if (old_fsuid != 0 && current->fsuid == 0) {
+			current->cap_effective.cap |=
+				(current->cap_permitted.cap & CAP_FS_MASK);
+		}
+	}
+
 	return old_fsuid;
 }
 
@@ -532,7 +609,8 @@
 
 	old_fsgid = current->fsgid;
 	if (gid == current->gid || gid == current->egid ||
-	    gid == current->sgid || gid == current->fsgid || suser())
+	    gid == current->sgid || gid == current->fsgid || 
+	    capable(CAP_SETGID))
 		current->fsgid = gid;
 	if (current->fsgid != old_fsgid)
 		current->dumpable = 0;
@@ -716,7 +794,7 @@
  
 asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
 {
-	if (!suser())
+	if (!capable(CAP_SETGID))
 		return -EPERM;
 	if ((unsigned) gidsetsize > NGROUPS)
 		return -EINVAL;
@@ -756,7 +834,7 @@
 
 asmlinkage int sys_sethostname(char *name, int len)
 {
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	if (len < 0 || len > __NEW_UTS_LEN)
 		return -EINVAL;
@@ -787,7 +865,7 @@
  */
 asmlinkage int sys_setdomainname(char *name, int len)
 {
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	if (len < 0 || len > __NEW_UTS_LEN)
 		return -EINVAL;
@@ -820,7 +898,7 @@
 	old_rlim = current->rlim + resource;
 	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
 	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
-	    !suser())
+	    !capable(CAP_SYS_RESOURCE))
 		return -EPERM;
 	if (resource == RLIMIT_NOFILE) {
 		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
@@ -916,3 +994,4 @@
         }
         return error;
 }
+
diff -u --recursive --new-file v2.1.99/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.1.99/linux/kernel/sysctl.c	Sat May  2 14:19:54 1998
+++ linux/kernel/sysctl.c	Sat May  2 17:44:59 1998
@@ -189,20 +189,22 @@
 
 static ctl_table vm_table[] = {
 	{VM_SWAPCTL, "swapctl", 
-	 &swap_control, sizeof(swap_control_t), 0600, NULL, &proc_dointvec},
+	 &swap_control, sizeof(swap_control_t), 0644, NULL, &proc_dointvec},
 	{VM_SWAPOUT, "swapout_interval",
-	 &swapout_interval, sizeof(int), 0600, NULL, &proc_dointvec},
+	 &swapout_interval, sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_FREEPG, "freepages", 
-	 &freepages, sizeof(freepages_t), 0600, NULL, &proc_dointvec},
+	 &freepages, sizeof(freepages_t), 0644, NULL, &proc_dointvec},
 	{VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0600, NULL,
 	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
 	 &bdflush_min, &bdflush_max},
 	{VM_OVERCOMMIT_MEMORY, "overcommit_memory", &sysctl_overcommit_memory,
 	 sizeof(sysctl_overcommit_memory), 0644, NULL, &proc_dointvec},
 	{VM_BUFFERMEM, "buffermem",
-	 &buffer_mem, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
+	 &buffer_mem, sizeof(buffer_mem_t), 0644, NULL, &proc_dointvec},
 	{VM_PAGECACHE, "pagecache",
-	 &page_cache, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
+	 &page_cache, sizeof(buffer_mem_t), 0644, NULL, &proc_dointvec},
+	{VM_PAGERDAEMON, "kswapd",
+	 &pager_daemon, sizeof(pager_daemon_t), 0644, NULL, &proc_dointvec},
 	{0}
 };
 
diff -u --recursive --new-file v2.1.99/linux/kernel/time.c linux/kernel/time.c
--- v2.1.99/linux/kernel/time.c	Tue Feb 17 13:12:49 1998
+++ linux/kernel/time.c	Wed May  6 10:56:06 1998
@@ -87,7 +87,7 @@
 {
 	int value;
 
-	if (!suser())
+	if (!capable(CAP_SYS_TIME))
 		return -EPERM;
 	if (get_user(value, tptr))
 		return -EFAULT;
@@ -156,7 +156,7 @@
 {
 	static int firsttime = 1;
 
-	if (!suser())
+	if (!capable(CAP_SYS_TIME))
 		return -EPERM;
 		
 	if (tz) {
@@ -221,7 +221,7 @@
         long ltemp, mtemp, save_adjust;
 
 	/* In order to modify anything, you gotta be super-user! */
-	if (txc->modes && !suser())
+	if (txc->modes && !capable(CAP_SYS_TIME))
 		return -EPERM;
 		
 	/* Now we validate the data before disabling interrupts */
diff -u --recursive --new-file v2.1.99/linux/mm/Makefile linux/mm/Makefile
--- v2.1.99/linux/mm/Makefile	Wed Jul 16 19:22:51 1997
+++ linux/mm/Makefile	Sun May  3 12:14:31 1998
@@ -9,7 +9,7 @@
 
 O_TARGET := mm.o
 O_OBJS	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
-	    vmalloc.o slab.o simp.o\
+	    vmalloc.o slab.o \
 	    swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.99/linux/mm/mlock.c linux/mm/mlock.c
--- v2.1.99/linux/mm/mlock.c	Tue Mar 10 10:03:36 1998
+++ linux/mm/mlock.c	Wed May  6 10:56:06 1998
@@ -144,7 +144,7 @@
 	struct vm_area_struct * vma, * next;
 	int error;
 
-	if (!suser())
+	if (!capable(CAP_IPC_LOCK))
 		return -EPERM;
 	len = (len + ~PAGE_MASK) & PAGE_MASK;
 	end = start + len;
@@ -235,7 +235,7 @@
 	unsigned int def_flags;
 	struct vm_area_struct * vma;
 
-	if (!suser())
+	if (!capable(CAP_IPC_LOCK))
 		return -EPERM;
 
 	def_flags = 0;
diff -u --recursive --new-file v2.1.99/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.1.99/linux/mm/page_alloc.c	Sat May  2 14:19:54 1998
+++ linux/mm/page_alloc.c	Wed May  6 14:42:54 1998
@@ -98,9 +98,7 @@
  *
  * Hint: -mask = 1+~mask
  */
-#ifdef __SMP__
-static spinlock_t page_alloc_lock;
-#endif
+static spinlock_t page_alloc_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * This routine is used by the kernel swap deamon to determine
@@ -125,7 +123,7 @@
 	 * free unfragmented memory.
 	 * Added low/high water marks to avoid thrashing -- Rik.
 	 */
-	if (nr_free_pages > (num_physpages >> 5) + (nr ? 0 : num_physpages >> 6))
+	if (nr_free_pages > (nr ? freepages.low : freepages.high))
 		return nr+1;
 
 	list = free_area + NR_MEM_LISTS;
@@ -282,7 +280,6 @@
 		spin_unlock_irqrestore(&page_alloc_lock, flags);
 		if (!(gfp_mask & __GFP_WAIT))
 			break;
-		shrink_dcache();
 		if (!try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX))
 			break;
 		gfp_mask &= ~__GFP_WAIT;	/* go through this only once */
@@ -335,15 +332,19 @@
 	int i;
 
 	/*
-	 * select nr of pages we try to keep free for important stuff
-	 * with a minimum of 48 pages. This is totally arbitrary
+	 * Select nr of pages we try to keep free for important stuff
+	 * with a minimum of 48 pages and a maximum of 256 pages, so
+	 * that we don't waste too much memory on large systems.
+	 * This is totally arbitrary.
 	 */
 	i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+7);
 	if (i < 48)
 		i = 48;
+	if (i > 256)
+		i = 256;
 	freepages.min = i;
-	freepages.low = i + (i>>1);
-	freepages.high = i + i;
+	freepages.low = i << 1;
+	freepages.high = freepages.low + i;
 	mem_map = (mem_map_t *) LONG_ALIGN(start_mem);
 	p = mem_map + MAP_NR(end_mem);
 	start_mem = LONG_ALIGN((unsigned long) p);
diff -u --recursive --new-file v2.1.99/linux/mm/swap.c linux/mm/swap.c
--- v2.1.99/linux/mm/swap.c	Thu Mar 26 15:57:06 1998
+++ linux/mm/swap.c	Sat May  2 17:44:59 1998
@@ -44,8 +44,8 @@
  */
 freepages_t freepages = {
 	48,	/* freepages.min */
-	72,	/* freepages.low */
-	96	/* freepages.high */
+	96,	/* freepages.low */
+	144	/* freepages.high */
 };
 
 /* We track the number of pages currently being asynchronously swapped
@@ -76,4 +76,10 @@
 	10,	/* minimum percent page cache */
 	30,	/* borrow percent page cache */
 	75	/* maximum */
+};
+
+pager_daemon_t pager_daemon = {
+	512,	/* base number for calculating the number of tries */
+	SWAP_CLUSTER_MAX,	/* minimum number of tries */
+	SWAP_CLUSTER_MAX,	/* do swap I/O in clusters of this size */
 };
diff -u --recursive --new-file v2.1.99/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.1.99/linux/mm/swapfile.c	Wed Apr  8 19:36:29 1998
+++ linux/mm/swapfile.c	Wed May  6 10:56:06 1998
@@ -356,7 +356,7 @@
 	int err = -EPERM;
 	
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		goto out;
 
 	dentry = namei(specialfile);
@@ -491,7 +491,7 @@
 	static int least_priority = 0;
 
 	lock_kernel();
-	if (!suser())
+	if (!capable(CAP_SYS_ADMIN))
 		goto out;
 	memset(&filp, 0, sizeof(filp));
 	p = swap_info;
diff -u --recursive --new-file v2.1.99/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.1.99/linux/mm/vmscan.c	Sat May  2 14:19:54 1998
+++ linux/mm/vmscan.c	Sat May  2 17:44:59 1998
@@ -455,17 +455,20 @@
 	switch (state) {
 		do {
 		case 0:
-			state = 1;
 			if (shrink_mmap(i, gfp_mask))
 				return 1;
+			state = 1;
 		case 1:
-			state = 2;
 			if ((gfp_mask & __GFP_IO) && shm_swap(i, gfp_mask))
 				return 1;
-		default:
-			state = 0;
+			state = 2;
+		case 2:
 			if (swap_out(i, gfp_mask))
 				return 1;
+			state = 3;
+		case 3:
+			shrink_dcache_memory(i, gfp_mask);
+			state = 0;
 		i--;
 		} while ((i - stop) >= 0);
 	}
@@ -545,30 +548,28 @@
 		schedule();
 		swapstats.wakeups++;
 
-		/* This will gently shrink the dcache.. */
-		shrink_dcache_memory();
-	
 		/*
 		 * Do the background pageout: be
 		 * more aggressive if we're really
 		 * low on free memory.
 		 *
-		 * The number of tries is 512 divided by an
-		 * 'urgency factor'. In practice this will mean
-		 * a value of 512 / 8 = 64 pages at a time,
-		 * giving 64 * 4 (times/sec) * 4k (pagesize) =
-		 * 1 MB/s in lowest-priority background
-		 * paging. This number rises to 8 MB/s when the
-		 * priority is highest (but then we'll be woken
-		 * up more often and the rate will be even higher).
-		 * -- Should make this sysctl tunable...
+		 * We try page_daemon.tries_base times, divided by
+		 * an 'urgency factor'. In practice this will mean
+		 * a value of pager_daemon.tries_base / 8 or 4 = 64
+		 * or 128 pages at a time.
+		 * This gives us 64 (or 128) * 4k * 4 (times/sec) =
+		 * 1 (or 2) MB/s swapping bandwidth in low-priority
+		 * background paging. This number rises to 8 MB/s
+		 * when the priority is highest (but then we'll be
+		 * woken up more often and the rate will be even
+		 * higher).
 		 */
-		tries = (512) >> free_memory_available(3);
+		tries = pager_daemon.tries_base >> free_memory_available(3);
 	
 		while (tries--) {
 			int gfp_mask;
 
-			if (++tried > SWAP_CLUSTER_MAX && free_memory_available(0))
+			if (++tried > pager_daemon.tries_min && free_memory_available(0))
 				break;
 			gfp_mask = __GFP_IO;
 			try_to_free_page(gfp_mask);
@@ -576,7 +577,7 @@
 			 * Syncing large chunks is faster than swapping
 			 * synchronously (less head movement). -- Rik.
 			 */
-			if (atomic_read(&nr_async_pages) >= SWAP_CLUSTER_MAX)
+			if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster)
 				run_task_queue(&tq_disk);
 
 		}
diff -u --recursive --new-file v2.1.99/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v2.1.99/linux/net/appletalk/ddp.c	Tue Mar 17 22:18:16 1998
+++ linux/net/appletalk/ddp.c	Wed May  6 10:56:06 1998
@@ -719,7 +719,7 @@
 	switch(cmd)
 	{
 		case SIOCSIFADDR:
-			if(!suser())
+			if(!capable(CAP_NET_ADMIN))
 				return (-EPERM);
 			if(sa->sat_family != AF_APPLETALK)
 				return (-EINVAL);
@@ -830,7 +830,7 @@
 
 	        case SIOCATALKDIFADDR:
 	        case SIOCDIFADDR:
-			if(!suser())
+			if(!capable(CAP_NET_ADMIN))
 				return (-EPERM);
 			if(sa->sat_family != AF_APPLETALK)
 				return (-EINVAL);
@@ -1809,7 +1809,7 @@
 		 */
 		case SIOCADDRT:
 		case SIOCDELRT:
-			if(!suser())
+			if(!capable(CAP_NET_ADMIN))
 				return -EPERM;
 			return (atrtr_ioctl(cmd,(void *)arg));
 
diff -u --recursive --new-file v2.1.99/linux/net/core/dev.c linux/net/core/dev.c
--- v2.1.99/linux/net/core/dev.c	Sat May  2 14:19:54 1998
+++ linux/net/core/dev.c	Wed May  6 10:56:06 1998
@@ -321,7 +321,7 @@
 
 void dev_load(const char *name)
 {
-	if(!dev_get(name) && suser())
+	if(!dev_get(name) && capable(CAP_SYS_MODULE))
 		request_module(name);
 }
 
@@ -1591,7 +1591,7 @@
 		case SIOCDELMULTI:
 		case SIOCSIFHWBROADCAST:
 		case SIOCSIFTXQLEN:
-			if (!suser())
+			if (!capable(CAP_NET_ADMIN))
 				return -EPERM;
 			dev_load(ifr.ifr_name);
 			rtnl_lock();
@@ -1764,6 +1764,9 @@
 extern int lapbeth_init(void);
 extern void arcnet_init(void);
 extern void ip_auto_config(void);
+#ifdef CONFIG_8xx
+extern int cpm_enet_init(void);
+#endif /* CONFIG_8xx */
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry proc_net_dev = {
@@ -1845,6 +1848,9 @@
 #endif
 #if defined(CONFIG_ARCNET)
 	arcnet_init();
+#endif
+#if defined(CONFIG_8xx)
+        cpm_enet_init();
 #endif
 	/*
 	 *	SLHC if present needs attaching so other people see it
diff -u --recursive --new-file v2.1.99/linux/net/core/scm.c linux/net/core/scm.c
--- v2.1.99/linux/net/core/scm.c	Tue Mar 10 10:03:36 1998
+++ linux/net/core/scm.c	Wed May  6 10:56:08 1998
@@ -45,18 +45,15 @@
 
 static __inline__ int scm_check_creds(struct ucred *creds)
 {
-	/* N.B. The test for suser should follow the credential check */
-	if (suser())
+	if ((creds->pid == current->pid || capable(CAP_SYS_ADMIN)) &&
+	    ((creds->uid == current->uid || creds->uid == current->euid ||
+	      creds->uid == current->suid) || capable(CAP_SETUID)) &&
+	    ((creds->gid == current->gid || creds->gid == current->egid ||
+	      creds->gid == current->sgid) || capable(CAP_SETGID))) {
 		return 0;
-	if (creds->pid != current->pid ||
-	    (creds->uid != current->uid && creds->uid != current->euid &&
-	     creds->uid != current->suid) ||
-	    (creds->gid != current->gid && creds->gid != current->egid &&
-	     creds->gid != current->sgid))
-		return -EPERM;
-	return 0;
+	}
+	return -EPERM;
 }
-
 
 static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
 {
diff -u --recursive --new-file v2.1.99/linux/net/core/sock.c linux/net/core/sock.c
--- v2.1.99/linux/net/core/sock.c	Sat May  2 14:19:54 1998
+++ linux/net/core/sock.c	Wed May  6 10:56:06 1998
@@ -185,7 +185,7 @@
   	switch(optname) 
   	{
 		case SO_DEBUG:	
-			if(val && !suser())
+			if(val && !capable(CAP_NET_ADMIN))
 			{
 				ret = -EACCES;
 			}
@@ -924,7 +924,7 @@
 			 */
 			if (current->pgrp != -arg &&
 				current->pid != arg &&
-				!suser()) return(-EPERM);
+				!capable(CAP_NET_ADMIN)) return(-EPERM);
 			sk->proc = arg;
 			return(0);
 		case F_GETOWN:
diff -u --recursive --new-file v2.1.99/linux/net/ethernet/pe2.c linux/net/ethernet/pe2.c
--- v2.1.99/linux/net/ethernet/pe2.c	Sun Mar 24 22:58:24 1996
+++ linux/net/ethernet/pe2.c	Sat May  2 14:22:29 1998
@@ -11,7 +11,8 @@
 	struct device	*dev = skb->dev;
 
 	skb->protocol = htons (ETH_P_IPX);
-	dev->hard_header(skb, dev, ETH_P_IPX, dest_node, NULL, skb->len);
+	if(dev->hard_header)
+		dev->hard_header(skb, dev, ETH_P_IPX, dest_node, NULL, skb->len);
 }
 
 struct datalink_proto *
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.1.99/linux/net/ipv4/af_inet.c	Sat May  2 14:19:55 1998
+++ linux/net/ipv4/af_inet.c	Wed May  6 10:56:07 1998
@@ -374,7 +374,7 @@
 		sock->ops = &inet_dgram_ops;
 		break;
 	case SOCK_RAW:
-		if (!suser())
+		if (!capable(CAP_NET_RAW))
 			goto free_and_badperm;
 		if (!protocol)
 			goto free_and_noproto;
@@ -521,7 +521,7 @@
 #endif		 
 	if (snum == 0) 
 		snum = sk->prot->good_socknum();
-	if (snum < PROT_SOCK && !suser())
+	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
 		return(-EACCES);
 	
 	chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
@@ -529,7 +529,7 @@
 	    chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) {
 #ifdef CONFIG_IP_TRANSPARENT_PROXY
 		/* Superuser may bind to any address to allow transparent proxying. */
-		if(chk_addr_ret != RTN_UNICAST || !suser())
+		if(chk_addr_ret != RTN_UNICAST || !capable(CAP_NET_ADMIN))
 #endif
 			return -EADDRNOTAVAIL;	/* Source address MUST be ours! */
 	}
@@ -868,7 +868,8 @@
 			err = get_user(pid, (int *) arg);
 			if (err)
 				return err; 
-			if (current->pid != pid && current->pgrp != -pid && !suser())
+			if (current->pid != pid && current->pgrp != -pid && 
+			    !capable(CAP_NET_ADMIN))
 				return -EPERM;
 			sk->proc = pid;
 			return(0);
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/devinet.c linux/net/ipv4/devinet.c
--- v2.1.99/linux/net/ipv4/devinet.c	Wed Apr  1 20:11:55 1998
+++ linux/net/ipv4/devinet.c	Wed May  6 10:56:07 1998
@@ -435,7 +435,7 @@
 		break;
 
 	case SIOCSIFFLAGS:
-		if (!suser())
+		if (!capable(CAP_NET_ADMIN))
 			return -EACCES;
 		rtnl_lock();
 		exclusive = 1;
@@ -444,7 +444,7 @@
 	case SIOCSIFBRDADDR:	/* Set the broadcast address */
 	case SIOCSIFDSTADDR:	/* Set the destination address */
 	case SIOCSIFNETMASK: 	/* Set the netmask for the interface */
-		if (!suser())
+		if (!capable(CAP_NET_ADMIN))
 			return -EACCES;
 		if (sin->sin_family != AF_INET)
 			return -EINVAL;
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
--- v2.1.99/linux/net/ipv4/fib_frontend.c	Tue Mar 17 22:18:16 1998
+++ linux/net/ipv4/fib_frontend.c	Wed May  6 10:56:07 1998
@@ -253,7 +253,7 @@
 	switch (cmd) {
 	case SIOCADDRT:		/* Add a route */
 	case SIOCDELRT:		/* Delete a route */
-		if (!suser())
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		if (copy_from_user(&r, arg, sizeof(struct rtentry)))
 			return -EFAULT;
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- v2.1.99/linux/net/ipv4/ip_fw.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv4/ip_fw.c	Sat May  2 14:22:29 1998
@@ -6,7 +6,7 @@
  *	license in recognition of the original copyright. 
  *				-- Alan Cox.
  *
- *	$Id: ip_fw.c,v 1.34 1998/03/20 09:12:06 davem Exp $
+ *	$Id: ip_fw.c,v 1.35 1998/04/30 16:29:51 freitag Exp $
  *
  *	Ported from BSD to Linux,
  *		Alan Cox 22/Nov/1994.
@@ -62,6 +62,7 @@
  *	Wouter Gadeyne		:	Fixed masquerading support of ftp PORT commands
  *
  *	Juan Jose Ciarlante	:	Masquerading code moved to ip_masq.c
+ *	Andi Kleen :		Print frag_offsets and the ip flags properly.
  *
  *	All the real work was done by .....
  *
@@ -202,6 +203,90 @@
 
 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
 
+#ifdef CONFIG_IP_FIREWALL_VERBOSE
+
+/* 
+ *	VERY ugly piece of code which actually makes kernel printf for
+ * 	matching packets. 
+ */
+
+static char *chain_name(struct ip_fw *chain, int mode)
+{
+	switch (mode) { 
+	case IP_FW_MODE_ACCT_IN: return "acct in";
+	case IP_FW_MODE_ACCT_OUT: return "acct out";
+	default:
+		if (chain == ip_fw_fwd_chain) 
+			return "fw-fwd";
+		else if (chain == ip_fw_in_chain)
+			return "fw-in";
+		else
+			return "fw-out"; 
+	}
+}
+
+static char *rule_name(struct ip_fw *f, int mode, char *buf)
+{
+	if (mode == IP_FW_MODE_ACCT_IN || mode == IP_FW_MODE_ACCT_OUT)
+		return "";
+
+	if(f->fw_flg&IP_FW_F_ACCEPT) {
+		if(f->fw_flg&IP_FW_F_REDIR) {
+			sprintf(buf, "acc/r%d ", f->fw_pts[f->fw_nsp+f->fw_ndp]);
+			return buf;
+		} else if(f->fw_flg&IP_FW_F_MASQ)
+			return "acc/masq ";
+		else
+			return "acc ";
+	} else if(f->fw_flg&IP_FW_F_ICMPRPL) {
+		return "rej ";
+	} else {
+		return "deny ";
+	}
+}
+
+static void print_packet(struct iphdr *ip, 
+			 u16 src_port, u16 dst_port, u16 icmp_type,
+			 char *chain, char *rule, char *devname)
+{
+	__u32 *opt = (__u32 *) (ip + 1);
+	int opti;
+	__u16 foff = ntohs(ip->frag_off); 
+
+	printk(KERN_INFO "IP %s %s%s", chain, rule, devname); 
+
+	switch(ip->protocol)
+	{
+	case IPPROTO_TCP:
+		printk(" TCP ");
+		break;
+	case IPPROTO_UDP:
+		printk(" UDP ");
+		break;
+	case IPPROTO_ICMP:
+		printk(" ICMP/%d ", icmp_type);
+		break;
+	default:
+		printk(" PROTO=%d ", ip->protocol);
+		break;
+	}
+	print_ip(ip->saddr);
+	if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
+		printk(":%hu", src_port);
+	printk(" ");
+	print_ip(ip->daddr);
+	if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
+		printk(":%hu", dst_port);
+	printk(" L=%hu S=0x%2.2hX I=%hu FO=0x%4.4hX T=%hu",
+	       ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
+	       foff & IP_OFFSET, ip->ttl); 
+	if (foff & IP_DF) printk(" DF=1");
+	if (foff & IP_MF) printk(" MF=1"); 
+	for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
+		printk(" O=0x%8.8X", *opt++);
+	printk("\n");	
+}
+#endif
 
 /*
  *	Returns one of the generic firewall policies, like FW_ACCEPT.
@@ -483,68 +568,14 @@
 		}
 
 #ifdef CONFIG_IP_FIREWALL_VERBOSE
-		/*
-		 * VERY ugly piece of code which actually
-		 * makes kernel printf for matching packets...
-		 */
-
 		if (f->fw_flg & IP_FW_F_PRN)
 		{
-			__u32 *opt = (__u32 *) (ip + 1);
-			int opti;
+			char buf[16]; 
 
-			if(mode == IP_FW_MODE_ACCT_IN)
-				printk(KERN_INFO "IP acct in ");
-			else if(mode == IP_FW_MODE_ACCT_OUT)
-				printk(KERN_INFO "IP acct out ");
-			else {
-				if(chain == ip_fw_fwd_chain)
-					printk(KERN_INFO "IP fw-fwd ");
-				else if(chain == ip_fw_in_chain)
-					printk(KERN_INFO "IP fw-in ");
-				else
-					printk(KERN_INFO "IP fw-out ");
-				if(f->fw_flg&IP_FW_F_ACCEPT) {
-					if(f->fw_flg&IP_FW_F_REDIR)
-						printk("acc/r%d ", f->fw_pts[f->fw_nsp+f->fw_ndp]);
-					else if(f->fw_flg&IP_FW_F_MASQ)
-						printk("acc/masq ");
-					else
-						printk("acc ");
-				} else if(f->fw_flg&IP_FW_F_ICMPRPL)
-					printk("rej ");
-				else
-					printk("deny ");
-			}
-			printk(rif ? rif->name : "-");
-			switch(ip->protocol)
-			{
-				case IPPROTO_TCP:
-					printk(" TCP ");
-					break;
-				case IPPROTO_UDP:
-					printk(" UDP ");
-					break;
-				case IPPROTO_ICMP:
-					printk(" ICMP/%d ", icmp_type);
-					break;
-				default:
-					printk(" PROTO=%d ", ip->protocol);
-					break;
-			}
-			print_ip(ip->saddr);
-			if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
-				printk(":%hu", src_port);
-			printk(" ");
-			print_ip(ip->daddr);
-			if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
-				printk(":%hu", dst_port);
-			printk(" L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
-				ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
-				ip->frag_off, ip->ttl);
-			for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
-				printk(" O=0x%8.8X", *opt++);
-			printk("\n");
+			print_packet(ip, src_port, dst_port, icmp_type,
+				     chain_name(chain, mode), 
+				     rule_name(f, mode, buf), 
+				     rif ? rif->name : "-");
 		}
 #endif		
 		if (mode != IP_FW_MODE_CHK) {
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/ip_sockglue.c linux/net/ipv4/ip_sockglue.c
--- v2.1.99/linux/net/ipv4/ip_sockglue.c	Tue Mar 17 22:18:16 1998
+++ linux/net/ipv4/ip_sockglue.c	Wed May  6 10:56:07 1998
@@ -311,7 +311,8 @@
 			  /* Reject setting of unused bits */
 			if (val & ~(IPTOS_TOS_MASK|IPTOS_PREC_MASK))
 				return -EINVAL;
-			if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && !suser())
+			if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && 
+			    !capable(CAP_NET_ADMIN))
 				return -EPERM;
 			if (sk->ip_tos != val) {
 				sk->ip_tos=val;
@@ -453,7 +454,7 @@
 		case IP_FW_POLICY_OUT:
 		case IP_FW_POLICY_FWD:
 		case IP_FW_MASQ_TIMEOUTS:
-			if(!suser())
+			if(!capable(CAP_NET_ADMIN))
 				return -EACCES;
 			if(optlen>sizeof(tmp_fw) || optlen<1)
 				return -EINVAL;
@@ -467,7 +468,7 @@
 		case IP_FW_MASQ_ADD:
 		case IP_FW_MASQ_DEL:
 		case IP_FW_MASQ_FLUSH:
-			if(!suser())
+			if(!capable(CAP_NET_ADMIN))
 				return -EPERM;
 			if(optlen>sizeof(masq_ctl) || optlen<1)
 				return -EINVAL;
@@ -483,7 +484,7 @@
 		case IP_ACCT_DELETE:
 		case IP_ACCT_FLUSH:
 		case IP_ACCT_ZERO:
-			if(!suser())
+			if(!capable(CAP_NET_ADMIN))
 				return -EACCES;
 			if(optlen>sizeof(tmp_fw) || optlen<1)
 				return -EINVAL;
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- v2.1.99/linux/net/ipv4/raw.c	Tue Mar 17 22:18:16 1998
+++ linux/net/ipv4/raw.c	Wed May  6 10:56:07 1998
@@ -398,7 +398,7 @@
 	   chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) {
 #ifdef CONFIG_IP_TRANSPARENT_PROXY
 		/* Superuser may bind to any address to allow transparent proxying. */
-		if(chk_addr_ret != RTN_UNICAST || !suser())
+		if(chk_addr_ret != RTN_UNICAST || !capable(CAP_NET_ADMIN))
 #endif
 			return -EADDRNOTAVAIL;
 	}
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.1.99/linux/net/ipv4/tcp_input.c	Sat May  2 14:19:55 1998
+++ linux/net/ipv4/tcp_input.c	Sat May  2 14:22:29 1998
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_input.c,v 1.114 1998/04/28 06:42:22 davem Exp $
+ * Version:	$Id: tcp_input.c,v 1.116 1998/05/02 14:50:11 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -421,33 +421,6 @@
 	return 1;
 }
 
-#if 0 /* Not working yet... -DaveM */
-static void tcp_compute_tsack(struct sock *sk, struct tcp_opt *tp)
-{
-	struct sk_buff *skb = skb_peek(&sk->write_queue);
-	__u32 tstamp = tp->rcv_tsecr;
-	int fack_count = 0;
-
-	while((skb != NULL) &&
-	      (skb != tp->send_head) &&
-	      (skb != (struct sk_buff *)&sk->write_queue)) {
-		if(TCP_SKB_CB(skb)->when == tstamp) {
-			__u8 sacked = TCP_SKB_CB(skb)->sacked;
-
-			sacked |= TCPCB_SACKED_ACKED;
-			if(sacked & TCPCB_SACKED_RETRANS)
-				tp->retrans_out--;
-			TCP_SKB_CB(skb)->sacked = sacked;
-		}
-		if(!before(TCP_SKB_CB(skb)->when, tstamp))
-			fack_count++;
-		skb = skb->next;
-	}
-	if(fack_count > tp->fackets_out)
-		tp->fackets_out = fack_count;
-}
-#endif
-
 #define FLAG_DATA		0x01 /* Incoming frame contained data.		*/
 #define FLAG_WIN_UPDATE		0x02 /* Incoming ACK was a window update.	*/
 #define FLAG_DATA_ACKED		0x04 /* This ACK acknowledged new data.		*/
@@ -481,13 +454,6 @@
 	if (ack == tp->snd_una && tp->packets_out && (not_dup == 0)) {
 		/* This is the standard reno style fast retransmit branch. */
 
-#if 0	/* Not working yet... -DaveM */
-		/* If not doing SACK, but doing timestamps, compute timestamp
-		 * based pseudo-SACKs when we see duplicate ACKs.
-		 */
-		if(!tp->sack_ok && tp->saw_tstamp)
-			tcp_compute_tsack(sk, tp);
-#endif
                 /* 1. When the third duplicate ack is received, set ssthresh 
                  * to one half the current congestion window, but no less 
                  * than two segments. Retransmit the missing segment.
@@ -611,6 +577,7 @@
 
 	while((skb=skb_peek(&sk->write_queue)) && (skb != tp->send_head)) {
 		struct tcp_skb_cb *scb = TCP_SKB_CB(skb); 
+		__u8 sacked = scb->sacked;
 		
 		/* If our packet is before the ack sequence we can
 		 * discard it as it's confirmed to have arrived at
@@ -626,22 +593,12 @@
 		 * connection startup slow start one packet too
 		 * quickly.  This is severely frowned upon behavior.
 		 */
+		if(sacked & TCPCB_SACKED_RETRANS && tp->retrans_out)
+			tp->retrans_out--;
 		if(!(scb->flags & TCPCB_FLAG_SYN)) {
-			__u8 sacked = scb->sacked;
-
 			acked |= FLAG_DATA_ACKED;
-			if(sacked & TCPCB_SACKED_RETRANS) {
+			if(sacked & TCPCB_SACKED_RETRANS)
 				acked |= FLAG_RETRANS_DATA_ACKED;
-
-				/* XXX The race is, fast retrans frame -->
-				 * XXX retrans timeout sends older frame -->
-				 * XXX ACK arrives for fast retrans frame -->
-				 * XXX retrans_out goes negative --> splat.
-				 * XXX Please help me find a better way -DaveM
-				 */
-				if(tp->retrans_out)
-					tp->retrans_out--;
-			}
 			if(tp->fackets_out)
 				tp->fackets_out--;
 		} else {
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.1.99/linux/net/ipv4/tcp_ipv4.c	Sat May  2 14:19:55 1998
+++ linux/net/ipv4/tcp_ipv4.c	Sat May  2 14:22:29 1998
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_ipv4.c,v 1.142 1998/04/30 12:00:45 davem Exp $
+ * Version:	$Id: tcp_ipv4.c,v 1.145 1998/05/02 12:47:13 davem Exp $
  *
  *		IPv4 specific functions
  *
@@ -48,7 +48,6 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/stddef.h>
 #include <linux/fcntl.h>
 #include <linux/random.h>
 #include <linux/init.h>
@@ -61,12 +60,15 @@
 #include <asm/segment.h>
 
 #include <linux/inet.h>
+#include <linux/stddef.h>
 
 extern int sysctl_tcp_timestamps;
 extern int sysctl_tcp_window_scaling;
 extern int sysctl_tcp_sack;
 extern int sysctl_tcp_syncookies;
 extern int sysctl_ip_dynaddr;
+extern __u32 sysctl_wmem_max;
+extern __u32 sysctl_rmem_max;
 
 /* Check TCP sequence numbers in ICMP packets. */
 #define ICMP_MIN_LENGTH 8
@@ -166,17 +168,21 @@
 	return tb;
 }
 
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
 /* Ensure that the bound bucket for the port exists.
  * Return 0 on success.
  */
 static __inline__ int tcp_bucket_check(unsigned short snum)
 {
-	if (tcp_bound_hash[tcp_bhashfn(snum)] == NULL &&
-			tcp_bucket_create(snum) == NULL)
+	struct tcp_bind_bucket *tb = tcp_bound_hash[tcp_bhashfn(snum)];
+	for( ; (tb && (tb->port != snum)); tb = tb->next)
+		;
+	if(tb == NULL && tcp_bucket_create(snum) == NULL)
 		return 1;
 	else
 		return 0;
 }
+#endif
 
 static int tcp_v4_verify_bind(struct sock *sk, unsigned short snum)
 {
@@ -215,10 +221,21 @@
 				result = 1;
 		}
 	}
-	if((result == 0) &&
-	   (tb == NULL) &&
-	   (tcp_bucket_create(snum) == NULL))
-		result = 1;
+	if(result == 0) {
+		if(tb == NULL) {
+			if(tcp_bucket_create(snum) == NULL)
+				result = 1;
+		} else {
+			/* It could be pending garbage collection, this
+			 * kills the race and prevents it from disappearing
+			 * out from under us by the time we use it.  -DaveM
+			 */
+			if(tb->owners == NULL && !(tb->flags & TCPB_FLAG_LOCKED)) {
+				tb->flags = TCPB_FLAG_LOCKED;
+				tcp_dec_slow_timer(TCP_SLT_BUCKETGC);
+			}
+		}
+	}
 go_like_smoke:
 	SOCKHASH_UNLOCK();
 	return result;
@@ -1308,6 +1325,11 @@
 	if (!newsk) 
 		goto exit;
 
+	if (newsk->rcvbuf < (3 * newsk->mtu))
+		newsk->rcvbuf = min ((3 * newsk->mtu), sysctl_rmem_max);
+	if (newsk->sndbuf < (3 * newsk->mtu))
+		newsk->sndbuf = min ((3 * newsk->mtu), sysctl_wmem_max);
+ 
 	sk->tp_pinfo.af_tcp.syn_backlog--;
 	sk->ack_backlog++;
 
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.1.99/linux/net/ipv4/tcp_timer.c	Sat May  2 14:19:55 1998
+++ linux/net/ipv4/tcp_timer.c	Sat May  2 14:22:29 1998
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_timer.c,v 1.50 1998/04/14 09:08:59 davem Exp $
+ * Version:	$Id: tcp_timer.c,v 1.51 1998/05/02 15:19:26 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -448,26 +448,24 @@
 	 */
 	if(tp->sack_ok) {
 		struct sk_buff *skb = skb_peek(&sk->write_queue);
-		__u8 toclear = TCPCB_SACKED_ACKED;
 
-		if(tp->retransmits == 0)
-			toclear |= TCPCB_SACKED_RETRANS;
 		while((skb != NULL) &&
 		      (skb != tp->send_head) &&
 		      (skb != (struct sk_buff *)&sk->write_queue)) {
-			TCP_SKB_CB(skb)->sacked &= ~(toclear);
+			TCP_SKB_CB(skb)->sacked &=
+				~(TCPCB_SACKED_ACKED | TCPCB_SACKED_RETRANS);
 			skb = skb->next;
 		}
-		tp->fackets_out = 0;
 	}
 
 	/* Retransmission. */
 	tp->retrans_head = NULL;
+	tp->fackets_out = 0;
+	tp->retrans_out = 0;
 	if (tp->retransmits == 0) {
 		/* remember window where we lost
 		 * "one half of the current window but at least 2 segments"
 		 */
-		tp->retrans_out = 0;
 		tp->snd_ssthresh = max(tp->snd_cwnd >> (1 + TCP_CWND_SHIFT), 2);
 		tp->snd_cwnd = (1 << TCP_CWND_SHIFT);
 	}
diff -u --recursive --new-file v2.1.99/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- v2.1.99/linux/net/ipv4/udp.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv4/udp.c	Wed May  6 10:56:07 1998
@@ -646,7 +646,7 @@
 #ifdef CONFIG_IP_TRANSPARENT_PROXY
 	if (msg->msg_flags&~(MSG_DONTROUTE|MSG_DONTWAIT|MSG_PROXY|MSG_NOSIGNAL))
 	  	return -EINVAL;
-	if ((msg->msg_flags&MSG_PROXY) && !suser() )
+	if ((msg->msg_flags&MSG_PROXY) && !capable(CAP_NET_ADMIN))
 	  	return -EPERM;
 #else
 	if (msg->msg_flags&~(MSG_DONTROUTE|MSG_DONTWAIT|MSG_NOSIGNAL))
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/addrconf.c linux/net/ipv6/addrconf.c
--- v2.1.99/linux/net/ipv6/addrconf.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv6/addrconf.c	Wed May  6 10:56:08 1998
@@ -894,7 +894,7 @@
 	struct in6_ifreq ireq;
 	int err;
 	
-	if (!suser())
+	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 	
 	if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
@@ -911,7 +911,7 @@
 	struct in6_ifreq ireq;
 	int err;
 	
-	if (!suser())
+	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 
 	if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.1.99/linux/net/ipv6/af_inet6.c	Wed Apr  1 20:11:55 1998
+++ linux/net/ipv6/af_inet6.c	Wed May  6 10:56:08 1998
@@ -89,7 +89,7 @@
 		prot=&udpv6_prot;
 		sock->ops = &inet6_dgram_ops;
 	} else if(sock->type == SOCK_RAW) {
-		if (!suser()) 
+		if (!capable(CAP_NET_RAW))
 			goto free_and_badperm;
 		if (!protocol) 
 			goto free_and_noproto;
@@ -187,7 +187,7 @@
 	snum = ntohs(addr->sin6_port);
 	if (snum == 0) 
 		snum = sk->prot->good_socknum();
-	if (snum < PROT_SOCK && !suser()) 
+	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
 		return(-EACCES);
 	
 	addr_type = ipv6_addr_type(&addr->sin6_addr);
@@ -291,7 +291,8 @@
 			return err;
 
 		/* see sock_no_fcntl */
-		if (current->pid != pid && current->pgrp != -pid && !suser())
+		if (current->pid != pid && current->pgrp != -pid && 
+		    !capable(CAP_NET_ADMIN))
 			return -EPERM;
 		sk->proc = pid;
 		return(0);
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/exthdrs.c linux/net/ipv6/exthdrs.c
--- v2.1.99/linux/net/ipv6/exthdrs.c	Tue Mar 17 22:18:16 1998
+++ linux/net/ipv6/exthdrs.c	Sat May  2 14:22:29 1998
@@ -4,8 +4,9 @@
  *
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>
+ *	Andi Kleen		<ak@muc.de>
  *
- *	$Id: exthdrs.c,v 1.5 1998/02/12 07:43:39 davem Exp $
+ *	$Id: exthdrs.c,v 1.6 1998/04/30 16:24:20 freitag Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -34,6 +35,10 @@
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
 
+#include <asm/uaccess.h>
+
+#define swap(a,b) do { typeof (a) tmp; tmp = (a); (a) = (b); (b) = (tmp); } while(0)
+
 /*
  *	inbound
  */
@@ -135,7 +140,7 @@
  */
 
 int ipv6opt_bld_rthdr(struct sk_buff *skb, struct ipv6_options *opt,
-		      struct in6_addr *addr, int proto)		      
+		      struct in6_addr *addr)		      
 {
 	struct rt0_hdr *phdr, *ihdr;
 	int hops;
@@ -153,8 +158,76 @@
 
 	ipv6_addr_copy(phdr->addr + (hops - 1), addr);
 	
-	phdr->rt_hdr.nexthdr = proto;
-
+	phdr->rt_hdr.nexthdr = proto; 
 	return NEXTHDR_ROUTING;
 }
 #endif
+
+/* 
+ * find out if nexthdr is an extension header or a protocol
+ */
+
+static __inline__ int ipv6_ext_hdr(u8 nexthdr)
+{
+	/* 
+	 * find out if nexthdr is an extension header or a protocol
+	 */
+	return ( (nexthdr == NEXTHDR_HOP)	||
+		 (nexthdr == NEXTHDR_ROUTING)	||
+		 (nexthdr == NEXTHDR_FRAGMENT)	||
+		 (nexthdr == NEXTHDR_ESP)	||
+		 (nexthdr == NEXTHDR_AUTH)	||
+		 (nexthdr == NEXTHDR_NONE)	||
+		 (nexthdr == NEXTHDR_DEST) );
+		 
+}
+
+/*
+ * Skip any extension headers. This is used by the ICMP module.
+ *
+ * Note that strictly speaking this conflicts with RFC1883 4.0:
+ * ...The contents and semantics of each extension header determine whether 
+ * or not to proceed to the next header.  Therefore, extension headers must
+ * be processed strictly in the order they appear in the packet; a
+ * receiver must not, for example, scan through a packet looking for a
+ * particular kind of extension header and process that header prior to
+ * processing all preceding ones.
+ * 
+ * We do exactly this. This is a protocol bug. We can't decide after a
+ * seeing an unknown discard-with-error flavour TLV option if it's a 
+ * ICMP error message or not (errors should never be send in reply to
+ * ICMP error messages).
+ * 
+ * But I see no other way to do this. This might need to be reexamined
+ * when Linux implements ESP (and maybe AUTH) headers.
+ */
+struct ipv6_opt_hdr *ipv6_skip_exthdr(struct ipv6_opt_hdr *hdr, 
+				      u8 *nexthdrp, int len)
+{
+	u8 nexthdr = *nexthdrp;
+
+	while (ipv6_ext_hdr(nexthdr)) {
+		int hdrlen; 
+		
+		if (nexthdr == NEXTHDR_NONE)
+			return NULL;
+		if (len < sizeof(struct ipv6_opt_hdr)) /* be anal today */
+			return NULL;
+
+		hdrlen = ipv6_optlen(hdr); 
+		if (len < hdrlen)
+			return NULL; 
+
+		nexthdr = hdr->nexthdr;
+		hdr = (struct ipv6_opt_hdr *) ((u8*)hdr + hdrlen);
+		len -= hdrlen;
+	}
+
+	/* Hack.. Do the same for AUTH headers? */
+	if (nexthdr == NEXTHDR_ESP) 
+		return NULL; 
+
+	*nexthdrp = nexthdr;
+	return hdr;
+}
+
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/icmp.c linux/net/ipv6/icmp.c
--- v2.1.99/linux/net/ipv6/icmp.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv6/icmp.c	Sat May  2 14:22:30 1998
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>
  *
- *	$Id: icmp.c,v 1.15 1998/03/21 07:28:03 davem Exp $
+ *	$Id: icmp.c,v 1.17 1998/05/01 10:31:41 davem Exp $
  *
  *	Based on net/ipv4/icmp.c
  *
@@ -21,6 +21,8 @@
  *	Changes:
  *
  *	Andi Kleen		:	exception handling
+ *	Andi Kleen			add rate limits. never reply to a icmp.
+ *					add more length checks and other fixes.
  */
 
 #define __NO_VERSION__
@@ -51,6 +53,7 @@
 #include <net/transp_v6.h>
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
+#include <net/icmp.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -129,6 +132,62 @@
 	return 0; 
 }
 
+
+/* 
+ * Slightly more convenient version of icmpv6_send.
+ */
+void icmpv6_param_prob(struct sk_buff *skb, int code, void *pos)
+{
+	int offset = (u8*)pos - (u8*)skb->nh.ipv6h; 
+	
+	icmpv6_send(skb, ICMPV6_PARAMPROB, code, offset, skb->dev);
+	kfree_skb(skb);
+}
+
+static inline int is_icmp(struct ipv6hdr *hdr, int len)
+{
+	__u8 nexthdr = hdr->nexthdr; 
+
+	if (!ipv6_skip_exthdr((struct ipv6_opt_hdr *)(hdr+1), &nexthdr, len))
+		return 0; 
+	return nexthdr == IPPROTO_ICMP; 
+}
+
+int sysctl_icmpv6_time = 1*HZ; 
+
+/* 
+ * Check the ICMP output rate limit 
+ */
+static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
+				     struct flowi *fl)
+{
+#if 0
+	struct dst_entry *dst; 
+	int allow = 0;
+#endif
+	/* Informational messages are not limited. */
+	if (type & 0x80)
+		return 1; 
+
+#if 0 /* not yet, first fix routing COW */
+
+	/* 
+	 * Look up the output route.
+	 * XXX: perhaps the expire for routing entries cloned by
+	 * this lookup should be more aggressive (not longer than timeout).
+	 */
+	dst = ip6_route_output(sk, fl, 1);
+	if (dst->error) 
+		ipv6_statistics.Ip6OutNoRoutes++;
+	else 
+		allow = xrlim_allow(dst, sysctl_icmpv6_time);
+	dst_release(dst);
+	return allow;
+#else
+	return 1;
+#endif
+}
+
 /*
  *	an inline helper for the "simple" if statement below
  *	checks if parameter problem report is caused by an
@@ -214,6 +273,24 @@
 		return;
 	}
 
+	/* 
+	 *	Never answer to a ICMP packet.
+	 */
+	if (is_icmp(hdr, (u8*)skb->tail - (u8*)hdr)) {
+		printk(KERN_DEBUG "icmpv6_send: no reply to icmp\n"); 
+		return;
+	}
+
+	fl.proto = IPPROTO_ICMPV6;
+	fl.nl_u.ip6_u.daddr = &hdr->saddr;
+	fl.nl_u.ip6_u.saddr = saddr;
+	fl.oif = iif;
+	fl.uli_u.icmpt.type = type;
+	fl.uli_u.icmpt.code = code;
+
+	if (!icmpv6_xrlim_allow(sk, type, &fl)) 
+		return; 
+
 	/*
 	 *	ok. kick it. checksum will be provided by the 
 	 *	getfrag_t callback.
@@ -248,13 +325,6 @@
 
 	msg.len = len;
 
-	fl.proto = IPPROTO_ICMPV6;
-	fl.nl_u.ip6_u.daddr = &hdr->saddr;
-	fl.nl_u.ip6_u.saddr = saddr;
-	fl.oif = iif;
-	fl.uli_u.icmpt.type = type;
-	fl.uli_u.icmpt.code = code;
-
 	ip6_build_xmit(sk, icmpv6_getfrag, &msg, &fl, len, NULL, -1,
 		       MSG_DONTWAIT);
 
@@ -312,21 +382,6 @@
 	dst_release(xchg(&sk->dst_cache, NULL));
 }
 
-static __inline__ int ipv6_ext_hdr(u8 nexthdr)
-{
-	/* 
-	 * find out if nexthdr is an extension header or a protocol
-	 */
-	return ( (nexthdr == NEXTHDR_HOP)	||
-		 (nexthdr == NEXTHDR_ROUTING)	||
-		 (nexthdr == NEXTHDR_FRAGMENT)	||
-		 (nexthdr == NEXTHDR_ESP)	||
-		 (nexthdr == NEXTHDR_AUTH)	||
-		 (nexthdr == NEXTHDR_NONE)	||
-		 (nexthdr == NEXTHDR_DEST) );
-		 
-}
-
 static void icmpv6_notify(struct sk_buff *skb,
 			  int type, int code, unsigned char *buff, int len,
 			  struct in6_addr *saddr, struct in6_addr *daddr, 
@@ -335,39 +390,22 @@
 	struct ipv6hdr *hdr = (struct ipv6hdr *) buff;
 	struct inet6_protocol *ipprot;
 	struct sock *sk;
-	char * pbuff;
+	struct ipv6_opt_hdr *pb;
 	__u32 info = 0;
 	int hash;
 	u8 nexthdr;
 
-	/* now skip over extension headers */
-
 	nexthdr = hdr->nexthdr;
 
-	pbuff = (char *) (hdr + 1);
+	pb = (struct ipv6_opt_hdr *) (hdr + 1);
 	len -= sizeof(struct ipv6hdr);
+	if (len < 0)
+		return;
 
-	while (ipv6_ext_hdr(nexthdr)) {
-		int hdrlen;
-
-		if (nexthdr == NEXTHDR_NONE)
-			return;
-
-		nexthdr = *pbuff;
-
-		/* Header length is size in 8-octet units, not
-		 * including the first 8 octets.
-		 */
-		hdrlen = *(pbuff+1);
-		hdrlen = (hdrlen + 1) << 3;
-
-		if (hdrlen > len)
-			return;
-		
-		/* Now this is right. */
-		pbuff += hdrlen;
-		len -= hdrlen;
-	}
+	/* now skip over extension headers */
+	pb = ipv6_skip_exthdr(pb, &nexthdr, len);
+	if (!pb)
+		return;
 
 	hash = nexthdr & (MAX_INET_PROTOS - 1);
 
@@ -378,7 +416,7 @@
 			continue;
 
 		if (ipprot->err_handler) 
-			ipprot->err_handler(skb, type, code, pbuff, info,
+			ipprot->err_handler(skb, type, code, (u8*)pb, info,
 					    saddr, daddr, ipprot);
 		return;
 	}
@@ -391,7 +429,7 @@
 		return;
 
 	while((sk = raw_v6_lookup(sk, nexthdr, daddr, saddr))) {
-		rawv6_err(sk, type, code, pbuff, saddr, daddr);
+		rawv6_err(sk, type, code, (char*)pb, saddr, daddr);
 		sk = sk->next;
 	}
 }
@@ -514,7 +552,7 @@
 	return 0;
 }
 
-__initfunc(void icmpv6_init(struct net_proto_family *ops))
+__initfunc(int icmpv6_init(struct net_proto_family *ops))
 {
 	struct sock *sk;
 	int err;
@@ -528,11 +566,11 @@
 	icmpv6_socket->state = SS_UNCONNECTED;
 	icmpv6_socket->type=SOCK_RAW;
 
-	if((err=ops->create(icmpv6_socket, IPPROTO_ICMPV6))<0)
+	if((err=ops->create(icmpv6_socket, IPPROTO_ICMPV6))<0) {
 		printk(KERN_DEBUG 
 		       "Failed to create the ICMP6 control socket.\n");
-
-	MOD_DEC_USE_COUNT;
+		return 1;
+	}
 
 	sk = icmpv6_socket->sk;
 	sk->allocation = GFP_ATOMIC;
@@ -542,6 +580,16 @@
 
 	ndisc_init(ops);
 	igmp6_init(ops);
+	return 0; 
+}
+
+void icmpv6_cleanup(void)
+{
+	inet6_del_protocol(&icmpv6_protocol);
+#if 0
+	ndisc_cleanup();
+#endif
+	igmp6_cleanup();
 }
 
 static struct icmp6_err {
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/ip6_input.c linux/net/ipv6/ip6_input.c
--- v2.1.99/linux/net/ipv6/ip6_input.c	Tue Mar 17 22:18:16 1998
+++ linux/net/ipv6/ip6_input.c	Sat May  2 14:22:30 1998
@@ -6,7 +6,7 @@
  *	Pedro Roque		<roque@di.fc.ul.pt>
  *	Ian P. Morris		<I.P.Morris@soton.ac.uk>
  *
- *	$Id: ip6_input.c,v 1.8 1998/02/12 07:43:43 davem Exp $
+ *	$Id: ip6_input.c,v 1.9 1998/04/30 16:24:24 freitag Exp $
  *
  *	Based in linux/net/ipv4/ip_input.c
  *
@@ -69,12 +69,6 @@
 	u8 type;
 	u8 len;
 };
-
-struct ipv6_destopt_hdr {
-	u8 nexthdr;
-	u8 hdrlen;
-};
-
 
 struct tlvtype_proc {
 	u8	type;
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/ipv6_sockglue.c linux/net/ipv6/ipv6_sockglue.c
--- v2.1.99/linux/net/ipv6/ipv6_sockglue.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv6/ipv6_sockglue.c	Sat May  2 14:22:30 1998
@@ -7,7 +7,7 @@
  *
  *	Based on linux/net/ipv4/ip_sockglue.c
  *
- *	$Id: ipv6_sockglue.c,v 1.18 1998/03/20 09:12:18 davem Exp $
+ *	$Id: ipv6_sockglue.c,v 1.19 1998/04/30 16:24:26 freitag Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -242,7 +242,7 @@
 	ipv6_sysctl_unregister();	
 #endif
 	ip6_route_cleanup();
-	ndisc_cleanup();
+	icmpv6_cleanup();
 	addrconf_cleanup();	
 }
 #endif
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/mcast.c linux/net/ipv6/mcast.c
--- v2.1.99/linux/net/ipv6/mcast.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv6/mcast.c	Sat May  2 14:22:30 1998
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: mcast.c,v 1.14 1998/03/20 09:12:18 davem Exp $
+ *	$Id: mcast.c,v 1.15 1998/04/30 16:24:28 freitag Exp $
  *
  *	Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c 
  *
@@ -619,8 +619,6 @@
 		printk(KERN_DEBUG 
 		       "Failed to create the IGMP6 control socket.\n");
 
-	MOD_DEC_USE_COUNT;
-
 	sk = igmp6_socket->sk;
 	sk->allocation = GFP_ATOMIC;
 	sk->num = 256;			/* Don't receive any data */
@@ -632,3 +630,9 @@
 #endif
 }
 
+void igmp6_cleanup(void)
+{
+#ifdef CONFIG_PROC_FS
+	remove_proc_entry("net/igmp6", 0); 
+#endif
+}
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/ndisc.c linux/net/ipv6/ndisc.c
--- v2.1.99/linux/net/ipv6/ndisc.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv6/ndisc.c	Sat May  2 14:22:30 1998
@@ -1152,9 +1152,6 @@
 		printk(KERN_DEBUG 
 		       "Failed to create the NDISC control socket.\n");
 
-	/* Eeeh... What is it? --ANK */
-	MOD_DEC_USE_COUNT;
-
 	sk = ndisc_socket->sk;
 	sk->allocation = GFP_ATOMIC;
 	sk->net_pinfo.af_inet6.hop_limit = 255;
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/reassembly.c linux/net/ipv6/reassembly.c
--- v2.1.99/linux/net/ipv6/reassembly.c	Tue Mar 17 22:18:16 1998
+++ linux/net/ipv6/reassembly.c	Sat May  2 14:22:30 1998
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: reassembly.c,v 1.9 1998/02/12 07:43:48 davem Exp $
+ *	$Id: reassembly.c,v 1.10 1998/04/30 16:24:32 freitag Exp $
  *
  *	Based on: net/ipv4/ip_fragment.c
  *
@@ -15,6 +15,11 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+/* 
+ *	Fixes:	
+ *	Andi Kleen	Make it work with multiple hosts.
+ *			More RFC compliance.
+ */
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
@@ -39,8 +44,9 @@
 
 static struct frag_queue ipv6_frag_queue = {
 	&ipv6_frag_queue, &ipv6_frag_queue,
-	0, {0}, NULL, NULL,
-	0
+	0, {{{0}}}, {{{0}}},
+	{0}, NULL, NULL,
+	0, 0, NULL
 };
 
 static void			create_frag_entry(struct sk_buff *skb, 
@@ -72,12 +78,11 @@
 	 *	one it's the kmalloc for a struct ipv6_frag.
 	 *	Feel free to try other alternatives...
 	 */
-	reasm_queue(fq, *skb, fhdr);
-
 	if ((fhdr->frag_off & __constant_htons(0x0001)) == 0) {
 		fq->last_in = 1;
 		fq->nhptr = nhptr;
 	}
+	reasm_queue(fq, *skb, fhdr);
 
 	if (fq->last_in) {
 		if ((nh = reasm_frag_1(fq, skb)))
@@ -90,18 +95,27 @@
 	return 0;
 }
 
-int ipv6_reassembly(struct sk_buff **skb, struct device *dev, __u8 *nhptr,
+int ipv6_reassembly(struct sk_buff **skbp, struct device *dev, __u8 *nhptr,
 		    struct ipv6_options *opt)
 {
-	struct frag_hdr *fhdr = (struct frag_hdr *) ((*skb)->h.raw);
+	struct sk_buff *skb = *skbp; 
+	struct frag_hdr *fhdr = (struct frag_hdr *) (skb->h.raw);
 	struct frag_queue *fq;
-	
+	struct ipv6hdr *hdr;
+
+	if ((u8 *)(fhdr+1) > skb->tail) {
+		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw);
+		return 0;
+	}
+	hdr = skb->nh.ipv6h;
 	for (fq = ipv6_frag_queue.next; fq != &ipv6_frag_queue; fq = fq->next) {
-		if (fq->id == fhdr->identification)
-			return reasm_frag(fq, skb, nhptr,fhdr);
+		if (fq->id == fhdr->identification && 
+		    !ipv6_addr_cmp(&hdr->saddr, &fq->saddr) &&
+		    !ipv6_addr_cmp(&hdr->daddr, &fq->daddr))
+			return reasm_frag(fq, skbp, nhptr,fhdr);
 	}
 	
-	create_frag_entry(*skb, dev, nhptr, fhdr);
+	create_frag_entry(skb, dev, nhptr, fhdr);
 
 	return 0;
 }
@@ -154,6 +168,7 @@
 			      struct frag_hdr *fhdr)
 {
 	struct frag_queue *fq;
+	struct ipv6hdr *hdr; 
 
 	fq = (struct frag_queue *) kmalloc(sizeof(struct frag_queue), 
 					   GFP_ATOMIC);
@@ -167,6 +182,10 @@
 
 	fq->id = fhdr->identification;
 
+	hdr = skb->nh.ipv6h;
+	ipv6_addr_copy(&fq->saddr, &hdr->saddr);
+	ipv6_addr_copy(&fq->daddr, &hdr->daddr);
+
 	fq->dev = dev;
 
 	/* init_timer has been done by the memset */
@@ -193,14 +212,14 @@
 
 
 static void reasm_queue(struct frag_queue *fq, struct sk_buff *skb, 
-			struct frag_hdr *fhdr)
+				     struct frag_hdr *fhdr)
 {
 	struct ipv6_frag *nfp, *fp, **bptr;
 
 	nfp = (struct ipv6_frag *) kmalloc(sizeof(struct ipv6_frag), 
 					   GFP_ATOMIC);
 
-	if (nfp == NULL) {
+	if (nfp == NULL) {		
 		kfree_skb(skb);
 		return;
 	}
@@ -209,6 +228,10 @@
 	nfp->len = (ntohs(skb->nh.ipv6h->payload_len) -
 		    ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
 
+	if ((u32)nfp->offset + (u32)nfp->len > 65536) {
+		icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off); 
+		goto err;
+	}
 
 	nfp->skb  = skb;
 	nfp->fhdr = fhdr;
@@ -224,19 +247,37 @@
 	}
 	
 	if (fp && fp->offset == nfp->offset) {
-		if (fp->len != nfp->len) {
-			/* this cannot happen */
+		if (nfp->len != fp->len) {
 			printk(KERN_DEBUG "reasm_queue: dup with wrong len\n");
 		}
 
 		/* duplicate. discard it. */
-		kfree_skb(skb);
-		kfree(nfp);
-		return;
+		goto err;
 	}
 	
 	*bptr = nfp;
 	nfp->next = fp;
+
+#ifdef STRICT_RFC
+	if (fhdr->frag_off & __constant_htons(0x0001)) {
+		/* Check if the fragment is rounded to 8 bytes.
+		 * Required by the RFC.
+		 */
+		if (nfp->len & 0x7) {
+			printk(KERN_DEBUG "fragment not rounded to 8bytes\n");
+
+			icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 
+					  &skb->nh.ipv6h->payload_len);
+			goto err;
+		}
+	}
+#endif 
+
+	return;
+
+err:
+	kfree(nfp);
+	kfree_skb(skb);
 }
 
 /*
@@ -303,6 +344,8 @@
 	/*
 	 *	FIXME: If we don't have a checksum we ought to be able
 	 *	to defragment and checksum in this pass. [AC]
+	 *	Note that we don't really know yet whether the protocol
+	 *	needs checksums at all. It might still be a good idea. -AK
 	 */
 	for(fp = fq->fragments; fp; ) {
 		struct ipv6_frag *back;
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/route.c linux/net/ipv6/route.c
--- v2.1.99/linux/net/ipv6/route.c	Sat May  2 14:19:55 1998
+++ linux/net/ipv6/route.c	Wed May  6 10:56:08 1998
@@ -1379,7 +1379,7 @@
 	switch(cmd) {
 	case SIOCADDRT:		/* Add a route */
 	case SIOCDELRT:		/* Delete a route */
-		if (!suser())
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		err = copy_from_user(&rtmsg, arg,
 				     sizeof(struct in6_rtmsg));
diff -u --recursive --new-file v2.1.99/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.1.99/linux/net/ipv6/tcp_ipv6.c	Sat May  2 14:19:55 1998
+++ linux/net/ipv6/tcp_ipv6.c	Sat May  2 14:22:30 1998
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: tcp_ipv6.c,v 1.78 1998/04/16 16:29:22 freitag Exp $
+ *	$Id: tcp_ipv6.c,v 1.80 1998/05/02 12:47:15 davem Exp $
  *
  *	Based on: 
  *	linux/net/ipv4/tcp.c
@@ -123,10 +123,21 @@
 				result = 1;
 		}
 	}
-	if((result == 0) &&
-	   (tb == NULL) &&
-	   (tcp_bucket_create(snum) == NULL))
-		result = 1;
+	if(result == 0) {
+		if(tb == NULL) {
+			if(tcp_bucket_create(snum) == NULL)
+				result = 1;
+		} else {
+			/* It could be pending garbage collection, this
+			 * kills the race and prevents it from disappearing
+			 * out from under us by the time we use it.  -DaveM
+			 */
+			if(tb->owners == NULL && !(tb->flags & TCPB_FLAG_LOCKED)) {
+				tb->flags = TCPB_FLAG_LOCKED;
+				tcp_dec_slow_timer(TCP_SLT_BUCKETGC);
+			}
+		}
+	}
 go_like_smoke:
 	SOCKHASH_UNLOCK();
 	return result;
@@ -731,7 +742,7 @@
 		isn = tcp_v6_init_sequence(sk,skb);
 
 	/*
-	 *	There are no SYN attacks on IPv6, yet...
+	 *	There are no SYN attacks on IPv6, yet...	
 	 */
 	if (BACKLOG(sk) >= BACKLOGMAX(sk)) {
 		printk(KERN_DEBUG "droping syn ack:%d max:%d\n",
diff -u --recursive --new-file v2.1.99/linux/net/netsyms.c linux/net/netsyms.c
--- v2.1.99/linux/net/netsyms.c	Sat May  2 14:19:55 1998
+++ linux/net/netsyms.c	Sat May  2 14:22:30 1998
@@ -458,7 +458,7 @@
 EXPORT_SYMBOL(qdisc_new_estimator);
 EXPORT_SYMBOL(qdisc_kill_estimator);
 #endif
-#ifdef CONFIG_NET_POLICE
+#ifdef CONFIG_NET_CLS_POLICE
 EXPORT_SYMBOL(tcf_police);
 EXPORT_SYMBOL(tcf_police_locate);
 EXPORT_SYMBOL(tcf_police_destroy);
diff -u --recursive --new-file v2.1.99/linux/net/packet/af_packet.c linux/net/packet/af_packet.c
--- v2.1.99/linux/net/packet/af_packet.c	Thu Mar 26 15:57:25 1998
+++ linux/net/packet/af_packet.c	Wed May  6 10:56:08 1998
@@ -691,7 +691,7 @@
 	struct sock *sk;
 	int err;
 
-	if (!suser())
+	if (!capable(CAP_NET_RAW))
 		return -EPERM;
 	if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW
 #ifdef CONFIG_SOCK_PACKET
@@ -1089,7 +1089,8 @@
 			err = get_user(pid, (int *) arg);
 			if (err)
 				return err; 
-			if (current->pid != pid && current->pgrp != -pid && !suser())
+			if (current->pid != pid && current->pgrp != -pid && 
+			    !capable(CAP_NET_ADMIN))
 				return -EPERM;
 			sk->proc = pid;
 			return(0);
diff -u --recursive --new-file v2.1.99/linux/net/rose/af_rose.c linux/net/rose/af_rose.c
--- v2.1.99/linux/net/rose/af_rose.c	Tue Apr 14 14:29:27 1998
+++ linux/net/rose/af_rose.c	Wed May  6 10:56:08 1998
@@ -1193,7 +1193,7 @@
 		case SIOCADDRT:
 		case SIOCDELRT:
 		case SIOCRSCLRRT:
-			if (!suser()) return -EPERM;
+			if (!capable(CAP_NET_ADMIN)) return -EPERM;
 			return rose_rt_ioctl(cmd, (void *)arg);
 
 		case SIOCRSGCAUSE: {
diff -u --recursive --new-file v2.1.99/linux/net/wanrouter/wanmain.c linux/net/wanrouter/wanmain.c
--- v2.1.99/linux/net/wanrouter/wanmain.c	Sat May  2 14:19:56 1998
+++ linux/net/wanrouter/wanmain.c	Wed May  6 10:56:08 1998
@@ -371,7 +371,7 @@
 	struct proc_dir_entry* dent;
 	wan_device_t* wandev;
 
-	if (!suser())
+	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 		
 	if ((cmd >> 8) != ROUTER_IOCTL)
diff -u --recursive --new-file v2.1.99/linux/net/x25/af_x25.c linux/net/x25/af_x25.c
--- v2.1.99/linux/net/x25/af_x25.c	Tue Apr 14 14:29:27 1998
+++ linux/net/x25/af_x25.c	Wed May  6 10:56:08 1998
@@ -1096,7 +1096,7 @@
 
 		case SIOCADDRT:
 		case SIOCDELRT:
-			if (!suser()) return -EPERM;
+			if (!capable(CAP_NET_ADMIN)) return -EPERM;
 			return x25_route_ioctl(cmd, (void *)arg);
 
 		case SIOCX25GSUBSCRIP:
diff -u --recursive --new-file v2.1.99/linux/scripts/Configure linux/scripts/Configure
--- v2.1.99/linux/scripts/Configure	Tue Apr 14 14:29:27 1998
+++ linux/scripts/Configure	Sun May  3 17:52:06 1998
@@ -53,10 +53,6 @@
 #
 # 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
 # texts.
-#
-# 100498 Riley Williams (rhw@bigfoot.com) - added ability to display
-# blank lines in help texts: Any line consisting only of a single dot
-# will be displayed blank.
 
 #
 # Make sure we're really running bash.
@@ -107,7 +103,7 @@
      then
 	  echo; echo "  Sorry, no help available for this option yet.";echo
      else
-	  (echo; echo "$text") | sed 's/^\.$//' | ${PAGER:-more}
+	  (echo; echo "$text") | ${PAGER:-more}
      fi
   else
      echo;
diff -u --recursive --new-file v2.1.99/linux/scripts/Menuconfig linux/scripts/Menuconfig
--- v2.1.99/linux/scripts/Menuconfig	Tue Apr 14 14:29:27 1998
+++ linux/scripts/Menuconfig	Sun May  3 17:52:06 1998
@@ -47,13 +47,6 @@
 #
 # 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
 # texts.
-#----------------------------------------------------------------------------
-#
-# 10 Apr 1998 - Added ability to display blank lines in help text: Any line
-#               which only contains a single dot will be displayed blank.
-#               Author: Riley Williams <rhw@bigfoot.com>
-#
-#----------------------------------------------------------------------------
 
 
 #
@@ -301,7 +294,7 @@
           echo "There is no help available for this kernel option."
 	  return 1
      else
-	  echo "$text" | sed 's/^\.$//'
+	  echo "$text"
      fi
   else
 	 echo "There is no help available for this kernel option."
