diff -u --recursive --new-file v2.1.103/linux/COPYING linux/COPYING
--- v2.1.103/linux/COPYING	Wed Dec  1 04:44:15 1993
+++ linux/COPYING	Wed May 20 18:54:33 1998
@@ -3,7 +3,7 @@
  services by normal system calls - this is merely considered normal use
  of the kernel, and does *not* fall under the heading of "derived work".
  Also note that the GPL below is copyrighted by the Free Software
- Foundation, but the instance of code that it refers to (the linux
+ Foundation, but the instance of code that it refers to (the Linux
  kernel) is copyrighted by me and others who actually wrote it.
 
 			Linus Torvalds
diff -u --recursive --new-file v2.1.103/linux/CREDITS linux/CREDITS
--- v2.1.103/linux/CREDITS	Thu May 14 19:47:37 1998
+++ linux/CREDITS	Thu Jun  4 15:52:21 1998
@@ -467,7 +467,7 @@
 
 N: Rik Faith
 E: faith@cs.unc.edu
-E: r.faith@ieee.org
+E: faith@acm.org
 D: Author: Future Domain TMC-16x0 SCSI driver
 D: Debugging: SCSI code; Cyclades serial driver; APM driver
 D: Debugging: XFree86 Mach 32 server, accelerated server code
@@ -1653,7 +1653,7 @@
 D: NFS mmap()
 D: XF86_S3
 D: Kernel modules
-D: Parts of varios other programs (xfig, open, ...)
+D: Parts of various other programs (xfig, open, ...)
 S: C/ Federico Garcia Lorca 1 10-A
 S: Sevilla 41005
 S: Spain
diff -u --recursive --new-file v2.1.103/linux/Documentation/00-INDEX linux/Documentation/00-INDEX
--- v2.1.103/linux/Documentation/00-INDEX	Sat May  2 14:19:50 1998
+++ linux/Documentation/00-INDEX	Thu Jun  4 22:53:50 1998
@@ -1,7 +1,8 @@
 This is a brief list of all the files in ./linux/Documentation and what
 they contain. If you add a documentation file, please list it here in 
 alphabetical order as well, or risk being hunted down like a rabid dog. 
-Note that subdirectories have their own index files too.
+Note that subdirectories have their own index files too. Please try and
+keep the descriptions small enough to fit on one line.
 							 Thanks -- Paul G.
 
 00-INDEX
@@ -56,6 +57,8 @@
 	- info on the in-kernel binary support for Java(tm)
 joystick.txt
 	- info on using joystick devices (and driver) with linux.
+kmod.txt
+	- - info on the kernel module loader/unloader (kerneld replacement)
 locks.txt
 	- info on file locking implementations, flock() vs. fcntl(), etc.
 logo.gif
@@ -76,6 +79,8 @@
 	- info on typical Linux memory problems.
 modules.txt
 	- short guide on how to make kernel parts into loadable modules
+mtrr.txt
+	- how to use PPro Memory Type Range Registers to increase performance
 nbd.txt
 	- info on a TCP implementation of a network block device.
 networking/
diff -u --recursive --new-file v2.1.103/linux/Documentation/ARM-README linux/Documentation/ARM-README
--- v2.1.103/linux/Documentation/ARM-README	Fri May  8 23:14:41 1998
+++ linux/Documentation/ARM-README	Wed May 20 18:54:33 1998
@@ -29,7 +29,7 @@
 Todo list
 ---------
 
-  This is the list of changes to be done (roughly prioritorised):
+  This is the list of changes to be done (roughly prioritised):
 
   * fully test new MEMC translation code
   * fully test new AcornSCSI driver.
@@ -123,7 +123,7 @@
 Request to developers
 ---------------------
 
-  When writing device drivers which include a separate assember file, please
+  When writing device drivers which include a separate assembler file, please
   include it in with the C file, and not the arch/arm/lib directory.  This
   allows the driver to be compiled as a loadable module without requiring
   half the code to be compiled into the kernel image.
diff -u --recursive --new-file v2.1.103/linux/Documentation/Changes linux/Documentation/Changes
--- v2.1.103/linux/Documentation/Changes	Thu May 14 19:47:37 1998
+++ linux/Documentation/Changes	Wed May 20 18:54:33 1998
@@ -209,7 +209,7 @@
 RPM
 ===
 
-   If you run RedHat Linux or any other distribution that uses RPM, you
+   If you run Red Hat Linux or any other distribution that uses RPM, you
 need to upgrade RPM to version 2.2.7 or later.
 
 DOSEMU
@@ -471,7 +471,7 @@
 your favorite Red Hat mirror site before installing the non-RPM
 version.  Remember, you might need to use the -force option to get the
 upgrade to install.  ftp://ftp.redhat.com/pub/contrib/ will have almost
-everything you need, as does RedHat 5.0.
+everything you need, as does Red Hat 5.0.
 
    Those of you running Debian (or a different distribution that
 supports .deb packages) can look in the "unstable" and
diff -u --recursive --new-file v2.1.103/linux/Documentation/CodingStyle linux/Documentation/CodingStyle
--- v2.1.103/linux/Documentation/CodingStyle	Mon Sep 23 21:54:40 1996
+++ linux/Documentation/CodingStyle	Wed May 20 18:54:33 1998
@@ -132,7 +132,7 @@
 complexity and indentation level of that function.  So, if you have a
 conceptually simple function that is just one long (but simple)
 case-statement, where you have to do lots of small things for a lot of
-different cases, it's ok to have a longer function. 
+different cases, it's OK to have a longer function. 
 
 However, if you have a complex function, and you suspect that a
 less-than-gifted first-year high-school student might not even
diff -u --recursive --new-file v2.1.103/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.103/linux/Documentation/Configure.help	Wed May 20 19:10:36 1998
+++ linux/Documentation/Configure.help	Thu May 21 16:42:47 1998
@@ -24,7 +24,7 @@
 #
 # Information about what a kernel is, what it does, how to patch and
 # compile it and much more is contained in the Kernel-HOWTO, available
-# via ftp (user: anonymous) from sunsite.unc.edu in the directory
+# via FTP (user: anonymous) from sunsite.unc.edu in the directory
 # /pub/Linux/docs/HOWTO. Before you start compiling, make sure that
 # you have the necessary versions of all programs and libraries
 # required to compile and run this kernel; they are listed in the file
@@ -99,7 +99,7 @@
   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
+  available via FTP (user: anonymous) in
   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
@@ -157,7 +157,7 @@
   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
-  mount (available via ftp (user: anonymous) from
+  mount (available via FTP (user: anonymous) from
   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
@@ -195,7 +195,7 @@
   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
+  consult the Disk-HOWTO, available via FTP (user: anonymous) from
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. To fine-tune IDE
   drive/interface parameters for improved performance, look for the
   hdparm package at
@@ -218,7 +218,7 @@
   for systems with only older MFM/RLL/ESDI drives. Choosing the old
   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
+  more detailed information, read the Disk-HOWTO, available via FTP
   (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 Use old disk-only driver on primary interface
@@ -262,7 +262,7 @@
   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
+  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
@@ -338,7 +338,7 @@
   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
+  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
@@ -694,10 +694,10 @@
   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
+  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
+  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
@@ -872,7 +872,7 @@
   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
+  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
@@ -969,7 +969,7 @@
   want to read the Linux/Alpha homepage on the WWW at
   http://www.azstarnet.com/~axplinux/ (to browse the WWW, you need to
   have access to a machine on the Internet that has a program like
-  lynx or netscape) and also the Alpha-HOWTO, available via ftp (user:
+  lynx or netscape) and also the Alpha-HOWTO, available via FTP (user:
   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:
@@ -1047,7 +1047,7 @@
   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
+  via FTP (user: anonymous) from
   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
@@ -1099,7 +1099,7 @@
   bus system, i.e. the way the CPU talks to the other stuff inside
   your box. Other bus systems are ISA, EISA, Microchannel (MCA) or
   VESA. If you have PCI, say Y, otherwise N. The PCI-HOWTO, available
-  via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO,
+  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.
 
@@ -1171,12 +1171,12 @@
   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
+  (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
+  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.
 
@@ -1265,7 +1265,7 @@
   becoming a universal executable format.
 
   If you want to execute JAVA binaries, read the Java on Linux HOWTO,
-  available via ftp (user: anonymous) at
+  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
@@ -1379,7 +1379,7 @@
   "vga=ask" which brings up a video mode menu on kernel startup. 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
+  explained in the SCSI-HOWTO, available via FTP (user: anonymous) in
   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.
@@ -1761,7 +1761,7 @@
   addresses. (This last problem can also be solved by connecting the
   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
+  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 IP forwarding is enabled
@@ -1774,7 +1774,7 @@
   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
+  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",
@@ -1801,7 +1801,7 @@
   ipautofw is a program by Richard Lynch allowing additional support
   for masquerading protocols which do not (as yet) have their own
   protocol helpers. Information and source for ipautofw is available
-  via ftp (user: anonymous) from
+  via FTP (user: anonymous) from
   ftp://ftp.netis.com/pub/members/rlynch/
 
   The ipautofw code is still under development and so is currently
@@ -1818,37 +1818,6 @@
   to allow some forwarding of packets from outside to inside a
   firewall on given ports. Information and source for ipportfw is
   available from
-  http://www.monmouth.demon.co.uk/ipsubs/portforwarding.html
-  The portfw code is still under development and so is currently
-  marked EXPERIMENTAL.
-  If you want this, say Y.
-
-IP: ICMP masquerading
-CONFIG_IP_MASQUERADE_ICMP
-  The basic masquerade code described for CONFIG_IP_MASQUERADE only
-  handles TCP or UDP packets (and ICMP errors for existing 
-  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)
-  ipautofw is a program by Richard Lynch allowing additional
-  support for masquerading protocols which do not (as yet)
-  have additional protocol helpers.  
-  Information and source for ipautofw is available 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.
-
-IP: ipportfw masquerade support
-CONFIG_IP_MASQUERADE_IPPORTFW
-  ipportfw is an addition to IP Masquerading written by Steven Clarke
-  to allow some forwarding of packets from outside to inside a
-  firewall on given ports. Information and source for ipportfw is
-  available from
   http://www.monmouth.demon.co.uk/ipsubs/portforwarding.html (to
   browse the WWW, you need to have access to a machine on the Internet
   that has a program like lynx or netscape).
@@ -1892,7 +1861,7 @@
   the WWW at http://www.thesphere.com/~dlp/TwoServers/ (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 in the
-  Virtual-Hosting-HOWTO, available via ftp (user: anonymous) from
+  Virtual-Hosting-HOWTO, available via FTP (user: anonymous) from
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
 
   Another scenario would be
@@ -1936,7 +1905,7 @@
 
 PC/TCP compatibility mode
 CONFIG_INET_PCTCP
-  If you have been having difficulties telneting to your Linux machine
+  If you have been having difficulties telnetting to your Linux machine
   from a DOS system that uses (broken) PC/TCP networking software (all
   versions up to OnNet 2.0) over your local Ethernet try saying Y
   here.  Everyone else says N. People having problems with NCSA telnet
@@ -2092,7 +2061,7 @@
   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
+  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,
@@ -2137,24 +2106,22 @@
 CONFIG_SPX
   The (SPP-derived) Sequenced Packet eXchange (SPX) protocol. Novell's
   networking protocol which monitors transmissions to guarantee
-  successful delivery. An example server/client program (SPX-0.0x.tar.gz) 
-  is available at ftp://ftp.spacs.k12.wi.us/users/jschlst/SPX-0.0x.tar.gz.
-  It is safe to say Y/M here.
+  successful delivery. It is safe to say Y/M here.
 
 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
+  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
+  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)
+  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
@@ -2183,7 +2150,7 @@
 CONFIG_IPDDP_ENCAP
   If you say Y here, the kernel will be able to encapsulate IP packets
   inside Appletalk frames; this is useful if your Linux box is stuck
-  on an appletalk network (which hopefully contains a decapsulator
+  on an Appletalk network (which hopefully contains a decapsulator
   somewhere). Please see Documentation/networking/ipddp.txt for more
   information. If you say Y here, you cannot say Y to "Appletalk-IP to
   IP Decapsulation support", below.
@@ -2192,7 +2159,7 @@
 CONFIG_IPDDP_DECAP
   If you say Y here, the kernel will be able to decapsulate
   Appletalk-IP frames to IP packets; this is useful if you want your
-  Linux box to act as an Internet gateway for an appletalk
+  Linux box to act as an Internet gateway for an Appletalk
   network. Please see Documentation/networking/ipddp.txt for more
   information. If you say Y here, you cannot say Y to "IP to
   Appletalk-IP Encapsulation support", above.
@@ -2232,7 +2199,7 @@
   Y here. You want to read 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) and the HAM-HOWTO
-  and the AX25-HOWTO, both available via ftp (user: anonymous) from
+  and the AX25-HOWTO, both 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 amateur
@@ -2255,7 +2222,7 @@
 
   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
+  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
@@ -2293,7 +2260,7 @@
 
   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
+  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
@@ -2314,7 +2281,7 @@
 
   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
+  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
@@ -2379,7 +2346,7 @@
   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
+  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
@@ -2403,7 +2370,7 @@
   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
+  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. 
 
@@ -2580,7 +2547,7 @@
   entry point can carry several logical point-to-point connections
   (called "virtual circuits") to other computers connected to the X.25
   network. Governments, banks, and other organizations tend to use it
-  to connect to each other or to form Wide Area Networks (WAN's). Many
+  to connect to each other or to form Wide Area Networks (WANs). Many
   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
@@ -2641,12 +2608,12 @@
   other third party bridge products. 
 
   In order to use this, you'll need the bridge configuration tools
-  available via ftp (user: anonymous) from
+  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)
+  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.
 
@@ -2698,7 +2665,7 @@
   that "speaks" the SCSI protocol), because you will be asked for
   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
+  SCSI-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
@@ -2713,7 +2680,7 @@
 CONFIG_BLK_DEV_SD
   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:
+  SCSI-HOWTO and the Disk-HOWTO, both available via FTP (user:
   anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. This is
   NOT for SCSI CDROMs.
 
@@ -2729,7 +2696,7 @@
 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
+  SCSI-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and
   drivers/scsi/README.st in the kernel source. This is NOT for SCSI
   CDROMs.
@@ -2756,7 +2723,7 @@
 Enable vendor-specific extensions (for SCSI CDROM)
 CONFIG_BLK_DEV_SR_VENDOR
   This enables the usage of vendor specific SCSI commands. This is
-  required to support multisession CD's with old NEC/TOSHIBA cdrom
+  required to support multisession CDs with old NEC/TOSHIBA cdrom
   drives (and HP Writers). If you have such a drive and get the first
   session only, try saying Y here; everybody else says N.
 
@@ -2767,11 +2734,11 @@
   CDROMs or tapes, say Y here. These won't be supported by the kernel
   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)
+  would need the program cdwrite, available via FTP (user: anonymous)
   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
+  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
@@ -2828,7 +2795,7 @@
 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
+  SCSI-HOWTO, available via FTP (user: anonymous) at
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You might also want to
   read the comments at the top of drivers/scsi/aha152x.c.
 
@@ -2840,7 +2807,7 @@
 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
+  3.4 of the SCSI-HOWTO, available via FTP (user: anonymous) at
   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
@@ -2854,7 +2821,7 @@
 Adaptec AHA1740 support
 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
+  3.5 of the SCSI-HOWTO, available via FTP (user: anonymous) 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/aha1740.h.
@@ -2873,7 +2840,7 @@
   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
+  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
@@ -2971,7 +2938,7 @@
 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
+  the SCSI-HOWTO, available via FTP (user: anonymous) at
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and the file
   drivers/scsi/README.dtc3x80.  
 
@@ -2987,7 +2954,7 @@
   and the DPT PM2011B and PM2012B controllers.  Note that there is
   also another driver for the same hardware: "EATA ISA/EISA/PCI
   support". You should only say Y to one of them. Please read the
-  SCSI-HOWTO, available via ftp (user: anonymous) at
+  SCSI-HOWTO, available via FTP (user: anonymous) at
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  
 
   This driver is also available as a module (= code which can be
@@ -3002,7 +2969,7 @@
   host adapters could also use this driver but are discouraged from
   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
+  available via FTP (user: anonymous) at
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  
 
   If you want to compile this as a module ( = code which can be
@@ -3016,7 +2983,7 @@
   The source at drivers/scsi/u14-34f.c contains some information about
   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
+  SCSI-HOWTO, available via FTP (user: anonymous) at
   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
@@ -3046,7 +3013,7 @@
   (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and
   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
+  It is explained in section 3.7 of the SCSI-HOWTO, available via FTP
   (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  
 
   This driver is also available as a module ( = code which can be
@@ -3058,7 +3025,7 @@
 CONFIG_SCSI_GENERIC_NCR5380
   This is the generic NCR family of SCSI controllers, not to be
   confused with the NCR 53c7 or 8xx controllers. It is explained in
-  section 3.8 of the SCSI-HOWTO, available via ftp (user: anonymous)
+  section 3.8 of the SCSI-HOWTO, available via FTP (user: anonymous)
   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.
@@ -3087,7 +3054,7 @@
 CONFIG_SCSI_NCR53C7xx
   This is the 53c7 and 8xx NCR family of SCSI controllers, not to be
   confused with the NCR 5380 controllers. It is explained in section
-  3.8 of the SCSI-HOWTO, available via ftp (user: anonymous) at
+  3.8 of the SCSI-HOWTO, available via FTP (user: anonymous) 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/53c7,8xx.h.
@@ -3260,7 +3227,7 @@
   'ibmmcascsi=display' as an additional kernel parameter. 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
+  the SCSI-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this driver as a module ( = code which can be
@@ -3326,7 +3293,7 @@
 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
+  3.10 of the SCSI-HOWTO, available via FTP (user: anonymous) 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/pas16.h.
@@ -3339,7 +3306,7 @@
 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
+  SCSI host adapter. Please read the SCSI-HOWTO, available via FTP
   (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module called pci2000.o ( = code
@@ -3350,7 +3317,7 @@
 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
+  SCSI host adapter. Please read the SCSI-HOWTO, available via FTP
   (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module called pci2220i.o ( = code
@@ -3361,7 +3328,7 @@
 PSI240i support
 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
+  SCSI host adapter. Please read the SCSI-HOWTO, available via FTP
   (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module called psi240i.o ( = code
@@ -3377,7 +3344,7 @@
   does NOT support the PCI version. The PCI versions are supported by
   the Qlogic ISP driver though.  Information about this driver is
   contained in drivers/scsi/README.qlogicfas.  You should also read
-  the SCSI-HOWTO, available via ftp (user: anonymous) at
+  the SCSI-HOWTO, available via FTP (user: anonymous) at
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
@@ -3393,7 +3360,7 @@
   Y here, make sure to say Y to "PCI BIOS support" as well. More
   information is contained in the file
   drivers/scsi/README.qlogicisp. You should also read the SCSI-HOWTO,
-  available via ftp (user: anonymous) at
+  available via FTP (user: anonymous) at
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
@@ -3405,7 +3372,7 @@
 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,
-  available via ftp (user: anonymous) at
+  available via FTP (user: anonymous) 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/seagate.h.
@@ -3418,7 +3385,7 @@
 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
+  3.11 of the SCSI-HOWTO, available via FTP (user: anonymous) 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/t128.h. Note that Trantor was purchased by Adaptec, and
@@ -3433,7 +3400,7 @@
 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
+  SCSI-HOWTO, available via FTP (user: anonymous) 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/ultrastor.h.
@@ -3464,7 +3431,7 @@
   to "PCI bios support", the addresses of all the PCI SCSI controllers
   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 ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  
+  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.
@@ -3499,7 +3466,7 @@
 CONFIG_SCSI_NCR53C406A
   This is support for the NCR53c406a SCSI host adapter. For user
   configurable parameters, check out drivers/scsi/NCR53c406.c in the
-  kernel source. Also read the SCSI-HOWTO, available via ftp (user:
+  kernel source. Also read the SCSI-HOWTO, available via FTP (user:
   anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.  
 
   If you want to compile this driver as a module ( = code which can be
@@ -3523,7 +3490,7 @@
 CONFIG_SCSI_AM53C974
   This is support for the AM53/79C974 SCSI host adapters. Please read
   drivers/scsi/README.AM53C974 for details. Also, the SCSI-HOWTO,
-  available via ftp (user: anonymous) at
+  available via FTP (user: anonymous) at
   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
@@ -3548,7 +3515,7 @@
   (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 ftp (user: anonymous) from
+  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
@@ -3635,7 +3602,7 @@
   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
+  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
@@ -3669,7 +3636,7 @@
   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:
+  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.
@@ -3693,11 +3660,11 @@
 
   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
+  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
+  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
@@ -3720,11 +3687,11 @@
   TCP/IP headers (not on the data itself), but it has to be supported
   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:
+  plan to use SLiRP, the SLIP emulator (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, you
-  definitely want to say Y here. The NET-2-HOWTO, available via ftp
+  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.
 
@@ -3751,7 +3718,7 @@
   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:
+  up shell account on some UNIX computer; get it via FTP (user:
   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
@@ -3791,7 +3758,7 @@
   interfaces. 
 
   Some user-level drivers for scarab devices which don't require
-  special kernel support are available via ftp (user: anonymous) from
+  special kernel support are available via FTP (user: anonymous) from
   ftp://shadow.cabi.net/pub/Linux.
 
 STRIP (Metricom Starmode radio IP)
@@ -3828,7 +3795,7 @@
   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
+  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
@@ -3941,7 +3908,7 @@
   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
+  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
@@ -4286,7 +4253,7 @@
 
   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
+  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
@@ -4312,7 +4279,7 @@
 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
+  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
@@ -4323,7 +4290,7 @@
 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
+  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
@@ -4336,7 +4303,7 @@
 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
+  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
@@ -4348,7 +4315,7 @@
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
   
   Important: There have been many reports that, with some motherboards
@@ -4367,7 +4334,7 @@
 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
+  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
@@ -4381,9 +4348,9 @@
   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
-  into the kernel, and read the the file
+  into the kernel, and read the file
   Documentation/networking/smc9.txt and the Ethernet-HOWTO, available
-  via ftp (user: anonymous) in
+  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
@@ -4396,7 +4363,7 @@
 CONFIG_NET_VENDOR_RACAL
   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
+  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
@@ -4407,7 +4374,7 @@
 NI5010 support
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that this is still
   experimental code. 
 
@@ -4420,7 +4387,7 @@
 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
+  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
@@ -4432,7 +4399,7 @@
 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
+  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
@@ -4444,14 +4411,14 @@
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   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
+  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
@@ -4462,7 +4429,7 @@
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   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
@@ -4477,7 +4444,7 @@
 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
+  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
@@ -4490,7 +4457,7 @@
 CONFIG_ELPLUS
   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:
+  say Y and read the Ethernet-HOWTO, available via FTP (user:
   anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
@@ -4502,7 +4469,7 @@
 3c507 support
 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
+  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
@@ -4514,7 +4481,7 @@
 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
+  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
@@ -4527,7 +4494,7 @@
 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
+  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
@@ -4545,7 +4512,7 @@
   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.
+  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.
 
@@ -4560,7 +4527,7 @@
   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 ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  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
@@ -4579,7 +4546,7 @@
   below.
 
   You might also want to have a look at the Ethernet-HOWTO, available
-  via ftp (user: anonymous) in
+  via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO (even though ARCnet is
   not really Ethernet).
 
@@ -4667,7 +4634,7 @@
 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
+  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
@@ -4680,7 +4647,7 @@
 CONFIG_CS89x0
   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
+  Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as
   Documentation/networking/cs89x0.txt.
 
@@ -4693,7 +4660,7 @@
 DEPCA support
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as
   drivers/net/depca.c.
 
@@ -4708,7 +4675,7 @@
   This driver supports the DE203, DE204 and DE205 network (Ethernet)
   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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) from
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
@@ -4720,13 +4687,13 @@
 SEEQ8005 support
 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:
+  is for you, read the Ethernet-HOWTO, available via FTP (user:
   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
+  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
@@ -4739,7 +4706,7 @@
 FMV-181/182/183/184 support
 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:
+  say Y and read the Ethernet-HOWTO, available via FTP (user:
   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
@@ -4755,7 +4722,7 @@
 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
+  separate driver. Please 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
@@ -4767,7 +4734,7 @@
 EtherExpress support
 CONFIG_EEXPRESS
   If you have an EtherExpress16 network (Ethernet) card, say Y and
-  read the Ethernet-HOWTO, available via ftp (user: anonymous) in
+  read the Ethernet-HOWTO, available via FTP (user: anonymous) in
   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
@@ -4782,7 +4749,7 @@
 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
+  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
@@ -4794,7 +4761,7 @@
 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
+  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
@@ -4806,7 +4773,7 @@
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
@@ -4818,7 +4785,7 @@
 NE2000/NE1000 support
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Many Ethernet cards
   without a specific driver are compatible with NE2000.
 
@@ -4831,14 +4798,14 @@
 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
+  the Ethernet-HOWTO, available via FTP (user: anonymous) in
   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
+  available via FTP (user: anonymous) from
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   Note that the answer to this question doesn't directly affect the
@@ -4850,13 +4817,13 @@
 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:
+  Y here and read the Ethernet-HOWTO, available via FTP (user:
   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
+  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
@@ -4868,7 +4835,7 @@
 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
+  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
@@ -4880,7 +4847,7 @@
 Mylex EISA LNE390A/LNE390B support
 CONFIG_LNE390
   If you have a network (Ethernet) card of this type, say Y and read
-  the Ethernet-HOWTO, available via ftp (user: anonymous) in
+  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
@@ -4892,7 +4859,7 @@
 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
+  read the Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
@@ -4906,7 +4873,7 @@
   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
+  Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific
   information is contained in Documentation/networking/de4x5.txt.
 
@@ -4924,7 +4891,7 @@
   of this type. (If your card is NOT SMC EtherPower 10/100 PCI
   (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
+  will say Y here.) Do read the Ethernet-HOWTO, available via FTP
   (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
   More specific information is contained in
   Documentation/networking/tulip.txt.
@@ -4940,7 +4907,7 @@
   This is support for the Digi International RightSwitch series of
   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
+  Ethernet-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific
   information is contained in Documentation/networking/dgrs.txt.
 
@@ -4953,7 +4920,7 @@
 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:
+  card, 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
@@ -4965,7 +4932,7 @@
 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
+  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
@@ -4977,7 +4944,7 @@
 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, available via ftp (user:
+  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.
@@ -4992,9 +4959,9 @@
 
 SMC EtherPower II (EXPERIMENTAL)
 CONFIG_EPIC100
-  If you have an SMC EtherPower II 9432 PCI ethernet network card
+  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
+  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
@@ -5008,14 +4975,14 @@
   The Zenith Z-Note notebook computer has a built-in network
   (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:
+  by this driver. Read the Ethernet-HOWTO, available via FTP (user:
   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
+  one of those, say Y and read the Ethernet-HOWTO, available via FTP
   (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
@@ -5038,7 +5005,7 @@
 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
+  available via FTP (user: anonymous) from
   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
@@ -5048,7 +5015,7 @@
 CONFIG_DE600
   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
+  Ethernet-HOWTO, available via FTP (user: anonymous) from
   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.
@@ -5062,7 +5029,7 @@
 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
+  Ethernet-HOWTO, available via FTP (user: anonymous) from
   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.
@@ -5080,7 +5047,7 @@
   connected to such a Token Ring network and want to use your Token
   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
+  via FTP (user:anonymous) from
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Most people can say N
   here.
 
@@ -5088,7 +5055,7 @@
 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
+  available via FTP (user:anonymous) from
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   Warning: this driver will almost definitely fail if more than one
@@ -5105,7 +5072,7 @@
   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
+  shapecfg program, available via FTP (user: anonymous) from
   ftp://shadow.cabi.net/pub/Linux in the shaper package.  
 
   This driver is also available as a module ( = code which can be
@@ -5143,7 +5110,7 @@
   If you have an Acorn system with one of these network cards, you
   should say Y to this option if you wish to use it with Linux.
 
-EBSA-110 ethernet interface
+EBSA-110 Ethernet interface
 CONFIG_AM79C961A
   If you wish to compile a kernel for the EBSA-110, then you should
   always answer Y to this.
@@ -5151,7 +5118,7 @@
 Support CDROM drives that are not SCSI or IDE/ATAPI
 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:
+  here, otherwise N. Read the CDROM-HOWTO, available via FTP (user:
   anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
 
   Note that the answer to this question doesn't directly affect the
@@ -5417,7 +5384,7 @@
   If you say Y here, you will be able to set per user limits for disk
   usage (also called disk quotas). Currently, it works only for the
   ext2 filesystem. You need additional software in order to use quota
-  support; for details, read the Quota mini-HOWTO, available via ftp
+  support; for details, read the Quota mini-HOWTO, available via FTP
   (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. Probably the quota
   support is only useful for multi user systems. If unsure, say N.
@@ -5437,7 +5404,7 @@
   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
+  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).
@@ -5625,7 +5592,7 @@
   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:
+  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.
@@ -5649,7 +5616,7 @@
   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
+  via FTP (user: anonymous) from
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO), thereby enlarging your
   kernel by about 27 kB; otherwise say N.
 
@@ -5694,7 +5661,7 @@
   This allows you to mount MSDOS partitions of your hard drive (unless
   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
+  DOSEMU-HOWTO, available via FTP (user: anonymous) at
   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
@@ -5791,7 +5758,7 @@
   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 in its kernel). NFS is explained in the Network
-  Administrator's Guide, available via ftp (user: anonymous) in
+  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.
 
@@ -5805,7 +5772,7 @@
 
   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
+  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
@@ -5835,7 +5802,7 @@
   is that it is faster; it might not be completely stable yet, though.
   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
+  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
@@ -5890,7 +5857,7 @@
   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:
+  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
@@ -6086,13 +6053,13 @@
   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
+  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
+  the program samba (available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/system/network/samba) for that.
 
   General information about how to connect Linux, Windows machines and
@@ -6425,7 +6392,7 @@
   If you want to display filenames with native language characters
   from the Microsoft fat filesystem family or from JOLIET CDROMs
   correctly on the screen, you need to include the appropriate
-  input/output character sets. Say Y here for the the Latin 2 character
+  input/output character sets. Say Y here for the Latin 2 character
   set, which works for most Latin-written Slavic and Central European
   languages: Czech, German, Hungarian, Polish, Rumanian, Croatian,
   Slovak, Slovene.
@@ -6536,7 +6503,7 @@
 CONFIG_SERIAL
   This selects whether you want to include the driver for the standard
   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
+  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
@@ -6563,7 +6530,7 @@
   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:
+  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.
@@ -6744,7 +6711,7 @@
   If you intend to attach a printer to the parallel port of your Linux
   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
+  read the Printing-HOWTO, available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   It is possible to share one parallel port among several devices
@@ -6759,7 +6726,7 @@
   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
+  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.
@@ -6779,7 +6746,7 @@
   a serial mouse. Most people have a regular serial MouseSystem or
   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
+  have something else, read the Busmouse-HOWTO, available via FTP
   (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and
   say Y here.
 
@@ -6797,7 +6764,7 @@
   generally a round connector with 9 pins. Note that the newer mice
   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
+  available via FTP (user: anonymous) in
   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
@@ -6816,7 +6783,7 @@
   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 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
@@ -6834,7 +6801,7 @@
 CONFIG_82C710_MOUSE
   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:
+  doesn't work. Read the Busmouse-HOWTO, available via FTP (user:
   anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
 PC110 digitizer pad support
@@ -6854,7 +6821,7 @@
 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
+  you have, say Y and read the Busmouse-HOWTO, available via FTP
   (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you are unsure, say N and read the HOWTO nevertheless: it will
@@ -6871,7 +6838,7 @@
 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:
+  busmice. Read the Busmouse-HOWTO, available via FTP (user:
   anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
@@ -6902,7 +6869,7 @@
 CONFIG_QIC02_DYNCONF
   You can either configure this driver once and for all by editing a
   header file (include/linux/tpqic02.h), in which case you should
-  say N, or you can fetch a program via anonymous ftp which is able
+  say N, or you can fetch a program via anonymous FTP which is able
   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.
@@ -7241,7 +7208,7 @@
   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:
+  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)
@@ -7360,7 +7327,7 @@
   kernel source.
 
   The watchdog is usually used together with the watchdog daemon which
-  is available via ftp (user: anonymous) from
+  is available via FTP (user: anonymous) from
   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.
@@ -7522,7 +7489,7 @@
   than an occasional beep, say Y. Be sure to have all the information
   about your sound card and its configuration down (I/O port,
   interrupt and DMA channel), because you will be asked for it. You
-  want to read the Sound-HOWTO, available via ftp (user: anonymous)
+  want to read the Sound-HOWTO, available via FTP (user: anonymous)
   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
@@ -7744,7 +7711,7 @@
   Say Y here if you have a SoundBlaster SB32, AWE32-PnP, SB AWE64 or
   similar sound card. See drivers/sound/lowlevel/README.awe,
   Documentation/sound/AWE32 and the Soundblaster-AWE mini-HOWTO,
-  available via ftp (user: anonymous) from
+  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)
@@ -7758,7 +7725,7 @@
   questions.  Read the drivers/sound/lowlevel/README.aedsp16 file and
   the head of drivers/sound/lowlevel/aedsp16.c to get more information
   about this driver and its configuration.  This driver supports Audio
-  Excel DSP 16 but not the III nor Pnp versions of this card. Read
+  Excel DSP 16 but not the III nor PnP versions of this card. Read
   drivers/sound/lowlevel/README.aedsp16 if you want to know something
   more on how to use the III version with this sound driver.
 
@@ -8746,20 +8713,20 @@
 # 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
 # LocalWords:  cdrom diskless netboot nfs xzvf ATAPI MB ide pavia rubini pl pd
-# LocalWords:  HD CDROMs IDECD NEC MITSUMI filesystem XT XD PCI bios cezar ATEN
+# LocalWords:  HD CDROMs IDECD NEC MITSUMI filesystem XT XD PCI BIOS cezar ATEN
 # LocalWords:  ISA EISA Microchannel VESA BIOSes IPC SYSVIPC ipc Ctrl dmesg hlt
 # LocalWords:  BINFMT Linkable http ac uk jo html GCC Sparc AVANTI CABRIOLET EB
 # LocalWords:  netscape gcc LD CC toplevel MODVERSIONS insmod rmmod modprobe IP
 # LocalWords:  genksyms INET loopback gatewaying ethernet PPP ARP Arp MEMSIZE
 # LocalWords:  howto multicasting MULTICAST MBONE firewalling ipfw ACCT resp ip
 # LocalWords:  proc acct IPIP encapsulator decapsulator klogd PCTCP RARP EXT PS
-# LocalWords:  telneting subnetted NAGLE rlogin NOSR ttyS TGA techinfo mbone nl
+# LocalWords:  telnetting subnetted NAGLE rlogin NOSR ttyS TGA techinfo mbone nl
 # LocalWords:  Mb SKB IPX Novell dosemu Appletalk DDP ATALK tapedrive vmalloc
 # LocalWords:  SD CHR scsi thingy SG CD LUNs LUN jukebox Adaptec BusLogic EATA
 # LocalWords:  buslogic DMA DPT ATT eata dma PIO UltraStor fdomain umsdos ext
 # LocalWords:  QLOGIC qlogic TMC seagate Trantor ultrastor FASST wd NETDEVICES
 # LocalWords:  unix BBS linux nullmodem CSLIP PLIP Kirch's LDP CSlip SL SCC IRQ
-# LocalWords:  Turbo Laplink plip NCSA port's ReQuest IRQs EQL SMC AMD PCnet NE
+# LocalWords:  Turbo Laplink plip NCSA ReQuest IRQs EQL SMC AMD PCnet NE
 # LocalWords:  COM ELPLUS Com EtherLinkIII VLB Arcnet arcnet Cabletron DEPCA DE
 # LocalWords:  depca EtherWorks EWRK ewrk SEEQ EtherExpressPro EEXPRESS NI xxx
 # LocalWords:  EtherExpress WaveLAN wavelan PCLAN HPLAN VG SK Ansel Xen de ZNET
@@ -8780,7 +8747,7 @@
 # LocalWords:  chipset FB multicast MROUTE appletalk ifconfig IBMTR multiport
 # LocalWords:  Multisession STALDRV EasyIO EC EasyConnection ISTALLION ONboard
 # LocalWords:  Brumby pci TNC cis ohio faq usenet NETLINK dev hydra ca Tyne mem
-# LocalWords:  carleton Deskstation DECstation SUNFD JENSEN Noname XXXM SLiRP
+# LocalWords:  carleton Deskstation DECstation SUNFD JENSEN Noname SLiRP
 # LocalWords:  pppd Zilog ZS SRM bootloader ez mainmenu rarp ipfwadm paride pcd
 # LocalWords:  RTNETLINK mknod xos MTU lwared Macs mac netatalk macs cs Wolff
 # LocalWords:  dartmouth flowerpt MultiMaster FlashPoint tudelft etherexpress
@@ -8802,10 +8769,10 @@
 # LocalWords:  ipppd syncppp RFC MPP VJ downloaded icn NICCY Creatix shmem ufr
 # LocalWords:  ibp md ARCnet ether encap NDIS arcether ODI Amigas AmiTCP NetBSD
 # LocalWords:  initrd tue util DES funet des OnNet BIOSP smc Travan Iomega CMS
-# LocalWords:  FC DC dc PPA IOMEGA's ppa RNFS FMV Fujitsu ARPD arpd loran layes
+# LocalWords:  FC DC dc PPA ppa RNFS FMV Fujitsu ARPD arpd loran layes
 # LocalWords:  FRAD indiana framerelay DLCI DCLIs Sangoma SDLA mrouted sync sec
 # LocalWords:  Starmode Metricom MosquitoNet mosquitonet kbit nfsroot Digiboard
-# LocalWords:  DIGI Xe Xeve digiboard UMISC touchscreens mtu ethernets HBAs MEX
+# LocalWords:  DIGI Xe Xeve digiboard UMISC touchscreens mtu HBAs MEX
 # LocalWords:  Shifflett netcom js jshiffle WIC DECchip ELCP EtherPower dst RTC
 # LocalWords:  rtc SMP lp Digi Intl RightSwitch DGRS dgrs AFFS Amiga UFS SDL AP
 # LocalWords:  Solaris RISCom riscom syncPPP PCBIT pcbit sparc anu au artoo ufs
@@ -8814,7 +8781,7 @@
 # LocalWords:  Bernd informatik rwth aachen uae affs multihosting bytecode java
 # LocalWords:  applets applet JDK ncsa cabi SNI Alphatronix readme LANs scarab
 # LocalWords:  winsock RNIS caltech OSPF honour Honouring Mbit Localtalk DEFRAG
-# LocalWords:  localtalk download Packetwin Baycom baycom interwork ascii JNT
+# LocalWords:  download Packetwin Baycom baycom interwork ascii JNT
 # LocalWords:  Camtec proxying indyramp defragment defragmented UDP FAS FASXX
 # LocalWords:  FastSCSI SIO FDC qlogicfas QLogic qlogicisp setbaycom ife ee LJ
 # LocalWords:  ethz ch Travelmates ProAudioSpectrum ProAudio SoundMan SB SBPro
@@ -8857,10 +8824,10 @@
 # LocalWords:  smp HiSax SiemensChipSet Siemens AVM Elsa ITK hisax PCC MICROR
 # LocalWords:  Mircolink EURO DSS Spellcaster BRI sc spellcast Digiboards GPIO
 # LocalWords:  SYMBIOS COMPAT SDMS rev ASUS Tekram HX VX API ibmmcascsi ASY asy
-# LocalWords:  loader's PCnetPCI automounter AUTOFS amd autofs VT Gallant's Pnp
+# LocalWords:  loader's PCnetPCI automounter AUTOFS amd autofs VT Gallant's PnP
 # LocalWords:  AEDSP aedsp enskip tik Sysctl sysctl PARPORT parport pnp IDs EPP
 # LocalWords:  Autoprobe bart patrickr HDLS READBACK AB usr DAMA DS SparQ aten
-# LocalWords:  Symbios PCscsi tmscsim RoamAbout GHz Hinds's contrib mathematik
+# LocalWords:  Symbios PCscsi tmscsim RoamAbout GHz Hinds' contrib mathematik
 # LocalWords:  darmstadt okir DIGIEPCA International's Xem digiepca epca bootup
 # LocalWords:  zorro CAPI AVMB capi avmb VP SYN syncookies EM em pc Ethertalk
 # LocalWords:  Dayna DL Daynatalk LT PhoneNET ATB Daystar queueing CMDS SCBs ls
@@ -8869,7 +8836,7 @@
 # LocalWords:  stuttgart rdist TRANS hostnames mango jukeboxes ESS userland PD
 # LocalWords:  hardlinked NAMETRANS env mtab fstab umount nologin runlevel gid
 # LocalWords:  transname filespace adm Nodename hostname uname Kernelname bootp
-# LocalWords:  KERNNAME kname ktype kernelname Kerneltype KERNTYPE Alt SCB's RX
+# LocalWords:  KERNNAME kname ktype kernelname Kerneltype KERNTYPE Alt RX
 # LocalWords:  dataless kerneltype SYSNAME Netbeui Comtrol Rocketport palmtop
 # LocalWords:  nvram SYSRQ SysRq PrintScreen sysrq NVRAMs NvRAM Shortwave RTTY
 # LocalWords:  HFMODEM shortwave Sitor Amtor Pactor GTOR hfmodem hayes TX TMOUT
@@ -8879,7 +8846,7 @@
 # LocalWords:  misconfigured autoconfiguration IPGRE ICMP tracert ipautofw PIM
 # LocalWords:  netis rlynch autofw ipportfw monmouth ipsubs portforwarding pimd
 # LocalWords:  portfw PIMSM netweb usc pim pf EUI aggregatable PB decapsulate
-# LocalWords:  ipddp Decapsulation DECAP bool HAMRADIO WAN's tcpdump af CD's tx
+# LocalWords:  ipddp Decapsulation DECAP bool HAMRADIO tcpdump af CDs tx
 # LocalWords:  ethertap multisession PPC MMIO GDT GDTH ICP gdth hamradio LAN's
 # LocalWords:  lmh weejock AIMSlab RadioTrack RTRACK HZP OptoSCC TRX rx TRXECHO
 # LocalWords:  DMASCC paccomm dmascc addr cfg oevsv oe kib picpar FDX baudrate
diff -u --recursive --new-file v2.1.103/linux/Documentation/IO-APIC.txt linux/Documentation/IO-APIC.txt
--- v2.1.103/linux/Documentation/IO-APIC.txt	Sat May  2 14:19:50 1998
+++ linux/Documentation/IO-APIC.txt	Wed May 20 18:54:33 1998
@@ -11,10 +11,10 @@
 
 	or - the board does not have PCI pins connected to the IO-APIC
 
-	or - the user has overriden blacklisted settings with the
+	or - the user has overridden blacklisted settings with the
 	     pirq= boot option line.
 
-Kernel messages tell you wether the board is 'safe'. If your box
+Kernel messages tell you whether the board is 'safe'. If your box
 boots with enabled IO-APIC IRQs, then you have nothing else to do. Your
 /proc/interrupts will look like this one:
 
@@ -42,7 +42,7 @@
 
 	A) if your board is unlisted, then mail to linux-smp to get
 	   it into either the white or the blacklist
-	B) if your board is blacklisted, then figure out the apropriate
+	B) if your board is blacklisted, then figure out the appropriate
 	   pirq= option to get your system to boot
 
 
@@ -52,7 +52,7 @@
 
 the actual numbers depend on your system, on your PCI cards and on their
 PCI slot position. Usually PCI slots are 'daisy chained' before they are
-connected to the PCI chipset irq routing facility (the incoming PIRQ1-4
+connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4
 lines):
 
                ,-.        ,-.        ,-.        ,-.        ,-.
@@ -80,11 +80,11 @@
 These INTA-D PCI IRQs are always 'local to the card', their real meaning
 depends on which slot they are in. If you look at the daisy chaining diagram,
 a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ2 of
-the PCI chipset. Most cards issue INTA, this creates optimal distibution
+the PCI chipset. Most cards issue INTA, this creates optimal distribution
 between the PIRQ lines. (distributing IRQ sources properly is not a
 necessity, PCI IRQs can be shared at will, but it's a good for performance
 to have non shared interrupts). Slot5 should be used for videocards, they
-dont use interrupts normally, thus they are not daisy chained either.
+do not use interrupts normally, thus they are not daisy chained either.
 
 so if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in
 Slot2, then you'll have to specify this pirq= line:
@@ -98,7 +98,7 @@
 
 note that this script wont work if you have skipped a few slots or if your
 board does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins
-connected in some strange way). Eg. if in the above case you have your SCSI
+connected in some strange way). E.g. if in the above case you have your SCSI
 card (IRQ11) in Slot3, and have Slot1 empty:
 
 	append="pirq=0,9,11"
@@ -130,7 +130,7 @@
 to the official whitelist, contact us]
 
 good luck and mail to linux-smp@vger.rutgers.edu or
-linux-kernel@vger.rutger.edu if you have any problems that are not covered
+linux-kernel@vger.rutgers.edu if you have any problems that are not covered
 by this document.
 
 -- mingo
diff -u --recursive --new-file v2.1.103/linux/Documentation/IO-mapping.txt linux/Documentation/IO-mapping.txt
--- v2.1.103/linux/Documentation/IO-mapping.txt	Sat Sep 28 01:05:38 1996
+++ linux/Documentation/IO-mapping.txt	Wed May 20 18:54:33 1998
@@ -56,13 +56,13 @@
 where all the addresses actually point to the same thing, it's just seen 
 through different translations..
 
-Similarly, on the alpha, the normal translation is
+Similarly, on the Alpha, the normal translation is
 
  physical address:	0
  virtual address:	0xfffffc0000000000
  bus address:		0x40000000
 
-(but there are also alpha's where the physical address and the bus address
+(but there are also Alphas where the physical address and the bus address
 are the same). 
 
 Anyway, the way to look up all these translations, you do
@@ -169,7 +169,7 @@
 
 Ok, that just about covers the basics of accessing IO portably.  Questions?
 Comments? You may think that all the above is overly complex, but one day you
-might find yourself with a 500MHz alpha in front of you, and then you'll be
+might find yourself with a 500 MHz Alpha in front of you, and then you'll be
 happy that your driver works ;)
 
 Note that kernel versions 2.0.x (and earlier) mistakenly called the
diff -u --recursive --new-file v2.1.103/linux/Documentation/SMP.txt linux/Documentation/SMP.txt
--- v2.1.103/linux/Documentation/SMP.txt	Mon May  6 02:26:01 1996
+++ linux/Documentation/SMP.txt	Wed May 20 18:54:34 1998
@@ -19,7 +19,7 @@
 o	Clean up warnings/volatiles.
 o	Fix load_TR() for non contiguous processor ids
 o	Iterate over the slave timer requests if one is lost (keep a count per cpu)
-o	Distribute irq's (locking present just needs the 82489 to be asked
+o	Distribute IRQs (locking present just needs the 82489 to be asked
 	nicely).
 o	486 startup code.
 o	How to handle mixed FPU/non FPU processors.
diff -u --recursive --new-file v2.1.103/linux/Documentation/cdrom/00-INDEX linux/Documentation/cdrom/00-INDEX
--- v2.1.103/linux/Documentation/cdrom/00-INDEX	Sun Dec 28 12:05:44 1997
+++ linux/Documentation/cdrom/00-INDEX	Thu Jun  4 22:53:50 1998
@@ -1,8 +1,9 @@
 00-INDEX
 	- this file (info on CD-ROMs and Linux)
+Makefile
+	- only used to generate TeX output from the documentation.
 aztcd
 	- info on Aztech/Orchid/Okano/Wearnes/Conrad/CyCDROM driver.
-
 cdrom-standard.tex
 	- LaTeX document on standardizing the CD-ROM programming interface.
 cdu31a
diff -u --recursive --new-file v2.1.103/linux/Documentation/cdrom/aztcd linux/Documentation/cdrom/aztcd
--- v2.1.103/linux/Documentation/cdrom/aztcd	Sat May  2 14:19:50 1998
+++ linux/Documentation/cdrom/aztcd	Wed May 20 18:54:34 1998
@@ -173,7 +173,7 @@
 If you did not set the correct base address in aztcd.h, you can also supply the
 base address when loading the driver via
                     insmod /lib/modules/X.X.X/misc/aztcd.o aztcd=<base address>
-Again specifing aztcd=-1 will cause autoprobing.
+Again specifying aztcd=-1 will cause autoprobing.
 If you do not have the iso9660-filesystem in your boot kernel, you also have
 to load it before you can mount the CDROM:
                     insmod /lib/modules/X.X.X/fs/isofs.o
diff -u --recursive --new-file v2.1.103/linux/Documentation/cdrom/sbpcd linux/Documentation/cdrom/sbpcd
--- v2.1.103/linux/Documentation/cdrom/sbpcd	Sat May  2 14:19:50 1998
+++ linux/Documentation/cdrom/sbpcd	Wed May 20 18:54:34 1998
@@ -304,8 +304,8 @@
 specify "block=2048" as a mount option. Doing this will disable the direct
 execution of a binary from the CD; you have to copy it to a device with the
 standard BLOCK_SIZE (1024) first. So, do not use this if your system is
-directly "running from the CDROM" (like some of YGGDRASIL's installation
-variants). There are CDs on the market (like the german "unifix" Linux
+directly "running from the CDROM" (like some of Yggdrasil's installation
+variants). There are CDs on the market (like the German "unifix" Linux
 distribution) which MUST get handled with a block_size of 1024. Generally,
 one can say all the CDs which hold files of the name YMTRANS.TBL are defective;
 do not use block=2048 with those.
diff -u --recursive --new-file v2.1.103/linux/Documentation/cdrom/sonycd535 linux/Documentation/cdrom/sonycd535
--- v2.1.103/linux/Documentation/cdrom/sonycd535	Sat May  2 14:19:50 1998
+++ linux/Documentation/cdrom/sonycd535	Wed May 20 18:54:34 1998
@@ -1,7 +1,7 @@
               README FOR LINUX SONY CDU-535/531 DRIVER
               ========================================
 
-This is the the Sony CDU-535 (and 531) driver version 0.7 for Linux.
+This is the Sony CDU-535 (and 531) driver version 0.7 for Linux.
 I do not think I have the documentation to add features like DMA support
 so if anyone else wants to pursue it or help me with it, please do.
 (I need to see what was done for the CDU-31A driver -- perhaps I can
diff -u --recursive --new-file v2.1.103/linux/Documentation/devices.txt linux/Documentation/devices.txt
--- v2.1.103/linux/Documentation/devices.txt	Mon Feb 23 18:12:01 1998
+++ linux/Documentation/devices.txt	Wed May 20 18:54:34 1998
@@ -236,7 +236,7 @@
 		  1 = /dev/loop1	Second loopback device
 		      ...
 
-		The loopback devices are used to mount filesystems not
+		The loopback devices are used to mount file systems not
 		associated with block devices.	The binding to the
 		loopback devices is handled by mount(8) or losetup(8).
 
@@ -288,7 +288,7 @@
 		      ...
 
 		The metadisk driver is used to span a
-		filesystem across multiple physical disks.
+		file system across multiple physical disks.
 
  10 char	Non-serial mice, misc features
 		  0 = /dev/logibm	Logitech bus mouse
@@ -387,11 +387,11 @@
 		 33 = /dev/patmgr1	Sequencer patch manager
 		 34 = /dev/midi02	Third MIDI port
 		 50 = /dev/midi03	Fourth MIDI port
-    block	BIOS harddrive callback support
-		  0 = /dev/dos_hda	First BIOS harddrive whole disk
-		 64 = /dev/dos_hdb	Second BIOS harddrive whole disk
-		128 = /dev/dos_hdc	Third BIOS harddrive whole disk
-		192 = /dev/dos_hdd	Fourth BIOS harddrive whole disk
+    block	BIOS hard drive callback support
+		  0 = /dev/dos_hda	First BIOS hard drive whole disk
+		 64 = /dev/dos_hdb	Second BIOS hard drive whole disk
+		128 = /dev/dos_hdc	Third BIOS hard drive whole disk
+		192 = /dev/dos_hdd	Fourth BIOS hard drive whole disk
 
 		Partitions are handled in the same way as IDE disks
 		(see major number 3).
@@ -785,18 +785,18 @@
 		  1 = /dev/nb1		Second network block device
 		      ...
 
-		Network Block Device is somehow similar to loopback
-		devices: If you read from it, it sends packet accross
-		network asking server for data. If you write to it, it
-		sends packet telling server to write. It could be used
-		to mounting filesystems over the net, swapping over
-		the net, implementing block device in userland etc.
+		The network block device is similar to a loopback device:
+		if you read from it, it sends packets across the network
+		asking the server for data. If you write to it, it sends
+		packets telling the server to write. It could be used to
+		mount file systems over the net, swap over the net, 
+		implement block devices in userland, etc.
 
  44 char	isdn4linux virtual modem - alternate devices
 		  0 = /dev/cui0		Callout device corresponding to ttyI0
 		      ...
 		 63 = /dev/cui63	Callout device corresponding to ttyI63
-    block	Flash Translatio Layer (FTL) filesystems
+    block	Flash Translation Layer (FTL) file systems
 		  0 = /dev/ftla		FTL on first Memory Technology Device
 		 16 = /dev/ftlb		FTL on second Memory Technology Device
 		 32 = /dev/ftlc		FTL on third Memory Technology Device
@@ -1247,7 +1247,7 @@
 /dev/cdwriter	CD-writer	symbolic	Current CD-writer device
 /dev/scanner	scanner		symbolic	Current scanner device
 /dev/modem	modem port	symbolic	Current dialout device
-/dev/root	root device	symbolic	Current root filesystem
+/dev/root	root device	symbolic	Current root file system
 /dev/swap	swap device	symbolic	Current swap device
 
 /dev/modem should not be used for a modem which supports dialin as
@@ -1280,7 +1280,7 @@
 pseudoterminals (PTYs).
 
 All terminal devices share a common set of capabilities known as line
-diciplines; these include the common terminal line dicipline as well
+disciplines; these include the common terminal line discipline as well
 as SLIP and PPP modes.
 
 All terminal devices are named similarly; this section explains the
@@ -1359,7 +1359,7 @@
 	Pseudoterminals (PTYs)
 
 Pseudoterminals, or PTYs, are used to create login sessions or provide
-other capabilities requiring a TTY line dicipline (including SLIP or
+other capabilities requiring a TTY line discipline (including SLIP or
 PPP capability) to arbitrary data-generation processes.  Each PTY has
 a master side, named /dev/pty[p-za-e][0-9a-f], and a slave side, named
 /dev/tty[p-za-e][0-9a-f].  The kernel arbitrates the use of PTYs by
diff -u --recursive --new-file v2.1.103/linux/Documentation/exception.txt linux/Documentation/exception.txt
--- v2.1.103/linux/Documentation/exception.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/exception.txt	Wed May 20 18:54:34 1998
@@ -36,21 +36,21 @@
 
 do_page_fault first obtains the unaccessible address from the CPU 
 control register CR2. If the address is within the virtual address 
-space of the process, the fault probably occured, because the page 
-was not swapped in, write protected or something similiar. However, 
+space of the process, the fault probably occurred, because the page 
+was not swapped in, write protected or something similar. However, 
 we are interested in the other case: the address is not valid, there 
 is no vma that contains this address. In this case, the kernel jumps 
 to the bad_area label. 
 
 There it uses the address of the instruction that caused the exception 
-(i.e. regs->eip) to find an address where the excecution can continue 
+(i.e. regs->eip) to find an address where the execution can continue 
 (fixup). If this search is successful, the fault handler modifies the 
 return address (again regs->eip) and returns. The execution will 
 continue at the address in fixup.
 
 Where does fixup point to?
 
-Since we jump to the the contents of fixup, fixup obviously points 
+Since we jump to the contents of fixup, fixup obviously points 
 to executable code. This code is hidden inside the user access macros. 
 I have picked the get_user macro defined in include/asm/uacess.h as an
 example. The definition is somewhat hard to follow, so let's peek at 
diff -u --recursive --new-file v2.1.103/linux/Documentation/filesystems/00-INDEX linux/Documentation/filesystems/00-INDEX
--- v2.1.103/linux/Documentation/filesystems/00-INDEX	Sat May  2 14:19:51 1998
+++ linux/Documentation/filesystems/00-INDEX	Thu Jun  4 22:53:50 1998
@@ -5,8 +5,7 @@
 coda.txt
 	- description of the CODA filesystem.
 fat_cvf.txt
-	- Description of the Compressed Volume Files extension to the FAT
-	  filesystem
+	- info on the Compressed Volume Files extension to the FAT filesystem
 hpfs.txt
 	- info and mount options for the OS/2 HPFS.
 isofs.txt
diff -u --recursive --new-file v2.1.103/linux/Documentation/ftape.txt linux/Documentation/ftape.txt
--- v2.1.103/linux/Documentation/ftape.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/ftape.txt	Wed May 20 18:54:34 1998
@@ -118,7 +118,7 @@
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ftape-2.x didn't handle the MTBSF tape operation correctly. A MTBSF
    call (i.e. "mt -f /dev/nqft0 bsf #COUNT") should space over #COUNT
-   file marks and then position at the EOT tape side of the the file
+   file marks and then position at the EOT tape side of the file
    mark. This has to be taken literally, i.e. "mt -f /dev/nqft0 bsf 1"
    should simply position at the start of the current volume.
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/hayes-esp.txt linux/Documentation/hayes-esp.txt
--- v2.1.103/linux/Documentation/hayes-esp.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/hayes-esp.txt	Wed May 20 18:54:34 1998
@@ -143,7 +143,7 @@
 
 The ESP module and the serial module should not conflict (they can be used at
 the same time).  After the ESP module has been loaded the ports on the ESP card
-will no longer be accessable by the serial driver.
+will no longer be accessible by the serial driver.
 
 If I/O errors are experienced when accessing the port, check for IRQ and DMA
 conflicts ('cat /proc/interrupts' and 'cat /proc/dma' for a list of IRQs and
diff -u --recursive --new-file v2.1.103/linux/Documentation/ide.txt linux/Documentation/ide.txt
--- v2.1.103/linux/Documentation/ide.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/ide.txt	Wed May 20 18:54:34 1998
@@ -136,7 +136,7 @@
 Note that the first parameter reserves 8 contiguous ioports, whereas the
 second value denotes a single ioport. If in doubt, do a 'cat /proc/ioports'.
 
-In all probability the device uses these ports and irqs if it is attached
+In all probability the device uses these ports and IRQs if it is attached
 to the appropriate ide channel.  Pass the parameter for the correct ide
 channel to the kernel, as explained above.
 
@@ -181,7 +181,7 @@
 
 Courtesy of Scott Snyder, the driver supports ATAPI cdrom drives
 such as the NEC-260 and the new MITSUMI triple/quad speed drives.
-Such drives will be identified at boot time, just like a harddisk.
+Such drives will be identified at boot time, just like a hard disk.
 
 If for some reason your cdrom drive is *not* found at boot time, you can force
 the probe to look harder by supplying a kernel command line parameter
@@ -191,7 +191,7 @@
 or
 	hdd=cdrom	/* hdd = "slave" on second interface */
 
-For example, a GW2000 system might have a harddrive on the primary
+For example, a GW2000 system might have a hard drive on the primary
 interface (/dev/hda) and an IDE cdrom drive on the secondary interface
 (/dev/hdc).  To mount a CD in the cdrom drive, one would use something like:
 
@@ -450,7 +450,7 @@
 must reside within the first 1024 cylinders of the drive.  If your linux
 root partition is *not* completely within the first 1024 cyls (quite common),
 then you can use LILO to boot linux from files on your DOS partition
-by doing the following after installing slackware (or whatever):
+by doing the following after installing Slackware (or whatever):
 
 	0. Boot from the "boot floppy" created during the installation
         1. Mount your DOS partition as /dos (and stick it in /etc/fstab)
diff -u --recursive --new-file v2.1.103/linux/Documentation/initrd.txt linux/Documentation/initrd.txt
--- v2.1.103/linux/Documentation/initrd.txt	Thu Apr 11 23:49:29 1996
+++ linux/Documentation/initrd.txt	Thu Jun  4 22:53:50 1998
@@ -93,7 +93,7 @@
 
 First, the "normal" root file system has to be prepared as follows:
 
-# mknod /dev/initrd b 0 250 
+# mknod /dev/initrd b 1 250 
 # chmod 400 /dev/initrd
 # mkdir /initrd
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/isdn/README linux/Documentation/isdn/README
--- v2.1.103/linux/Documentation/isdn/README	Sat May  2 14:19:51 1998
+++ linux/Documentation/isdn/README	Wed May 20 18:54:34 1998
@@ -387,7 +387,7 @@
    command "isdnctrl addphone <InterfaceName> in <caller-id>"
    Euro-ISDN does not transmit the leading '0' of the caller-id for an
    incoming call, therefore you should configure it accordingly.
-   If the real number for the dialout e.g. is "09311234567" the the number
+   If the real number for the dialout e.g. is "09311234567" the number
    to configure here is "9311234567". The pattern-match function 
    works similar to the shell mechanism.
 
@@ -408,7 +408,7 @@
    Returns the EAZ of an interface.
 
    "isdnctrl delphone <InterfaceName> in|out <number>" 
-   Deletes a number from one of the the access-lists of the interface.
+   Deletes a number from one of the access-lists of the interface.
 
    "isdnctrl delif <InterfaceName>" 
    Removes the interface (and possible slaves) from the kernel.
diff -u --recursive --new-file v2.1.103/linux/Documentation/m68k/framebuffer.txt linux/Documentation/m68k/framebuffer.txt
--- v2.1.103/linux/Documentation/m68k/framebuffer.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/m68k/framebuffer.txt	Wed Jun  3 12:39:40 1998
@@ -315,7 +315,7 @@
 
 All necessary files can be found at
 
-    ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/
+    ftp://ftp.uni-erlangen.de/pub/Linux/680x0/
 
 and on its mirrors.
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/00-INDEX linux/Documentation/networking/00-INDEX
--- v2.1.103/linux/Documentation/networking/00-INDEX	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/00-INDEX	Wed May 20 18:54:34 1998
@@ -73,7 +73,7 @@
 tcp.txt
 	- short blurb on how TCP output takes place.
 tulip.txt
-	- info on using DEC 21040/21041/21140 based PCI ethernet cards.
+	- info on using DEC 21040/21041/21140 based PCI Ethernet cards.
 vortex.txt
 	- info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) e'net cards.
 wan-router.txt
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/DLINK.txt linux/Documentation/networking/DLINK.txt
--- v2.1.103/linux/Documentation/networking/DLINK.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/DLINK.txt	Wed May 20 18:54:34 1998
@@ -72,7 +72,7 @@
 
 	o Get the latest net binaries, according to current net.wisdom.
 
-	o Read the NET-2 and Ethernet HOWTO's and modify your setup.
+	o Read the NET-2 and Ethernet HOWTOs and modify your setup.
 
 	o If your parallel port has a strange address or irq,
 	  modify "linux/drivers/net/CONFIG" accordingly, or adjust
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/PLIP.txt linux/Documentation/networking/PLIP.txt
--- v2.1.103/linux/Documentation/networking/PLIP.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/PLIP.txt	Wed May 20 18:54:34 1998
@@ -45,13 +45,13 @@
 
 Doesn't work over a modem, like SLIP and PPP. Limited range, 15 m.
 Can only be used to connect three (?) Linux boxes. Doesn't connect to
-an existing ethernet. Isn't standard (not even de facto standard, like
+an existing Ethernet. Isn't standard (not even de facto standard, like
 SLIP).
 
 Performance
 ==========
 
-PLIP easily outperforms ethernet cards....(ups, I was dreaming, but
+PLIP easily outperforms Ethernet cards....(ups, I was dreaming, but
 it *is* getting late. EOB)
 
 PLIP hardware interconnection
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/arcnet-hardware.txt linux/Documentation/networking/arcnet-hardware.txt
--- v2.1.103/linux/Documentation/networking/arcnet-hardware.txt	Thu Sep  4 13:25:28 1997
+++ linux/Documentation/networking/arcnet-hardware.txt	Wed May 20 18:54:34 1998
@@ -17,11 +17,11 @@
 INTRODUCTION TO ARCNET
 ----------------------
 
-ARCnet is a network type which works in a way similar to popular "ethernet"
+ARCnet is a network type which works in a way similar to popular Ethernet
 networks but which is also different in some very important ways.
 
 First of all, you can get ARCnet cards in at least two speeds: 2.5Mbps
-(slower than ethernet) and 100Mbps (faster than normal ethernet).  In fact,
+(slower than Ethernet) and 100Mbps (faster than normal Ethernet).  In fact,
 there are others as well, but these are less common.  The different hardware
 types, as far as I'm aware, are not compatible and so you cannot wire a
 100Mbps card to a 2.5Mbps card, and so on.  From what I hear, my driver does
@@ -29,7 +29,7 @@
 since I only have the 2.5Mbps variety.  It is probably not going to saturate
 your 100Mbps card.  Stop complaining :)
 
-You also cannot connect an ARCnet card to any kind of ethernet card and
+You also cannot connect an ARCnet card to any kind of Ethernet card and
 expect it to work.  
 
 There are two "types" of ARCnet - STAR topology and BUS topology.  This
@@ -41,7 +41,7 @@
 Once you get past these little stumbling blocks, ARCnet is actually quite a
 well-designed standard.  It uses something called "modified token passing"
 which makes it completely incompatible with so-called "Token Ring" cards,
-but which makes transfers much more reliable than ethernet does.  In fact,
+but which makes transfers much more reliable than Ethernet does.  In fact,
 ARCnet will guarantee that a packet arrives safely at the destination, and
 even if it can't possibly be delivered properly (ie. because of a cable
 break, or because the destination computer does not exist) it will at least
@@ -53,9 +53,9 @@
 
 In addition, all known ARCnet cards have an (almost) identical programming
 interface.  This means that with one "arcnet" driver you can support any
-card; whereas, with ethernet, each manufacturer uses what is sometimes a
+card; whereas, with Ethernet, each manufacturer uses what is sometimes a
 completely different programming interface, leading to a lot of different,
-sometimes very similar, ethernet drivers.  Of course, always using the same
+sometimes very similar, Ethernet drivers.  Of course, always using the same
 programming interface also means that when high-performance hardware
 facilities like PCI busmastering DMA appear, it's hard to take advantage of
 them.  Let's not go into that.
@@ -63,10 +63,10 @@
 One thing that makes ARCnet cards difficult to program for, however, is the
 limit on their packet sizes; standard ARCnet can only send packets that are
 up to 508 bytes in length.  This is smaller than the internet "bare minimum"
-of 576 bytes, let alone the ethernet MTU of 1500.  To compensate, an extra
+of 576 bytes, let alone the Ethernet MTU of 1500.  To compensate, an extra
 level of encapsulation is defined by RFC1201, which I call "packet
 splitting," that allows "virtual packets" to grow as large as 64K each,
-although they are generally kept down to the ethernet-style 1500 bytes.
+although they are generally kept down to the Ethernet-style 1500 bytes.
 
 For more information on the advantages and disadvantages (mostly the
 advantages) of ARCnet networks, you might try the "ARCnet Trade Association"
@@ -319,7 +319,7 @@
 	- Avery's favourite: 0xD0000
 
   - the station address:  Every ARCnet card has its own "unique" network
-    address from 0 to 255.  Unlike ethernet, you can set this address
+    address from 0 to 255.  Unlike Ethernet, you can set this address
     yourself with a jumper or switch (or on some cards, with special
     software).  Since it's only 8 bits, you can only have 254 ARCnet cards
     on a network.  DON'T use 0 or 255, since these are reserved (although
@@ -1169,7 +1169,7 @@
 
 DIP Switches:
 
-	The dipswitches accessible on the accessible end of the card while
+	The DIP switches accessible on the accessible end of the card while
         it is installed, is used to set the arcnet address.  There are 8
         switches.  Use an address from 1 to 254.
 
@@ -1184,7 +1184,7 @@
 	11111110	1
 	11111111	0	(Don't use this!)
 
-	There is another dipswitch array of 8 switches at the top of the
+	There is another array of eight DIP switches at the top of the
         card.  There are five labelled MS0-MS4 which seem to control the
         memory address, and another three labelled IO0-IO2 which seem to
         control the base I/O address of the card.
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/arcnet.txt linux/Documentation/networking/arcnet.txt
--- v2.1.103/linux/Documentation/networking/arcnet.txt	Thu Sep  4 13:25:28 1997
+++ linux/Documentation/networking/arcnet.txt	Wed May 20 18:54:34 1998
@@ -216,10 +216,10 @@
 
 Go read the NET-2-HOWTO and ETHERNET-HOWTO for Linux; they should be
 available where you picked up this driver.  Think of your ARCnet as a
-souped-up (or down, as the case may be) ethernet card.
+souped-up (or down, as the case may be) Ethernet card.
 
 By the way, be sure to change all references from "eth0" to "arc0" in the
-HOWTOs.  Remember that ARCnet isn't a "true" ethernet, and the device name
+HOWTOs.  Remember that ARCnet isn't a "true" Ethernet, and the device name
 is DIFFERENT.
 
 
@@ -245,7 +245,7 @@
 How do I get it to work with...?
 --------------------------------
 
-NFS: Should be fine linux->linux, just pretend you're using ethernet cards. 
+NFS: Should be fine linux->linux, just pretend you're using Ethernet cards. 
         oak.oakland.edu:/simtel/msdos/nfs has some nice DOS clients.  There
         is also a DOS-based NFS server called SOSS.  It doesn't multitask
         quite the way Linux does (actually, it doesn't multitask AT ALL) but
@@ -271,7 +271,7 @@
 
 LAN Manager and Windows for Workgroups: These programs use protocols that
         are incompatible with the internet standard.  They try to pretend
-        the cards are ethernet, and confuse everyone else on the network. 
+        the cards are Ethernet, and confuse everyone else on the network. 
         
         However, v2.00 and higher of the Linux ARCnet driver supports this
         protocol via the 'arc0e' device.  See the section on "Multiprotocol
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/cs89x0.txt linux/Documentation/networking/cs89x0.txt
--- v2.1.103/linux/Documentation/networking/cs89x0.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/cs89x0.txt	Wed May 20 18:54:34 1998
@@ -72,7 +72,7 @@
 1.2.2 Files in the Driver Archive:
 
   readme.txt  - this file
-  release.txt - known defects and modifcation log
+  release.txt - known defects and modification log
   cs89x0.c    - driver C code
   cs89x0.h    - driver header file
   cs89x0.o    - pre-compiled module (for v2.0 kernel)
@@ -196,7 +196,7 @@
 
     insmod cs89x0.o io=0x200 irq=0xA media=aui
 
-This exmaple loads the module and configures the adapter to use an IO port base
+This example loads the module and configures the adapter to use an IO port base
 address of 200h, interrupt 10, and use the AUI media connection.  The following
 configuration options are available on the command line:
 
@@ -235,7 +235,7 @@
   * irq 
   * media type (no autodetect)
 
-The following addtional parameters are CS89XX defaults (values used with no 
+The following additional parameters are CS89XX defaults (values used with no 
 EEPROM or command-line argument).
 
   * DMA Burst = enabled
@@ -545,8 +545,8 @@
                                               12       Mouse (PS/2)                              
 Memory Address  Device                        13       Math Coprocessor
 --------------  ---------------------         14       Hard Disk controller
-A000-BFFF	EGA Graphics Adpater
-A000-C7FF	VGA Graphics Adpater
+A000-BFFF	EGA Graphics Adapter
+A000-C7FF	VGA Graphics Adapter
 B000-BFFF	Mono Graphics Adapter
 B800-BFFF	Color Graphics Adapter
 E000-FFFF	AT BIOS
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/de4x5.txt linux/Documentation/networking/de4x5.txt
--- v2.1.103/linux/Documentation/networking/de4x5.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/de4x5.txt	Wed May 20 18:54:34 1998
@@ -1,5 +1,5 @@
     Originally,   this  driver  was    written  for the  Digital   Equipment
-    Corporation series of EtherWORKS ethernet cards:
+    Corporation series of EtherWORKS Ethernet cards:
 
         DE425 TP/COAX EISA
 	DE434 TP PCI
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/dgrs.txt linux/Documentation/networking/dgrs.txt
--- v2.1.103/linux/Documentation/networking/dgrs.txt	Sat Nov 29 10:33:18 1997
+++ linux/Documentation/networking/dgrs.txt	Wed May 20 18:54:34 1998
@@ -1,7 +1,7 @@
 	The Digi Intl. RightSwitch SE-X (dgrs) Device Driver
 
 This is a Linux driver for the Digi International RightSwitch SE-X
-EISA and PCI boards.  These are 4 (EISA) or 6 (PCI) port ethernet
+EISA and PCI boards.  These are 4 (EISA) or 6 (PCI) port Ethernet
 switches and a NIC combined into a single board.  This driver can
 be compiled into the kernel statically or as a loadable module.
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/eql.txt linux/Documentation/networking/eql.txt
--- v2.1.103/linux/Documentation/networking/eql.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/eql.txt	Wed May 20 18:54:34 1998
@@ -33,7 +33,7 @@
   TCP implementation is pretty fast though.--)
 
 
-  I suggest to ISP's out there that it would probably be fair to charge
+  I suggest to ISPs out there that it would probably be fair to charge
   a load-balancing client 75% of the cost of the second line and 50% of
   the cost of the third line etc...
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/ethertap.txt linux/Documentation/networking/ethertap.txt
--- v2.1.103/linux/Documentation/networking/ethertap.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/ethertap.txt	Wed May 20 18:54:34 1998
@@ -7,7 +7,7 @@
 ============
 
 Ethertap provides packet reception and transmission for user
-space programs. It can be viewed as a simple ethernet device,
+space programs. It can be viewed as a simple Ethernet device,
 which instead of receiving packets from a network wire, it receives
 them from user space.
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/ewrk3.txt linux/Documentation/networking/ewrk3.txt
--- v2.1.103/linux/Documentation/networking/ewrk3.txt	Sat Nov 29 10:33:18 1997
+++ linux/Documentation/networking/ewrk3.txt	Wed May 20 18:54:34 1998
@@ -35,9 +35,9 @@
     'ifconfig eth?? down' then 'rmmod ewrk3'.
 
 The performance we've  achieved so far  has been measured through the 'ttcp'
-tool   at 975kB/s.  This  measures  the  total  tcp  stack performance which
+tool   at 975kB/s.  This  measures  the  total  TCP  stack performance which
 includes the   card,  so don't  expect   to get   much nearer  the  1.25MB/s
-theoretical ethernet rate.
+theoretical Ethernet rate.
 
 
 Enjoy!
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/filter.txt linux/Documentation/networking/filter.txt
--- v2.1.103/linux/Documentation/networking/filter.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/filter.txt	Thu Jun  4 22:53:50 1998
@@ -15,7 +15,7 @@
 (BPF), so refering to the BSD bpf.4 manpage is very helpful in
 creating filters.
 
-LSF is much simpler that BPF. One does not have to worry about
+LSF is much simpler than BPF. One does not have to worry about
 devices or anything like that. You simply create your filter
 code, send it to the kernel via the SO_ATTACH_FILTER ioctl and
 if your filter code passes the kernel check on it, you then
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/lapb-module.txt linux/Documentation/networking/lapb-module.txt
--- v2.1.103/linux/Documentation/networking/lapb-module.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/lapb-module.txt	Wed May 20 18:54:34 1998
@@ -6,7 +6,7 @@
 the Linux operating system that require a LAPB service. This document
 defines the interfaces to, and the services provided by this module. The
 term module in this context does not imply that the LAPB module is a
-seperately loadable module, although it may be. The term module is used in
+separately loadable module, although it may be. The term module is used in
 its more standard meaning.
 
 The interface to the LAPB module consists of functions to the module,
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/multicast.txt linux/Documentation/networking/multicast.txt
--- v2.1.103/linux/Documentation/networking/multicast.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/multicast.txt	Thu Jun  4 22:53:50 1998
@@ -1,6 +1,5 @@
 Behaviour of cards under Multicast. This is how they currently 
-behave not what the hardware can do. In particular all the 8390 based
-cards don't use the onboard hash filter, and the lance driver doesn't
+behave not what the hardware can do - i.e. the lance driver doesn't
 use its filter, even though the code for loading it is in the DEC
 lance based driver.
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/soundmodem.txt linux/Documentation/networking/soundmodem.txt
--- v2.1.103/linux/Documentation/networking/soundmodem.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/soundmodem.txt	Wed May 20 18:54:34 1998
@@ -2,13 +2,13 @@
 
        Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
 
-This driver allows either SoundBlaster (sbc) or WindowsSoundSystem (wss)
+This driver allows either SoundBlaster (sbc) or Windows Sound System (wss)
 compatible soundcards to be used as either 1200 baud AFSK or 9600 baud FSK
 AX.25 packet radio modems. Only half duplex operation is supported; an
 attempt to include full duplex support failed because the hardware did
 not support it (it appeared that the card only provides one DMA channel,
-although the Codec chip would support two channels). The driver needs
-some processing power! A 486DX/2 66MHz is a minimum requirement, otherwise
+although the codec chip would support two channels). The driver needs
+some processing power! A 66 MHz 486 DX2 is a minimum requirement.  Otherwise
 interactive performance of the computer may become sluggish. This driver
 does *not* support telephone modem standards, it is intended for radio
 use only.
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/tulip.txt linux/Documentation/networking/tulip.txt
--- v2.1.103/linux/Documentation/networking/tulip.txt	Mon Apr 22 01:27:41 1996
+++ linux/Documentation/networking/tulip.txt	Wed May 20 18:54:34 1998
@@ -1,7 +1,7 @@
-                Tulip ethernet card driver
+                Tulip Ethernet Card Driver
 
 The Tulip driver is developed by Donald Becker and changed by
-Takashi Manabe. This driver is designed to work with PCI ethernet
+Takashi Manabe. This driver is designed to work with PCI Ethernet
 cards which use the DECchip DC21x4x family. This driver hopefully
 works with all of 1.2.x and 1.3.x kernels, but I tested only
 with 1.2.13, 1.3.39, 1.3.49, 1.3.52, 1.3.57 and later.
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/wan-router.txt linux/Documentation/networking/wan-router.txt
--- v2.1.103/linux/Documentation/networking/wan-router.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/wan-router.txt	Wed May 20 18:54:34 1998
@@ -41,7 +41,7 @@
 operating system and provides generic hardware-independent services for such
 drivers.  Why can existing Linux network device interface not be used for
 this purpose?  Well, it can.  However, there are a few key differences between
-a typical network interface (e.g. ethernet) and a WAN link.
+a typical network interface (e.g. Ethernet) and a WAN link.
 
 Many WAN protocols, such as X.25 and frame relay, allow for multiple logical
 connections (known as `virtual circuits' in X.25 terminology) over a single
@@ -50,7 +50,7 @@
 result, it is the virtual circuit, not the physical link, that represents a
 route and, therefore, a network interface in Linux terms.
 
-To further complicate things, virtual cuircits are usually volatile in nature
+To further complicate things, virtual circuits are usually volatile in nature
 (excluding so called `permanent' virtual circuits or PVCs).  With almost no
 time required to set up and tear down a virtual circuit, it is highly desirable
 to implement on-demand connections in order to minimize network charges.  So
@@ -59,7 +59,7 @@
 and go away dynamically.
  
 Last, but not least, WAN configuration is much more complex than that of say
-ethernet and may well amount to several dozens of parameters.  Some of them
+Ethernet and may well amount to several dozens of parameters.  Some of them
 are "link-wide"  while others are virtual circuit-specific.  The same holds
 true for WAN statistics which is by far more extensive and extremely useful
 when troubleshooting WAN connections.  Extending the ifconfig utility to suit
@@ -71,9 +71,9 @@
 provide a user with more-or-less standard look and feel for all WAN devices and
 assist a WAN device driver writer by providing common services, such as:
 
- o User-level interface via /proc filesystem
+ o User-level interface via /proc file system
  o Centralized configuration
- o Device managenent (setup, shutdown, etc.)
+ o Device management (setup, shutdown, etc.)
  o Network interface management (dynamic creation/destruction)
  o Protocol encapsulation/decapsulation
 
@@ -84,7 +84,7 @@
 			or
 	ftp.sangoma.com/pub/linux/vX.Y.Z/wanpipe-X.Y.Z.tgz
 
-where vX.Y.Z represent the linux kernel version number.
+where vX.Y.Z represent the Linux kernel version number.
 
 For technical questions and/or comments regarding this product please e-mail
 to jaspreet@sangoma.com or dm@sangoma.com.
@@ -107,7 +107,7 @@
 
 
 
-ACKNOLEGEMENTS
+ACKNOWLEDGMENTS
 
 This product is based on the WANPIPE(tm) Multiprotocol WAN Router developed
 by Sangoma Technologies Inc. for Linux 1.2.x.  Release of Linux 2.0 in summer
@@ -173,7 +173,7 @@
 1.0.1	January 30, 1997
 
 			      -	Implemented user-readable status and statistics
-				via /proc filesystem
+				via /proc file system
 
 1.0.0	December 31, 1996
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/networking/z8530drv.txt linux/Documentation/networking/z8530drv.txt
--- v2.1.103/linux/Documentation/networking/z8530drv.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/networking/z8530drv.txt	Wed May 20 18:54:34 1998
@@ -254,7 +254,7 @@
 clock dpll		# clock source: 
 			# 	dpll     = normal halfduplex operation
 			# 	external = MODEM provides own Rx/Tx clock
-			#	divider  = use fullduplex divider if
+			#	divider  = use full duplex divider if
 			#		   installed (1)
 mode nrzi		# HDLC encoding mode
 			#	nrzi = 1k2 MODEM, G3RUH 9k6 MODEM
@@ -450,7 +450,7 @@
      Example: sccparam /dev/scc3 speed 9600
 
 txdelay:
-     The delay (in units of 10ms) after keying of the 
+     The delay (in units of 10 ms) after keying of the 
      transmitter, until the first byte is sent. This is usually 
      called "TXDELAY" in a TNC.  When 0 is specified, the driver 
      will just wait until the CTS signal is asserted. This 
@@ -472,7 +472,7 @@
 
 slottime:
      This is the time between samples of the channel. It is 
-     expressed in units of 10ms.  About 200-300 ms (value 20-30) 
+     expressed in units of 10 ms.  About 200-300 ms (value 20-30) 
      seems to be a good value.
 
      Example: sccparam /dev/scc0 slot 20
@@ -484,7 +484,7 @@
      SCC before the transmitter is keyed down. The value depends 
      on the baudrate selected.  A few character times should be 
      sufficient, e.g. 40ms at 1200 baud. (value 4)
-     The value of this parameter is in 10ms units.
+     The value of this parameter is in 10 ms units.
 
      Example: sccparam /dev/scc2 4
 
@@ -507,9 +507,9 @@
 wait:
      The initial waittime before any transmit attempt, after the 
      frame has been queue for transmit.  This is the length of 
-     the first slot in CSMA mode.  In fullduplex modes it is
+     the first slot in CSMA mode.  In full duplex modes it is
      set to 0 for maximum performance.
-     The value of this parameter is in 10ms units. 
+     The value of this parameter is in 10 ms units. 
 
      Example: sccparam /dev/scc1 wait 4
 
@@ -534,7 +534,7 @@
      Example: sccparam /dev/scc3 min 10
 
 idle
-     This parameter specifies the maximum idle time in fullduplex 
+     This parameter specifies the maximum idle time in full duplex 
      2 mode, in seconds.  When no frames have been sent for this 
      time, the transmitter will be keyed down.  A value of 0 is
      has same result as the fullduplex mode 1. This parameter
diff -u --recursive --new-file v2.1.103/linux/Documentation/nfsroot.txt linux/Documentation/nfsroot.txt
--- v2.1.103/linux/Documentation/nfsroot.txt	Sat May  2 14:19:51 1998
+++ linux/Documentation/nfsroot.txt	Wed May 20 18:54:34 1998
@@ -116,7 +116,7 @@
 		classful addressing, unless overridden in BOOTP reply.
 
   <hostname>	Name of the client. If empty, the client IP address is
-		used in ASCII-notation, or the value received by BOOTP.
+		used in ASCII notation, or the value received by BOOTP.
 
   <device>	Name of network device to use. If this is empty, all
 		devices are used for RARP and BOOTP requests, and the
diff -u --recursive --new-file v2.1.103/linux/Documentation/paride.txt linux/Documentation/paride.txt
--- v2.1.103/linux/Documentation/paride.txt	Wed May 20 19:10:36 1998
+++ linux/Documentation/paride.txt	Wed May 20 18:54:34 1998
@@ -12,7 +12,7 @@
 to pass commands and data through the parallel port interface, most 
 external devices are actually identical to an internal model, but with
 a parallel-port adapter chip added in.  Some of the original parallel port
-adapters were little more than mechanisms for mulitplexing a SCSI bus.
+adapters were little more than mechanisms for multiplexing a SCSI bus.
 (The Iomega PPA-3 adapter used in the ZIP drives is an example of this
 approach).  Most current designs, however, take a different approach.
 The adapter chip reproduces a small ISA or IDE bus in the external device
diff -u --recursive --new-file v2.1.103/linux/Documentation/rtc.txt linux/Documentation/rtc.txt
--- v2.1.103/linux/Documentation/rtc.txt	Mon May  6 22:18:50 1996
+++ linux/Documentation/rtc.txt	Thu Jun  4 22:53:50 1998
@@ -129,7 +129,7 @@
 fflush(stderr);
 for (i=1; i<6; i++) {
 	struct timeval tv = {5, 0};	/* 5 second timeout on select */
-	struct fd_set readfds;
+	fd_set readfds;
 
 	FD_ZERO(&readfds);
 	FD_SET(fd, &readfds);
diff -u --recursive --new-file v2.1.103/linux/Documentation/smart-config.txt linux/Documentation/smart-config.txt
--- v2.1.103/linux/Documentation/smart-config.txt	Fri Jan 23 18:10:31 1998
+++ linux/Documentation/smart-config.txt	Thu Jun  4 22:53:50 1998
@@ -72,14 +72,12 @@
     modular, 'make' will notice that the foo.o was not compiled
     with -DMODULE and will recompile foo.c.
 
-    Flag dependencies also work with per-source-file flags such
-    as those in drivers/net/CONFIG.
-
     All .a and .o files made from C source or with 'ld' or 'ar'
     have flag dependencies.  .S files do not have flag dependencies.
 
 Per-source-file Flags
 
+    Flag dependencies also work with per-source-file flags.
     You can specify compilation flags for individual source files
     like this:
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/smp.tex linux/Documentation/smp.tex
--- v2.1.103/linux/Documentation/smp.tex	Sat May  2 14:19:52 1998
+++ linux/Documentation/smp.tex	Wed May 20 18:54:34 1998
@@ -24,8 +24,8 @@
 \hfill Alan Cox, 1995
 
 
-The author wishes to thank Caldera Inc ( http://www.caldera.com )
-whose donation of an ASUS dual pentium board made this project possible, 
+The author wishes to thank Caldera Inc. ( http://www.caldera.com )
+whose donation of an ASUS dual Pentium board made this project possible, 
 and Thomas Radke, whose initial work on multiprocessor Linux formed 
 the backbone of this project.
 
@@ -35,7 +35,7 @@
 specification places much of the onus for hard work on the chipset and 
 hardware rather than the operating system.
 
-The Intel pentium processors have a wide variety of inbuilt facilities for 
+The Intel Pentium processors have a wide variety of inbuilt facilities for 
 supporting multiprocessing, including hardware cache coherency, built in 
 interprocessor interrupt handling and a set of atomic test and set, 
 exchange and similar operations. The cache coherency in particular makes the 
@@ -176,7 +176,7 @@
 The memory management core of the existing Linux system functions 
 adequately within the multiprocessor framework providing the locking is 
 used. Certain processor specific areas do need changing, in particular 
-invalidate() must invalidate the TLB's of all processors before it returns.
+invalidate() must invalidate the TLBs of all processors before it returns.
 
 
 \subsubsection{Miscellaneous Functions}
@@ -210,7 +210,7 @@
 extensions to standard kernel facilities to cope with multiple processors.
 
 \subsubsection{Initialisation}	
-The intel MP architecture captures all the processors except for a single 
+The Intel MP architecture captures all the processors except for a single 
 processor known as the 'boot processor' in the BIOS at boot time. Thus a 
 single processor enters the kernel bootup code. The first processor 
 executes the bootstrap code, loads and uncompresses the kernel. Having 
@@ -266,8 +266,8 @@
 appropriately. From then on the real APIC logical identity register is 
 read.
 
-Message passing is accomplished using a pair of IPI's on interrupt 13 
-(unused by the 80486 FPU's in SMP mode) and interrupt 16. Two are used in 
+Message passing is accomplished using a pair of IPIs on interrupt 13 
+(unused by the 80486 FPUs in SMP mode) and interrupt 16. Two are used in 
 order to separate messages that cannot be processed until the receiver 
 obtains the kernel spinlock from messages that can be processed 
 immediately. In effect IRQ 13 is a fast IRQ handler that does not obtain 
diff -u --recursive --new-file v2.1.103/linux/Documentation/sound/Opti linux/Documentation/sound/Opti
--- v2.1.103/linux/Documentation/sound/Opti	Sat May  2 14:19:52 1998
+++ linux/Documentation/sound/Opti	Wed May 20 18:54:34 1998
@@ -49,8 +49,8 @@
 
 Using isapnptools
 -----------------
-In most systems with a PnP bios you do not need to use isapnp. The
-initialization provided by the bios is sufficient for the driver
+In most systems with a PnP BIOS you do not need to use isapnp. The
+initialization provided by the BIOS is sufficient for the driver
 to pick up the card and continue initialization.
 
 If that fails, or if you have other PnP cards, you need to use isapnp
@@ -155,10 +155,10 @@
 before the cdrom is accessed the first time.
 
 Using the sound driver built-in to the kernel may help here, but...
-Most new systems have a PnP bios and also two IDE controllers.
+Most new systems have a PnP BIOS and also two IDE controllers.
 The IDE controller on the sound card may be needed only on older
 systems (which have only one IDE controller) but these systems
-also do not have a PnP bios - requiring isapnptools and a modularized
+also do not have a PnP BIOS - requiring isapnptools and a modularized
 driver.
 
 Known problems
diff -u --recursive --new-file v2.1.103/linux/Documentation/sound/Soundblaster linux/Documentation/sound/Soundblaster
--- v2.1.103/linux/Documentation/sound/Soundblaster	Sat May  2 14:19:52 1998
+++ linux/Documentation/sound/Soundblaster	Wed May 20 18:54:34 1998
@@ -29,10 +29,10 @@
 Using Mwave
 
 To make this driver work with Mwave you must set mwave_bug. You also need
-to warmboot from DOS/Windows with the required firmware loaded under this
+to warm boot from DOS/Windows with the required firmware loaded under this
 OS. IBM are being difficult about documenting how to load this firmware.
 
-Avance Logic ALS007
+Advance Logic ALS007
 
 This card isn't currently supported. I have patches to merge however that
 add limited support.
diff -u --recursive --new-file v2.1.103/linux/Documentation/sound/mwave linux/Documentation/sound/mwave
--- v2.1.103/linux/Documentation/sound/mwave	Sat May  2 14:19:52 1998
+++ linux/Documentation/sound/mwave	Wed May 20 18:54:34 1998
@@ -1,7 +1,7 @@
 	How to try and survive an IBM Mwave under Linux SB drivers
 
 
-* IBM refuse to provide documentation. If anyone can ever find out what
+* IBM refuses to provide documentation. If anyone can ever find out what
   MWD50430.EXE actually does to load firmware then this comedy could go
   away.
 
@@ -12,9 +12,9 @@
 
 ----------------------------------------------------------------------------
 
-OK, First thing - the IRQ problem IS a problem, whether the test is bypassed or
+OK, first thing - the IRQ problem IS a problem, whether the test is bypassed or
 not. And it is NOT a linux problem - it is an MWAVE problem that is fixed with
-the latest MWAVE patches. So, in other words, DON'T bypass the test for MWAVES!!
+the latest MWAVE patches. So, in other words, don't bypass the test for MWAVES!
 
 My config is Win 95 on HDA1, swap on HDA2, RH 5 on HDA3.
 
@@ -132,7 +132,7 @@
 the doc=yes parm is an environment variable that my init scripts use, it is not
 a kernel argument.
 
-However, the apm=off parm IS a kernel argument!!!!!!! APM, at least in my setup,
+However, the apm=off parm IS a kernel argument!  APM, at least in my setup,
 causes the kernel to crash when loaded via loadlin (but NOT when loaded via
 LILO). The APM stuff COULD be forced out of the kernel via the kernel compile
 options. BUT I, instead, got hold of an unofficial patch to the APM drivers that
diff -u --recursive --new-file v2.1.103/linux/Documentation/svga.txt linux/Documentation/svga.txt
--- v2.1.103/linux/Documentation/svga.txt	Sat May  2 14:19:52 1998
+++ linux/Documentation/svga.txt	Wed May 20 18:54:34 1998
@@ -70,7 +70,7 @@
    The mode list usually contains a few basic modes and some VESA modes.  In
 case your chipset has been detected, some chipset-specific modes are shown as
 well (some of these might be missing or unusable on your machine as different
-BIOSes are often shipped with the same card and the mode numbers depend purely
+BIOSs are often shipped with the same card and the mode numbers depend purely
 on the VGA BIOS).
 
    The modes displayed on the menu are partially sorted: The list starts with
@@ -139,8 +139,8 @@
 
    If you add 0x8000 to the mode ID, the program will try to recalculate
 vertical display timing according to mode parameters, which can be used to
-eliminate some annoying bugs of certain VGA BIOS'es (usually those used for
-cards with S3 chipsets and old Cirrus Logic BIOSes) -- mainly extra lines at the
+eliminate some annoying bugs of certain VGA BIOSs (usually those used for
+cards with S3 chipsets and old Cirrus Logic BIOSs) -- mainly extra lines at the
 end of the display.
 
 4. Options
@@ -179,7 +179,7 @@
 top of the menu).
 
    CONFIG_VIDEO_400_HACK - force setting of 400 scan lines for standard VGA
-modes. This option is intended to be used on certain buggy BIOS'es which draw
+modes. This option is intended to be used on certain buggy BIOSs which draw
 some useless logo using font download and then fail to reset the correct mode.
 Don't use unless needed as it forces resetting the video card.
 
diff -u --recursive --new-file v2.1.103/linux/Documentation/sysrq.txt linux/Documentation/sysrq.txt
--- v2.1.103/linux/Documentation/sysrq.txt	Wed May 20 19:10:36 1998
+++ linux/Documentation/sysrq.txt	Thu Jun  4 22:53:50 1998
@@ -46,7 +46,7 @@
 
 'm'     - Will dump current memory info to your console.
 
-'0'-'8' - Sets the console log level, controlling which kernel messages
+'0'-'9' - Sets the console log level, controlling which kernel messages
           will be printed to your console. ('0', for example would make
           it so that only emergency messages like PANICs or OOPSes would
           make it to your console.)
@@ -69,12 +69,17 @@
 and 'U'mount first.
 
 'S'ync is great when your system is locked up, it allows you to sync your
-disks and will certainly lessen the chance of data loss and fscking.
+disks and will certainly lessen the chance of data loss and fscking. Note
+that the sync hasn't taken place until you see the "OK" and "Done" appear 
+on the screen. (If the kernel is really in strife, you may not ever get the
+OK or Done message...)
 
 'U'mount is basically useful in the same ways as 'S'ync. I generally 'S'ync,
 'U'mount, then re'B'oot when my system locks. It's saved me many a fsck.
+Again, the unmount (remount read-only) hasn't taken place until you see the
+"OK" and "Done" message appear on the screen.
 
-The loglevel'0'-'8' is useful when your console is being flooded with
+The loglevel'0'-'9' is useful when your console is being flooded with
 kernel messages you do not want to see. Setting '0' will prevent all but
 the most urgent kernel messages from reaching your console. (They will
 still be logged if syslogd/klogd are alive, though.)
@@ -87,7 +92,8 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 That happens to me, also. I've found that tapping shift, alt, and control
 on both sides of the keyboard, and hitting an invalid sysrq sequence again
-will fix the problem. (ie, something like alt-sysrq-z).
+will fix the problem. (ie, something like alt-sysrq-z). Switching to another
+virtual console (ALT+Fn) and then back again should also help.
 
 *  I hit SysRQ, but nothing seems to happen, what's wrong?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff -u --recursive --new-file v2.1.103/linux/MAINTAINERS linux/MAINTAINERS
--- v2.1.103/linux/MAINTAINERS	Wed May 20 19:10:36 1998
+++ linux/MAINTAINERS	Thu Jun  4 15:52:21 1998
@@ -107,8 +107,8 @@
 S:	Maintained
 
 APM DRIVER
-P:	Rik Faith & Stephen Rothwell
-M:	faith@cs.unc.edu, Stephen.Rothwell@canb.auug.org.au
+P:	Stephen Rothwell
+M:	Stephen.Rothwell@canb.auug.org.au
 L:	linux-laptop@vger.rutgers.edu
 S:	Maintained
 
@@ -304,11 +304,11 @@
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
-IPX NETWORK LAYER
-P:	
-M:
-L:	
-S:	Orphan
+IPX/SPX NETWORK LAYER
+P:	Jay Schulist
+M:	Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+L:	linux-net@vger.rutgers.edu
+S:	Maintained
 
 ISDN SUBSYSTEM
 P:	Fritz Elfert
diff -u --recursive --new-file v2.1.103/linux/Makefile linux/Makefile
--- v2.1.103/linux/Makefile	Wed May 20 19:10:37 1998
+++ linux/Makefile	Wed May 20 19:10:21 1998
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 103
+SUBLEVEL = 104
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
diff -u --recursive --new-file v2.1.103/linux/README linux/README
--- v2.1.103/linux/README	Thu May 14 19:47:37 1998
+++ linux/README	Wed May 20 18:54:34 1998
@@ -1,7 +1,7 @@
 
 	Linux kernel release 2.1.xx
 
-These are the release notes for linux version 2.1.  Read them carefully,
+These are the release notes for Linux version 2.1.  Read them carefully,
 as they tell you what this is all about, explain how to install the
 kernel, and what to do if something goes wrong. 
 
@@ -45,7 +45,7 @@
 DOCUMENTATION:
 
  - There is a lot of documentation available both in electronic form on
-   the internet and in books, both Linux-specific and pertaining to
+   the Internet and in books, both Linux-specific and pertaining to
    general UNIX questions.  I'd recommend looking into the documentation
    subdirectories on any Linux ftp site for the LDP (Linux Documentation
    Project) books.  This README is not meant to be documentation on the
@@ -170,7 +170,7 @@
 COMPILING the kernel:
 
  - Make sure you have gcc-2.7.0 or newer available.  It seems older gcc
-   versions can have problems compiling newer versions of linux.  This
+   versions can have problems compiling newer versions of Linux.  This
    is mainly because the older compilers can only generate "a.out"-format
    executables.  As of Linux 2.1.0, the kernel must be compiled as an
    "ELF" binary.  If you upgrade your compiler, remember to get the new
diff -u --recursive --new-file v2.1.103/linux/Rules.make linux/Rules.make
--- v2.1.103/linux/Rules.make	Wed Apr  8 19:36:24 1998
+++ linux/Rules.make	Wed May 20 18:54:34 1998
@@ -178,7 +178,7 @@
 # The -w option (enable warnings) for genksyms will return here in 2.1
 # So where has it gone ???
 #
-# Added the SMP seperator to stop module accidents between uniproc/smp
+# Added the SMP separator to stop module accidents between uniproc/smp
 # intel boxes - AC - from bits by Michael Chastain
 #
 
diff -u --recursive --new-file v2.1.103/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- v2.1.103/linux/arch/alpha/kernel/bios32.c	Thu May  7 22:51:46 1998
+++ linux/arch/alpha/kernel/bios32.c	Wed May 20 18:54:34 1998
@@ -375,7 +375,7 @@
 			 *
 			 * In sparse memory address space, the first
 			 * octant (16MB) of every 128MB segment is
-			 * aliased to the the very first 16MB of the
+			 * aliased to the very first 16 MB of the
 			 * address space (i.e., it aliases the ISA
 			 * memory address space).  Thus, we try to
 			 * avoid allocating PCI devices in that range.
diff -u --recursive --new-file v2.1.103/linux/arch/alpha/kernel/cia.c linux/arch/alpha/kernel/cia.c
--- v2.1.103/linux/arch/alpha/kernel/cia.c	Mon Apr  6 17:40:59 1998
+++ linux/arch/alpha/kernel/cia.c	Wed May 20 18:54:34 1998
@@ -725,7 +725,7 @@
 	printk(KERN_CRIT "   vector=0x%lx la_ptr=0x%lx pc=0x%lx\n",
 	       vector, la_ptr, regs->pc);
 
-	/* dump the the logout area to give all info: */
+	/* dump the logout area to give all info: */
 
 	ptr = (unsigned long *)la_ptr;
 	for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
diff -u --recursive --new-file v2.1.103/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v2.1.103/linux/arch/alpha/kernel/entry.S	Wed Apr  1 20:11:47 1998
+++ linux/arch/alpha/kernel/entry.S	Thu May 21 13:48:06 1998
@@ -264,7 +264,7 @@
 	stq $18,40($30)
 	bis $31,2,$0	/* Register v0: syscall nr for fork() */
 	SAVE_ALL
-	jsr $26,sys_clone
+	bsr $26,sys_clone
 	stq $0,0($30)
 	br $31,ret_from_sys_call
 .end	kernel_clone
@@ -559,6 +559,7 @@
 .globl  alpha_switch_to
 .ent    alpha_switch_to
 alpha_switch_to:
+	.prologue 0
 	bsr $1,do_switch_stack
 	call_pal PAL_swpctx
 	lda $16,-2($31)
@@ -1179,6 +1180,6 @@
 	.quad sys_getrusage
 	.quad sys_wait4				/* 365 */
 	.quad sys_adjtimex
-	.quad sys_ni_syscall
+	.quad sys_getcwd
 	.quad sys_ni_syscall
 	.quad sys_ni_syscall			/* 369 */
diff -u --recursive --new-file v2.1.103/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S
--- v2.1.103/linux/arch/alpha/kernel/head.S	Wed Apr  8 19:36:24 1998
+++ linux/arch/alpha/kernel/head.S	Thu May 21 13:48:06 1998
@@ -21,6 +21,7 @@
 	.ent	__start
 _stext:
 __start:
+	.prologue 0
 	br	$27,1f
 1:	ldgp	$29,0($27)
 	/* We need to get current loaded up with our first task...  */
@@ -39,6 +40,7 @@
 	/* on entry here from SRM console, the HWPCB of this processor */
 	/* has been loaded, and $27 contains the task pointer */
 __start_cpu:
+	.prologue 0
 	/* first order of business, load the GP */
 	br	$26,1f
 1:	ldgp	$29,0($26)
@@ -57,6 +59,7 @@
 	.globl	wrent
 	.ent	wrent
 wrent:
+	.prologue 0
 	call_pal PAL_wrent
 	ret	($26)
 	.end wrent
@@ -65,6 +68,7 @@
 	.globl	wrkgp
 	.ent	wrkgp
 wrkgp:
+	.prologue 0
 	call_pal PAL_wrkgp
 	ret	($26)
 	.end wrkgp
@@ -73,6 +77,7 @@
 	.globl	wrusp
 	.ent	wrusp
 wrusp:
+	.prologue 0
 	call_pal PAL_wrusp
 	ret	($26)
 	.end wrusp
@@ -81,6 +86,7 @@
 	.globl	rdusp
 	.ent	rdusp
 rdusp:
+	.prologue 0
 	call_pal PAL_rdusp
 	ret	($26)
 	.end rdusp
@@ -89,6 +95,7 @@
 	.globl	rdmces
 	.ent	rdmces
 rdmces:
+	.prologue 0
 	call_pal PAL_rdmces
 	ret	($26)
 	.end rdmces
@@ -97,6 +104,7 @@
 	.globl	wrmces
 	.ent	wrmces
 wrmces:
+	.prologue 0
 	call_pal PAL_wrmces
 	ret	($26)
 	.end wrmces
@@ -105,6 +113,7 @@
 	.globl  whami
 	.ent    whami
 whami:
+	.prologue 0
 	call_pal PAL_whami
 	ret     ($26)
 	.end whami
@@ -127,6 +136,7 @@
 	.globl	cserve_ena
 	.ent	cserve_ena
 cserve_ena:
+	.prologue 0
 	bis	$16,$16,$17
 	lda	$16,52($31)
 	call_pal PAL_cserve
@@ -137,6 +147,7 @@
 	.globl	cserve_dis
 	.ent	cserve_dis
 cserve_dis:
+	.prologue 0
 	bis	$16,$16,$17
 	lda	$16,53($31)
 	call_pal PAL_cserve
diff -u --recursive --new-file v2.1.103/linux/arch/alpha/kernel/lca.c linux/arch/alpha/kernel/lca.c
--- v2.1.103/linux/arch/alpha/kernel/lca.c	Mon Apr  6 17:40:59 1998
+++ linux/arch/alpha/kernel/lca.c	Wed May 20 18:54:34 1998
@@ -504,7 +504,7 @@
 		printk(KERN_CRIT "  Unknown errorlog size %d\n", el.c->size);
 	}
 
-	/* dump the the logout area to give all info: */
+	/* dump the logout area to give all info: */
 
 	ptr = (unsigned long *) la;
 	for (i = 0; i < el.c->size / sizeof(long); i += 2) {
diff -u --recursive --new-file v2.1.103/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.1.103/linux/arch/alpha/kernel/smp.c	Wed Apr  8 19:36:24 1998
+++ linux/arch/alpha/kernel/smp.c	Thu May 21 14:24:05 1998
@@ -463,7 +463,7 @@
 #endif
 			return;
 		}
-		udelay(1000);
+		mdelay(1);
 	}
 #if 0
 	printk("secondary_cpu_start: SUCCESS for CPU %d!!!\n", cpuid);
@@ -490,7 +490,7 @@
                         printk("Processor %x not ready\n", cpuid);
                         return;
                 }
-                udelay(1000);
+                mdelay(1);
         }
 
         cp1 = (char *) &cpu->ipc_buffer[1];
@@ -506,7 +506,7 @@
                         printk("Processor %x not ready\n", cpuid);
                         return;
                 }
-                udelay(1000);
+                mdelay(1);
         }
 }
 
diff -u --recursive --new-file v2.1.103/linux/arch/alpha/kernel/t2.c linux/arch/alpha/kernel/t2.c
--- v2.1.103/linux/arch/alpha/kernel/t2.c	Mon Apr  6 17:40:59 1998
+++ linux/arch/alpha/kernel/t2.c	Wed May 20 18:54:35 1998
@@ -636,7 +636,7 @@
 	printk(KERN_CRIT "  T2 machine check: %s%s\n",
 	       reason, mchk_header->elfl_retry ? " (retryable)" : "");
 
-	/* dump the the logout area to give all info: */
+	/* dump the logout area to give all info: */
 
 	ptr = (unsigned long *)la_ptr;
 	for (i = 0; i < mchk_header->elfl_size / sizeof(long); i += 2) {
diff -u --recursive --new-file v2.1.103/linux/arch/arm/kernel/entry-armo.S linux/arch/arm/kernel/entry-armo.S
--- v2.1.103/linux/arch/arm/kernel/entry-armo.S	Wed May 20 19:10:37 1998
+++ linux/arch/arm/kernel/entry-armo.S	Wed May 20 18:54:35 1998
@@ -397,12 +397,12 @@
 /*=============================================================================
  * Interrupt (IRQ) handler
  *-----------------------------------------------------------------------------
- * Note: if in user mode, then *no* kernel routine is running, so dont have
+ * Note: if in user mode, then *no* kernel routine is running, so do not have
  *       to save svc lr
  * (r13 points to irq temp save area)
  */
 
-vector_IRQ:	ldr	r13, .LCirq			@ Ill leave this one in just in case...
+vector_IRQ:	ldr	r13, .LCirq			@ I will leave this one in just in case...
 		sub	lr, lr, #4
 		str	lr, [r13]
 		tst	lr, #3
diff -u --recursive --new-file v2.1.103/linux/arch/arm/lib/checksum.S linux/arch/arm/lib/checksum.S
--- v2.1.103/linux/arch/arm/lib/checksum.S	Fri May  8 23:14:42 1998
+++ linux/arch/arm/lib/checksum.S	Wed May 20 18:54:35 1998
@@ -207,7 +207,7 @@
 		blt	.too_small_user
 		tst	r1, #2			@ Test destination alignment
 		beq	.dst_aligned_user
-		subs	r2, r2, #2		@ We dont know if SRC is aligned...
+		subs	r2, r2, #2		@ We do not know if SRC is aligned...
 		load2b	ip, r8
 		orr	ip, ip, r8, lsl #8
 		adds	r3, r3, ip
@@ -469,7 +469,7 @@
 		blt	Ltoo_small
 		tst	r1, #2			@ Test destination alignment
 		beq	Ldst_aligned
-		subs	r2, r2, #2		@ We dont know if SRC is aligned...
+		subs	r2, r2, #2		@ We do not know if SRC is aligned...
 		ldrb	ip, [r0], #1
 		ldrb	r8, [r0], #1
 		orr	ip, ip, r8, lsl #8
diff -u --recursive --new-file v2.1.103/linux/arch/arm/lib/ll_char_wr.S linux/arch/arm/lib/ll_char_wr.S
--- v2.1.103/linux/arch/arm/lib/ll_char_wr.S	Fri May  8 23:14:42 1998
+++ linux/arch/arm/lib/ll_char_wr.S	Wed May 20 18:54:35 1998
@@ -9,9 +9,9 @@
  * 08-04-98	RMK	Shifts re-ordered
  */
 
-@ Regs: [] = corruptable
+@ Regs: [] = corruptible
 @       {} = used
-@       () = dont use
+@       () = do not use
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
diff -u --recursive --new-file v2.1.103/linux/arch/arm/mm/proc-arm2,3.S linux/arch/arm/mm/proc-arm2,3.S
--- v2.1.103/linux/arch/arm/mm/proc-arm2,3.S	Fri May  8 23:14:42 1998
+++ linux/arch/arm/mm/proc-arm2,3.S	Wed May 20 18:54:35 1998
@@ -123,7 +123,7 @@
  *	     address  Address of fault.
  *	     pte      New PTE at address
  * Purpose : Update the mapping for this address.
- * Notes   : does the ARM3 run faster if you dont use the result in the next instruction?
+ * Notes   : does the ARM3 run faster if you do not use the result in the next instruction?
  */
 _arm2_3_update_cache:
 		tst	r2, #PAGE_PRESENT
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.1.103/linux/arch/i386/kernel/bios32.c	Wed May 20 19:10:37 1998
+++ linux/arch/i386/kernel/bios32.c	Thu May 21 14:13:15 1998
@@ -543,7 +543,8 @@
 		pci_indirect.address = pcibios_entry + PAGE_OFFSET;
 
 		save_flags(flags); cli();
-		__asm__("lcall (%%edi)\n\t"
+		__asm__ __volatile__(
+			"lcall (%%edi)\n\t"
 			"jc 1f\n\t"
 			"xor %%ah, %%ah\n"
 			"1:"
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.1.103/linux/arch/i386/kernel/io_apic.c	Wed May 20 19:10:37 1998
+++ linux/arch/i386/kernel/io_apic.c	Fri May 22 12:14:13 1998
@@ -129,6 +129,15 @@
 }
 
 /*
+ * Syncronize the IO-APIC and the CPU by doing
+ * a dummy read from the IO-APIC
+ */
+static inline void io_apic_sync(void)
+{
+	(void) *(IO_APIC_BASE+4);
+}
+
+/*
  * We disable IO-APIC IRQs by setting their 'destination CPU mask' to
  * zero. Trick, trick.
  */
@@ -141,6 +150,7 @@
 		*(((int *)&entry)+1) = io_apic_read(0x11+pin*2);
 		entry.dest.logical.logical_dest = 0x0;
 		io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
+		io_apic_sync();
 	}
 }
 
@@ -165,6 +175,7 @@
 		*(((int *)&entry)+0) = io_apic_read(0x10+pin*2);
 		entry.mask = 1;
 		io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
+		io_apic_sync();
 	}
 }
 
@@ -891,6 +902,229 @@
 
 	return 0;
 }
+
+#ifdef __SMP__
+
+/*
+ * In the SMP+IOAPIC case it might happen that there are an unspecified
+ * number of pending IRQ events unhandled. These cases are very rare,
+ * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
+ * better to do it this way as thus we do not have to be aware of
+ * 'pending' interrupts in the IRQ path, except at this point.
+ */
+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));
+	}
+}
+
+/*
+ * Edge triggered needs to resend any interrupt
+ * that was delayed.
+ */
+static void enable_edge_ioapic_irq(unsigned int irq)
+{
+	self_IPI(irq);
+	enable_IO_APIC_irq(irq);
+}
+
+static void disable_edge_ioapic_irq(unsigned int irq)
+{
+	disable_IO_APIC_irq(irq);
+}
+
+/*
+ * Level triggered interrupts can just be masked
+ */
+static void enable_level_ioapic_irq(unsigned int irq)
+{
+	unmask_IO_APIC_irq(irq);
+}
+
+static void disable_level_ioapic_irq(unsigned int irq)
+{
+	mask_IO_APIC_irq(irq);
+}
+
+/*
+ * Enter and exit the irq handler context..
+ */
+static inline void enter_ioapic_irq(int cpu)
+{
+	hardirq_enter(cpu);
+	while (test_bit(0,&global_irq_lock)) barrier();
+}
+
+static inline void exit_ioapic_irq(int cpu)
+{
+	hardirq_exit(cpu);
+	release_irqlock(cpu);
+}	
+
+static void do_edge_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	struct irqaction * action;
+
+	spin_lock(&irq_controller_lock);
+
+	/*
+	 * Edge triggered IRQs can be acked immediately
+	 * and do not need to be masked.
+	 */
+	ack_APIC_irq();
+	desc->ipi = 0;
+	desc->events = 1;
+
+	/*
+	 * If the irq is disabled for whatever reason, we cannot
+	 * use the action we have..
+	 */
+	action = NULL;
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		desc->status = IRQ_INPROGRESS;
+		desc->events = 0;
+	}
+	spin_unlock(&irq_controller_lock);
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	 */
+	if (!action)
+		return;
+
+	enter_ioapic_irq(cpu);
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events..
+	 */
+	for (;;) {
+		int pending;
+
+		handle_IRQ_event(irq, regs);
+
+		spin_lock(&irq_controller_lock);
+		pending = desc->events;
+		desc->events = 0;
+		if (!pending)
+			break;
+		spin_unlock(&irq_controller_lock);
+	}
+	desc->status &= IRQ_DISABLED;
+	spin_unlock(&irq_controller_lock);
+
+	exit_ioapic_irq(cpu);
+}
+
+static void do_level_ioapic_IRQ (unsigned int irq, int cpu,
+						 struct pt_regs * regs)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	struct irqaction * action;
+
+	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.
+	 *
+	 * disable has to happen before the ACK, to avoid IRQ storms.
+	 * So this all has to be within the spinlock.
+	 */
+	mask_IO_APIC_irq(irq);
+
+	desc->ipi = 0;
+
+	/*
+	 * If the irq is disabled for whatever reason, we must
+	 * not enter the irq action.
+	 */
+	action = NULL;
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		desc->status = IRQ_INPROGRESS;
+	}
+
+	ack_APIC_irq();
+	spin_unlock(&irq_controller_lock);
+
+	/* Exit early if we had no action or it was disabled */
+	if (!action)
+		return;
+
+	enter_ioapic_irq(cpu);
+
+	handle_IRQ_event(irq, regs);
+
+	spin_lock(&irq_controller_lock);
+	desc->status &= ~IRQ_INPROGRESS;
+	if (!desc->status)
+		unmask_IO_APIC_irq(irq);
+	spin_unlock(&irq_controller_lock);
+
+	exit_ioapic_irq(cpu);
+}
+
+/*
+ * Level and edge triggered IO-APIC interrupts need different handling,
+ * so we use two separate irq descriptors. edge triggered IRQs can be
+ * handled with the level-triggered descriptor, but that one has slightly
+ * more overhead. Level-triggered interrupts cannot be handled with the
+ * edge-triggered handler, without risking IRQ storms and other ugly
+ * races.
+ */
+
+static struct hw_interrupt_type ioapic_edge_irq_type = {
+	"IO-APIC-edge",
+	do_edge_ioapic_IRQ,
+	enable_edge_ioapic_irq,
+	disable_edge_ioapic_irq
+};
+
+static struct hw_interrupt_type ioapic_level_irq_type = {
+	"IO-APIC-level",
+	do_level_ioapic_IRQ,
+	enable_level_ioapic_irq,
+	disable_level_ioapic_irq
+};
+
+void init_IO_APIC_traps(void)
+{
+	int i;
+	/*
+	 * NOTE! The local APIC isn't very good at handling
+	 * multiple interrupts at the same interrupt level.
+	 * As the interrupt level is determined by taking the
+	 * vector number and shifting that right by 4, we
+	 * want to spread these out a bit so that they don't
+	 * all fall in the same interrupt level
+	 *
+	 * 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 */ &&
+		    (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
 
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.103/linux/arch/i386/kernel/irq.c	Wed May 20 19:10:37 1998
+++ linux/arch/i386/kernel/irq.c	Fri May 22 16:09:54 1998
@@ -61,7 +61,7 @@
  *
  * (0x0000ffff for NR_IRQS==16, 0x00ffffff for NR_IRQS=24)
  */
-static unsigned int cached_irq_mask = (1<<NR_IRQS)-1;
+unsigned int cached_irq_mask = (1<<NR_IRQS)-1;
 
 #define cached_21	((cached_irq_mask | io_apic_irqs) & 0xff)
 #define cached_A1	(((cached_irq_mask | io_apic_irqs) >> 8) & 0xff)
@@ -86,18 +86,24 @@
  */
 unsigned int io_apic_irqs = 0;
 
-struct hw_interrupt_type {
-	const char * typename;
-	void (*handle)(unsigned int irq, int cpu, struct pt_regs * regs);
-	void (*enable)(unsigned int irq);
-	void (*disable)(unsigned int irq);
-};
-
-
 static void do_8259A_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
 static void enable_8259A_irq (unsigned int irq);
 static void disable_8259A_irq (unsigned int irq);
 
+/*
+ * Dummy controller type for unused interrupts
+ */
+static void do_none(unsigned int irq, int cpu, struct pt_regs * regs) { }
+static void enable_none(unsigned int irq) { }
+static void disable_none(unsigned int irq) { }
+
+static struct hw_interrupt_type no_irq_type = {
+	"none",
+	do_none,
+	enable_none,
+	disable_none
+};
+
 static struct hw_interrupt_type i8259A_irq_type = {
 	"XT-PIC",
 	do_8259A_IRQ,
@@ -105,73 +111,9 @@
 	disable_8259A_irq
 };
 
-
-#ifdef __SMP__
-
-/*
- * Level and edge triggered IO-APIC interrupts need different handling,
- * so we use two separate irq descriptors. edge triggered IRQs can be
- * handled with the level-triggered descriptor, but that one has slightly
- * more overhead. Level-triggered interrupts cannot be handled with the
- * edge-triggered handler, without risking IRQ storms and other ugly
- * races.
- */
-
-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 = {
-	"IO-APIC-edge",
-	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 = {
-	"IO-APIC-level",
-	do_level_ioapic_IRQ,
-	enable_level_ioapic_irq,
-	disable_level_ioapic_irq
-};
-
-#endif
-
-/*
- * Status: reason for being disabled: somebody has
- * done a "disable_irq()" or we must not re-enter the
- * already executing irq..
- */
-#define IRQ_INPROGRESS	1
-#define IRQ_DISABLED	2
-
-/*
- * This is the "IRQ descriptor", which contains various information
- * about the irq, including what kind of hardware handling it has,
- * whether it is disabled etc etc.
- *
- * Pad this out to 32 bytes for cache and indexing reasons.
- */
-typedef struct {
-	unsigned int status;			/* IRQ status - IRQ_INPROGRESS, IRQ_DISABLED */
-	unsigned int events;			/* Do we have any pending events? */
-	unsigned int ipi;			/* Have we sent off the pending IPI? */
-	struct hw_interrupt_type *handler;	/* handle/enable/disable functions */
-	struct irqaction *action;		/* IRQ action list */
-	unsigned int unused[3];
-} irq_desc_t;
-
 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_edge_irq_type, }, /* 'high' PCI IRQs */
-#endif
+	[0 ... 15] = { 0, 0, 0, &i8259A_irq_type, },	/* default to standard ISA IRQs */
+	[16 ... 23] = { 0, 0, 0, &no_irq_type, },	/* 'high' PCI IRQs filled in on demand */
 };
 
 
@@ -641,7 +583,7 @@
 
 #endif
 
-static int handle_IRQ_event(unsigned int irq, struct pt_regs * regs)
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs)
 {
 	struct irqaction * action;
 	int status;
@@ -742,176 +684,6 @@
 	irq_exit(cpu, irq);
 }
 
-#ifdef __SMP__
-
-/*
- * In the SMP+IOAPIC case it might happen that there are an unspecified
- * number of pending IRQ events unhandled. These cases are very rare,
- * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
- * 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 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));
-	}
-}
-
-/*
- * Edge triggered needs to resend any interrupt
- * that was delayed.
- */
-static void enable_edge_ioapic_irq(unsigned int irq)
-{
-	self_IPI(irq);
-	enable_IO_APIC_irq(irq);
-}
-
-static void disable_edge_ioapic_irq(unsigned int irq)
-{
-	disable_IO_APIC_irq(irq);
-}
-
-/*
- * Level triggered interrupts can just be masked
- */
-static void enable_level_ioapic_irq(unsigned int irq)
-{
-	unmask_IO_APIC_irq(irq);
-}
-
-static void disable_level_ioapic_irq(unsigned int irq)
-{
-	mask_IO_APIC_irq(irq);
-}
-
-/*
- * Enter and exit the irq handler context..
- */
-static inline void enter_ioapic_irq(int cpu)
-{
-	hardirq_enter(cpu);
-	while (test_bit(0,&global_irq_lock)) barrier();
-}
-
-static inline void exit_ioapic_irq(int cpu)
-{
-	hardirq_exit(cpu);
-	release_irqlock(cpu);
-}	
-
-static void do_edge_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	struct irqaction * action;
-
-	spin_lock(&irq_controller_lock);
-
-	/*
-	 * Edge triggered IRQs can be acked immediately
-	 * and do not need to be masked.
-	 */
-	ack_APIC_irq();
-	desc->ipi = 0;
-	desc->events = 1;
-
-	/*
-	 * If the irq is disabled for whatever reason, we cannot
-	 * use the action we have..
-	 */
-	action = NULL;
-	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-		action = desc->action;
-		desc->status = IRQ_INPROGRESS;
-		desc->events = 0;
-	}
-	spin_unlock(&irq_controller_lock);
-
-	/*
-	 * If there is no IRQ handler or it was disabled, exit early.
-	 */
-	if (!action)
-		return;
-
-	enter_ioapic_irq(cpu);
-
-	/*
-	 * Edge triggered interrupts need to remember
-	 * pending events..
-	 */
-	for (;;) {
-		int pending;
-
-		handle_IRQ_event(irq, regs);
-
-		spin_lock(&irq_controller_lock);
-		pending = desc->events;
-		desc->events = 0;
-		if (!pending)
-			break;
-		spin_unlock(&irq_controller_lock);
-	}
-	desc->status &= IRQ_DISABLED;
-	spin_unlock(&irq_controller_lock);
-
-	exit_ioapic_irq(cpu);
-}
-
-static void do_level_ioapic_IRQ (unsigned int irq, int cpu,
-						 struct pt_regs * regs)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	struct irqaction * action;
-
-	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.
-	 *
-	 * disable has to happen before the ACK, to avoid IRQ storms.
-	 * So this all has to be within the spinlock.
-	 */
-	mask_IO_APIC_irq(irq);
-
-	desc->ipi = 0;
-
-	/*
-	 * If the irq is disabled for whatever reason, we must
-	 * not enter the irq action.
-	 */
-	action = NULL;
-	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-		action = desc->action;
-		desc->status = IRQ_INPROGRESS;
-	}
-
-	ack_APIC_irq();
-	spin_unlock(&irq_controller_lock);
-
-	/* Exit early if we had no action or it was disabled */
-	if (!action)
-		return;
-
-	enter_ioapic_irq(cpu);
-
-	handle_IRQ_event(irq, regs);
-
-	spin_lock(&irq_controller_lock);
-	desc->status &= ~IRQ_INPROGRESS;
-	if (!desc->status)
-		unmask_IO_APIC_irq(irq);
-	spin_unlock(&irq_controller_lock);
-
-	exit_ioapic_irq(cpu);
-}
-
-#endif
-
 
 /*
  * Generic enable/disable code: this just calls
@@ -1197,39 +969,6 @@
 	spin_unlock_irq(&irq_controller_lock);
 	return irq_found;
 }
-
-#ifdef __SMP__
-void init_IO_APIC_traps(void)
-{
-	int i;
-	/*
-	 * NOTE! The local APIC isn't very good at handling
-	 * multiple interrupts at the same interrupt level.
-	 * As the interrupt level is determined by taking the
-	 * vector number and shifting that right by 4, we
-	 * want to spread these out a bit so that they don't
-	 * all fall in the same interrupt level
-	 *
-	 * 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 */ &&
-		    (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
 
 __initfunc(void init_IRQ(void))
 {
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.1.103/linux/arch/i386/kernel/irq.h	Wed May 20 19:10:37 1998
+++ linux/arch/i386/kernel/irq.h	Fri May 22 13:42:05 1998
@@ -1,6 +1,48 @@
 #ifndef __irq_h
 #define __irq_h
 
+#include <asm/irq.h>
+
+/*
+ * Interrupt controller descriptor. This is all we need
+ * to describe about the low-level hardware.
+ */
+struct hw_interrupt_type {
+	const char * typename;
+	void (*handle)(unsigned int irq, int cpu, struct pt_regs * regs);
+	void (*enable)(unsigned int irq);
+	void (*disable)(unsigned int irq);
+};
+
+
+/*
+ * Status: reason for being disabled: somebody has
+ * done a "disable_irq()" or we must not re-enter the
+ * already executing irq..
+ */
+#define IRQ_INPROGRESS	1
+#define IRQ_DISABLED	2
+
+/*
+ * This is the "IRQ descriptor", which contains various information
+ * about the irq, including what kind of hardware handling it has,
+ * whether it is disabled etc etc.
+ *
+ * Pad this out to 32 bytes for cache and indexing reasons.
+ */
+typedef struct {
+	unsigned int status;			/* IRQ status - IRQ_INPROGRESS, IRQ_DISABLED */
+	unsigned int events;			/* Do we have any pending events? */
+	unsigned int ipi;			/* Have we sent off the pending IPI? */
+	struct hw_interrupt_type *handler;	/* handle/enable/disable functions */
+	struct irqaction *action;		/* IRQ action list */
+	unsigned int unused[3];
+} irq_desc_t;
+
+extern irq_desc_t irq_desc[NR_IRQS];
+
+extern int handle_IRQ_event(unsigned int, struct pt_regs *);
+
 /*
  * Various low-level irq details needed by irq.c, process.c,
  * time.c, io_apic.c and smp.c
@@ -27,6 +69,7 @@
 void print_IO_APIC (void);
 
 extern unsigned int io_apic_irqs;
+extern unsigned int cached_irq_mask;
 
 #define IO_APIC_VECTOR(irq)	(0x51+((irq)<<3))
 
@@ -159,7 +202,7 @@
 		eip -= (unsigned long) &_stext;
 		eip >>= prof_shift;
 		/*
-		 * Dont ignore out-of-bounds EIP values silently,
+		 * Don't ignore out-of-bounds EIP values silently,
 		 * put them into the last histogram slot, so if
 		 * present, they will show up as a sharp peak.
 		 */
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.1.103/linux/arch/i386/kernel/mtrr.c	Thu May  7 22:51:46 1998
+++ linux/arch/i386/kernel/mtrr.c	Thu May 21 13:34:43 1998
@@ -110,6 +110,10 @@
     19980502   Richard Gooch <rgooch@atnf.csiro.au>
 	       Documentation improvement: mention Pentium II and AGP.
   v1.20
+    19980521   Richard Gooch <rgooch@atnf.csiro.au>
+	       Only manipulate interrupt enable flag on local CPU.
+	       Allow enclosed uncachable regions.
+  v1.21
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -143,7 +147,7 @@
 #include <asm/atomic.h>
 #include <linux/smp.h>
 
-#define MTRR_VERSION            "1.20 (19980502)"
+#define MTRR_VERSION            "1.21 (19980521)"
 
 #define TRUE  1
 #define FALSE 0
@@ -244,8 +248,8 @@
 {
     unsigned long tmp;
 
-    /* disable interrupts */
-    save_flags(ctxt->flags); cli();
+    /* disable interrupts locally */
+    __save_flags (ctxt->flags); __cli ();
 
     /* save value of CR4 and clear Page Global Enable (bit 7) */
     asm volatile ("movl  %%cr4, %0\n\t"
@@ -290,8 +294,8 @@
     asm volatile ("movl  %0, %%cr4"
                   : : "r" (ctxt->cr4val) : "memory");
 
-    /* re-enable interrupts (if enabled previously) */
-    restore_flags(ctxt->flags);
+    /* re-enable interrupts locally (if enabled previously) */
+    __restore_flags (ctxt->flags);
 }   /*  End Function set_mtrr_done  */
 
 
@@ -804,8 +808,10 @@
 		    base, size, lbase, lsize);
 	    return -EINVAL;
 	}
+	/*  New region is enclosed by an existing region  */
 	if (ltype != type)
 	{
+	    if (type == MTRR_TYPE_UNCACHABLE) continue;
 	    spin_unlock (&main_lock);
 	    printk ( "mtrr: type mismatch for %lx,%lx old: %s new: %s\n",
 		     base, size, attrib_to_str (ltype), attrib_to_str (type) );
@@ -1202,7 +1208,7 @@
     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
+#  endif
 
 #  ifdef __SMP__
 #    ifdef MODULE
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.1.103/linux/arch/i386/kernel/process.c	Wed May 20 19:10:37 1998
+++ linux/arch/i386/kernel/process.c	Thu Jun  4 11:03:46 1998
@@ -46,6 +46,8 @@
 #endif
 #include "irq.h"
 
+spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
+
 struct task_struct *last_task_used_math = NULL;
 
 #ifdef __SMP__
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.1.103/linux/arch/i386/kernel/smp.c	Wed May 20 19:10:37 1998
+++ linux/arch/i386/kernel/smp.c	Thu Jun  4 11:03:46 1998
@@ -57,8 +57,6 @@
 
 #include "irq.h"
 
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
-
 extern unsigned long start_kernel, _etext;
 extern void update_one_process( struct task_struct *p,
 				unsigned long ticks, unsigned long user,
@@ -867,7 +865,7 @@
 		SMP_PRINTK(("Startup point 1.\n"));
 		timeout = 0;
 		do {
-			SMP_PRINTK(("Sleeping.\n")); udelay(1000000);
+			SMP_PRINTK(("Sleeping.\n")); mdelay(1000);
 			udelay(10);
 		} while ( (send_status = (apic_read(APIC_ICR) & 0x1000))
 			  && (timeout++ < 1000));
@@ -1118,7 +1116,7 @@
 	SMP_PRINTK(("Boot done.\n"));
 
 	/*
-	 * Here we can be sure that there is an IO-APIC in the system, lets
+	 * Here we can be sure that there is an IO-APIC in the system. Let's
 	 * go and set it up:
 	 */
 	setup_IO_APIC();
@@ -1654,7 +1652,7 @@
 	setup_APIC_timer(1000000000);
 
 	/*
-	 * The timer chip counts down to zero. Lets wait
+	 * The timer chip counts down to zero. Let's wait
 	 * for a wraparound to start exact measurement:
 	 * (the current tick might have been already half done)
 	 */
@@ -1662,14 +1660,14 @@
 	wait_8254_wraparound ();
 
 	/*
-	 * We wrapped around just now, lets start:
+	 * We wrapped around just now. Let's start:
 	 */
 	RDTSC(t1);
 	tt1=apic_read(APIC_TMCCT);
 
 #define LOOPS (HZ/10)
 	/*
-	 * lets wait LOOPS wraprounds:
+	 * let's wait LOOPS wraprounds:
 	 */
 	for (i=0; i<LOOPS; i++)
 		wait_8254_wraparound ();
diff -u --recursive --new-file v2.1.103/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- v2.1.103/linux/arch/i386/kernel/time.c	Wed May 20 19:10:37 1998
+++ linux/arch/i386/kernel/time.c	Wed May 20 18:54:35 1998
@@ -203,7 +203,7 @@
 	 *     (see c't 95/10 page 335 for Neptun bug.)
 	 */
 
-/* you can safely undefine this if you dont have the Neptun chipset */
+/* you can safely undefine this if you don't have the Neptune chipset */
 
 #define BUGGY_NEPTUN_TIMER
 
@@ -217,7 +217,7 @@
 			if( inb(0x20) & 0x01 ) {
 				/*
 				 * We cannot detect lost timer interrupts ... 
-				 * well, thats why we call them lost, dont we? :)
+				 * well, that's why we call them lost, don't we? :)
 				 * [hmm, on the Pentium and Alpha we can ... sort of]
 				 */
 				count -= LATCH;
diff -u --recursive --new-file v2.1.103/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- v2.1.103/linux/arch/i386/mm/init.c	Wed May 20 19:10:37 1998
+++ linux/arch/i386/mm/init.c	Thu May 21 20:57:02 1998
@@ -293,6 +293,16 @@
 		memset((void *)start_mem, 0, PAGE_SIZE);
 		start_mem += PAGE_SIZE;
 		set_pte(pg_table, pte);
+
+		/*
+		 * Do the same for the IO-APIC
+		 */
+		apic_area = 0xFEC00000;
+		pg_table = pte_offset((pmd_t *)pg_dir, apic_area);
+		pte = mk_pte(start_mem, PAGE_KERNEL);
+		memset((void *)start_mem, 0, PAGE_SIZE);
+		start_mem += PAGE_SIZE;
+		set_pte(pg_table, pte);		
 	}
 
 	local_flush_tlb();
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/atari/stram.c linux/arch/m68k/atari/stram.c
--- v2.1.103/linux/arch/m68k/atari/stram.c	Tue Feb 17 13:12:44 1998
+++ linux/arch/m68k/atari/stram.c	Wed May 20 18:54:35 1998
@@ -53,7 +53,7 @@
  * ++roman:
  * 
  * New version of ST-Ram buffer allocation. Instead of using the
- * 1 MB - 4 KB that remain when the the ST-Ram chunk starts at $1000
+ * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
  * (1 MB granularity!), such buffers are reserved like this:
  *
  *  - If the kernel resides in ST-Ram anyway, we can take the buffer
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.1.103/linux/arch/m68k/config.in	Fri May  8 23:14:42 1998
+++ linux/arch/m68k/config.in	Wed May 20 18:54:35 1998
@@ -19,7 +19,7 @@
 endmenu
 
 mainmenu_option next_comment
-comment 'Platform dependant setup'
+comment 'Platform-dependent setup'
 
 bool 'Amiga support' CONFIG_AMIGA
 bool 'Atari support' CONFIG_ATARI
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/fpsp040/res_func.S linux/arch/m68k/fpsp040/res_func.S
--- v2.1.103/linux/arch/m68k/fpsp040/res_func.S	Fri Apr 26 02:12:35 1996
+++ linux/arch/m68k/fpsp040/res_func.S	Wed May 20 18:54:35 1998
@@ -1889,7 +1889,7 @@
 |
 | Input: a0  points to a normalized number in internal extended format
 |	 d0  is the round precision (=1 for sgl; =2 for dbl)
-|	 d1  is the the single precision or double precision
+|	 d1  is the single precision or double precision
 |	     denorm threshold
 |
 | Output: (In the format for dest_sgl or dest_dbl)
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/fpsp040/slogn.S linux/arch/m68k/fpsp040/slogn.S
--- v2.1.103/linux/arch/m68k/fpsp040/slogn.S	Fri Apr 26 02:12:35 1996
+++ linux/arch/m68k/fpsp040/slogn.S	Wed May 20 18:54:35 1998
@@ -17,7 +17,7 @@
 |		result is provably monotonic in double precision.
 |
 |	Speed: The program slogn takes approximately 190 cycles for input 
-|		argument X such that |X-1| >= 1/16, which is the the usual 
+|		argument X such that |X-1| >= 1/16, which is the usual 
 |		situation. For those arguments, slognp1 takes approximately
 |		 210 cycles. For the less common arguments, the program will
 |		 run no worse than 10% slower.
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/fpsp040/ssin.S linux/arch/m68k/fpsp040/ssin.S
--- v2.1.103/linux/arch/m68k/fpsp040/ssin.S	Fri Apr 26 02:12:35 1996
+++ linux/arch/m68k/fpsp040/ssin.S	Wed May 20 18:54:35 1998
@@ -21,7 +21,7 @@
 |		result is provably monotonic in double precision.
 |
 |	Speed: The programs sSIN and sCOS take approximately 150 cycles for
-|		input argument X such that |X| < 15Pi, which is the the usual
+|		input argument X such that |X| < 15Pi, which is the usual
 |		situation. The speed for sSINCOS is approximately 190 cycles.
 |
 |	Algorithm:
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/fpsp040/stan.S linux/arch/m68k/fpsp040/stan.S
--- v2.1.103/linux/arch/m68k/fpsp040/stan.S	Fri Apr 26 02:12:35 1996
+++ linux/arch/m68k/fpsp040/stan.S	Wed May 20 18:54:35 1998
@@ -16,7 +16,7 @@
 |		result is provably monotonic in double precision.
 |
 |	Speed: The program sTAN takes approximately 170 cycles for
-|		input argument X such that |X| < 15Pi, which is the the usual
+|		input argument X such that |X| < 15Pi, which is the usual
 |		situation.
 |
 |	Algorithm:
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/fpsp040/sto_res.S linux/arch/m68k/fpsp040/sto_res.S
--- v2.1.103/linux/arch/m68k/fpsp040/sto_res.S	Tue Apr 23 21:31:24 1996
+++ linux/arch/m68k/fpsp040/sto_res.S	Wed May 20 18:54:35 1998
@@ -3,7 +3,7 @@
 |
 |	Takes the result and puts it in where the user expects it.
 |	Library functions return result in fp0.	If fp0 is not the
-|	users destination register then fp0 is moved to the the
+|	users destination register then fp0 is moved to the
 |	correct floating-point destination register.  fp0 and fp1
 |	are then restored to the original contents. 
 |
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/kernel/time.c linux/arch/m68k/kernel/time.c
--- v2.1.103/linux/arch/m68k/kernel/time.c	Mon Feb 23 18:12:02 1998
+++ linux/arch/m68k/kernel/time.c	Wed May 20 18:54:35 1998
@@ -38,7 +38,7 @@
 			++prof_buffer[pc];
 		else
 		/*
-		 * Dont ignore out-of-bounds PC values silently,
+		 * Don't ignore out-of-bounds PC values silently,
 		 * put them into the last histogram slot, so if
 		 * present, they will show up as a sharp peak.
 		 */
diff -u --recursive --new-file v2.1.103/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
--- v2.1.103/linux/arch/m68k/mm/memory.c	Tue Feb 17 13:12:45 1998
+++ linux/arch/m68k/mm/memory.c	Wed May 20 18:54:36 1998
@@ -137,7 +137,7 @@
 		return;
 	} else {
 		/*
-		 * move this descriptor the the front of the list, since
+		 * move this descriptor to the front of the list, since
 		 * it has one or more free tables.
 		 */
 		save_flags(flags);
diff -u --recursive --new-file v2.1.103/linux/arch/mips/jazz/setup.c linux/arch/mips/jazz/setup.c
--- v2.1.103/linux/arch/mips/jazz/setup.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/jazz/setup.c	Wed May 20 18:54:36 1998
@@ -1,5 +1,5 @@
 /*
- * Setup pointers to hardware dependant routines.
+ * Setup pointers to hardware-dependent routines.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.1.103/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
--- v2.1.103/linux/arch/mips/kernel/setup.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/setup.c	Wed May 20 18:54:36 1998
@@ -177,7 +177,7 @@
 	atag = bi_TagFind(tag_vram_base);
 	memcpy(&mips_vram_base, TAGVALPTR(atag), atag->size);
 
-	/* Save defaults for configuration dependand routines.  */
+	/* Save defaults for configuration-dependent routines.  */
 	irq_setup = default_irq_setup;
 	fd_cacheflush = default_fd_cacheflush;
 #ifdef CONFIG_BLK_DEV_IDE
diff -u --recursive --new-file v2.1.103/linux/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c
--- v2.1.103/linux/arch/mips/kernel/signal.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/signal.c	Wed May 20 18:54:36 1998
@@ -285,14 +285,14 @@
 #if 0
 	if (current->used_math) {	/* fp is active.  */
 		set_cp0_status(ST0_CU1, ST0_CU1);
-		save_fp_context(sc);		/* cpu dependant */
+		save_fp_context(sc);		/* CPU-dependent */
 		last_task_used_math = NULL;
 		regs->cp0_status &= ~ST0_CU1;
 		current->used_math = 0;
 	}
 #endif
 set_cp0_status(ST0_CU1, ST0_CU1);
-save_fp_context(sc);		/* cpu dependant */
+save_fp_context(sc);		/* CPU-dependent */
 
 	__put_user(set->sig[0], &sc->sc_sigset[0]);
 	__put_user(set->sig[1], &sc->sc_sigset[1]);
diff -u --recursive --new-file v2.1.103/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c
--- v2.1.103/linux/arch/mips/kernel/time.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/time.c	Wed May 20 18:54:36 1998
@@ -191,7 +191,7 @@
 			if (inb(0x20) & 0x01) {
 				/*
 				 * We cannot detect lost timer interrupts ... 
-				 * well, thats why we call them lost, dont we? :)
+				 * well, that's why we call them lost, don't we? :)
 				 * [hmm, on the Pentium and Alpha we can ... sort of]
 				 */
 				count -= LATCH;
diff -u --recursive --new-file v2.1.103/linux/arch/mips/kernel/unaligned.c linux/arch/mips/kernel/unaligned.c
--- v2.1.103/linux/arch/mips/kernel/unaligned.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/unaligned.c	Wed May 20 18:54:36 1998
@@ -65,7 +65,7 @@
  *         printf("\n");
  * }
  *
- * Coprozessor loads are not supported; I think this case is unimportant
+ * Coprocessor loads are not supported; I think this case is unimportant
  * in the practice.
  *
  * TODO: Handle ndc (attempted store to doubleword in uncached memory)
@@ -338,7 +338,7 @@
 	case swc2_op:
 	case sdc2_op:
 		/*
-		 * These are the coprozessor 2 load/stores.  The current
+		 * These are the coprocessor 2 load/stores.  The current
 		 * implementations don't use cp2 and cp2 should always be
 		 * disabled in c0_status.  So send SIGILL.
                  * (No longer true: The Sony Praystation uses cp2 for
diff -u --recursive --new-file v2.1.103/linux/arch/mips/sni/setup.c linux/arch/mips/sni/setup.c
--- v2.1.103/linux/arch/mips/sni/setup.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sni/setup.c	Wed May 20 18:54:36 1998
@@ -1,5 +1,5 @@
 /*
- * Setup pointers to hardware dependant routines.
+ * Setup pointers to hardware-dependent routines.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.1.103/linux/arch/ppc/8xx_io/uart.c linux/arch/ppc/8xx_io/uart.c
--- v2.1.103/linux/arch/ppc/8xx_io/uart.c	Fri May  8 23:14:44 1998
+++ linux/arch/ppc/8xx_io/uart.c	Thu May 21 14:24:05 1998
@@ -2324,7 +2324,7 @@
 		 * make it out of the transmit buffer.
 		 */
 		if (i == CONFIG_SERIAL_CONSOLE_PORT)
-			udelay(2000);
+			mdelay(2);
 #endif
 		info = kmalloc(sizeof(ser_info_t), GFP_KERNEL);
 		if (info) {
diff -u --recursive --new-file v2.1.103/linux/arch/ppc/boot/misc.c linux/arch/ppc/boot/misc.c
--- v2.1.103/linux/arch/ppc/boot/misc.c	Fri May  8 23:14:44 1998
+++ linux/arch/ppc/boot/misc.c	Thu May 21 14:24:05 1998
@@ -452,7 +452,7 @@
 			}
 			break;  /* Exit 'timer' loop */
 		}
-		udelay(1000);  /* 1 msec */
+		mdelay(1);  /* 1 msec */
 	}
 	*cp = 0;
 	puts("\n");
diff -u --recursive --new-file v2.1.103/linux/arch/ppc/boot/vreset.c linux/arch/ppc/boot/vreset.c
--- v2.1.103/linux/arch/ppc/boot/vreset.c	Thu Apr 23 20:21:28 1998
+++ linux/arch/ppc/boot/vreset.c	Thu May 21 14:24:05 1998
@@ -416,7 +416,6 @@
 static int scanPCI(int start_slt);
 static int PCIVendor(int);
 static void printslots(void);
-int delayLoop(int);
 extern void puthex(unsigned long);
 extern void puts(const char *);
 static void unlockS3(void);
@@ -495,7 +494,7 @@
 			puts("VGA Chip Vendor ID: ");
 			puthex(PCIVendor(slot));
 			puts("\n");
-			delayLoop(1);
+			mdelay(1000);
 	#endif
 		};
 	
@@ -513,10 +512,10 @@
 	
 	#ifdef DEBUG
 		printslots();
-		delayLoop(5);	
+		mdelay(5000);
 	#endif
 	
-		delayLoop(1);	/* give time for the video monitor to come up */
+		mdelay(1000);	/* give time for the video monitor to come up */
         }
 	return (1);  /* 'CRT' I/O supported */
 }
@@ -805,21 +804,6 @@
 
 	return ( theSlot );
 }
-
-/* Delay for a certain number of seconds */
-/* Note: They loop is used since 'udelay' can't handle really long counts! */
-
-int
-delayLoop(int k)
-{
-	int i;
-	while (k-- > 0) {
-		for (i = 0;  i < 1000;  i++) {
-			udelay(1000);
-		}
-	}
-}
-
 
 /* return Vendor ID of card in the slot */
 static
diff -u --recursive --new-file v2.1.103/linux/arch/ppc/kernel/ppc-stub.c linux/arch/ppc/kernel/ppc-stub.c
--- v2.1.103/linux/arch/ppc/kernel/ppc-stub.c	Thu Apr 23 20:21:29 1998
+++ linux/arch/ppc/kernel/ppc-stub.c	Wed May 20 18:54:36 1998
@@ -604,7 +604,7 @@
 		}
 			break;
 		case 'H':
-			/* dont do anything, yet, just acknowledge */
+			/* don't do anything, yet, just acknowledge */
 			hexToInt(&ptr, &addr);
 			strcpy(remcomOutBuffer,"OK");
 			break;
diff -u --recursive --new-file v2.1.103/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.1.103/linux/arch/ppc/kernel/prom.c	Fri May  8 23:14:45 1998
+++ linux/arch/ppc/kernel/prom.c	Wed May 20 18:54:36 1998
@@ -101,7 +101,7 @@
  * and data have been mapped to KERNELBASE.  At this point the code
  * is running at whatever address it has been loaded at, so
  * references to extern and static variables must be relocated
- * explicitly.  The procedure reloc_offset() returns the the address
+ * explicitly.  The procedure reloc_offset() returns the address
  * we're currently running at minus the address we were linked at.
  * (Note that strings count as static variables.)
  *
diff -u --recursive --new-file v2.1.103/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.1.103/linux/arch/ppc/mm/init.c	Fri May  8 23:14:45 1998
+++ linux/arch/ppc/mm/init.c	Wed May 20 18:54:36 1998
@@ -1305,7 +1305,7 @@
  * someday.
  *
  * For the MBX860 (at this time anyway), there is nothing to initialize
- * associated the the PROM.  Rather than include all of the prom.c
+ * the associated PROM.  Rather than include all of the prom.c
  * functions in the image just to get prom_init, all we really need right
  * now is the initialization of the physical memory region.
  */
diff -u --recursive --new-file v2.1.103/linux/arch/sparc/ap1000/util.c linux/arch/sparc/ap1000/util.c
--- v2.1.103/linux/arch/sparc/ap1000/util.c	Sat Sep 20 14:51:53 1997
+++ linux/arch/sparc/ap1000/util.c	Wed May 20 18:54:36 1998
@@ -42,8 +42,8 @@
 	return res;
 }
 
-/* How many bogo mips in the entire machine
-Dont worry about float because when it gets this big, its irrelevant */
+/* How many BogoMIPS in the entire machine
+Don't worry about float because when it gets this big, it's irrelevant */
 int mpp_agg_bogomips(void)
 {
   return mpp_num_cells()*loops_per_sec/500000; /* cheat in working it out */
diff -u --recursive --new-file v2.1.103/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v2.1.103/linux/arch/sparc/kernel/entry.S	Thu Apr 23 20:21:30 1998
+++ linux/arch/sparc/kernel/entry.S	Wed May 20 18:54:36 1998
@@ -335,7 +335,7 @@
 
 	/* Here is where we check for possible SMP IPI passed to us
 	 * on some level other than 15 which is the NMI and only used
-	 * for cross calls.  That has a seperate entry point below.
+	 * for cross calls.  That has a separate entry point below.
 	 */
 maybe_smp4m_msg:
 	GET_PROCESSOR_MID(o3, o2)
diff -u --recursive --new-file v2.1.103/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
--- v2.1.103/linux/arch/sparc/kernel/head.S	Fri May  8 23:14:45 1998
+++ linux/arch/sparc/kernel/head.S	Wed May 20 18:54:36 1998
@@ -585,7 +585,7 @@
 		bnz	srmmu_nviking			! is in mbus mode
 		 nop
 		
-		rd	%psr, %g3			! DONT TOUCH %g3
+		rd	%psr, %g3			! DO NOT TOUCH %g3
 		andn	%g3, PSR_ET, %g2
 		wr	%g2, 0x0, %psr
 		WRITE_PAUSE
@@ -596,10 +596,10 @@
 		set	AC_M_CTPR, %g4
 		lda	[%g4] ASI_M_MMUREGS, %g4
 		sll	%g4, 0x4, %g4			! We use this below
-							! DONT TOUCH %g4
+							! DO NOT TOUCH %g4
 
 		/* Set the AC bit in the Viking's MMU control reg. */
-		lda	[%g0] ASI_M_MMUREGS, %g5	! DONT TOUCH %g5
+		lda	[%g0] ASI_M_MMUREGS, %g5	! DO NOT TOUCH %g5
 		set	0x8000, %g6			! AC bit mask
 		or	%g5, %g6, %g6			! Or it in...
 		sta	%g6, [%g0] ASI_M_MMUREGS	! Close your eyes...
@@ -1040,7 +1040,7 @@
  * No, it doesn't work, have to play the save/readCWP/restore trick.
  */
 
-		wr	%g0, 0x0, %wim			! so we dont get a trap
+		wr	%g0, 0x0, %wim			! so we do not get a trap
 		WRITE_PAUSE
 
 		save
diff -u --recursive --new-file v2.1.103/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- v2.1.103/linux/arch/sparc/kernel/process.c	Thu Apr 23 20:21:30 1998
+++ linux/arch/sparc/kernel/process.c	Thu May 21 14:24:05 1998
@@ -150,7 +150,7 @@
 void machine_halt(void)
 {
 	sti();
-	udelay(8000);
+	mdelay(8);
 	cli();
 #ifdef CONFIG_SUN_CONSOLE
 	if (!serial_console)
@@ -165,7 +165,7 @@
 	char *p;
 	
 	sti();
-	udelay(8000);
+	mdelay(8);
 	cli();
 
 	p = strchr (reboot_command, '\n');
diff -u --recursive --new-file v2.1.103/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- v2.1.103/linux/arch/sparc64/kernel/process.c	Fri May  8 23:14:46 1998
+++ linux/arch/sparc64/kernel/process.c	Thu May 21 14:24:05 1998
@@ -145,7 +145,7 @@
 void machine_halt(void)
 {
 	sti();
-	udelay(8000);
+	mdelay(8);
 	cli();
 #ifdef CONFIG_SUN_CONSOLE
 	if (!serial_console)
@@ -160,7 +160,7 @@
 	char *p;
 	
 	sti();
-	udelay(8000);
+	mdelay(8);
 	cli();
 
 	p = strchr (reboot_command, '\n');
diff -u --recursive --new-file v2.1.103/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.1.103/linux/arch/sparc64/mm/init.c	Fri May  8 23:14:46 1998
+++ linux/arch/sparc64/mm/init.c	Wed May 20 18:54:36 1998
@@ -925,7 +925,7 @@
 
 	/* The funny offsets are to make page table operations much quicker and
 	 * requite less state, see pgtable.h for gory details.
-	 * pgtable.h assumes null_pmd_table is null_pte_table - PAGE_SIZE, lets
+	 * pgtable.h assumes null_pmd_table is null_pte_table - PAGE_SIZE, let's
 	 * check it now.
 	 */
 	null_pte_table=__pa(((unsigned long)&empty_null_pte_table)+shift);
diff -u --recursive --new-file v2.1.103/linux/arch/sparc64/solaris/misc.c linux/arch/sparc64/solaris/misc.c
--- v2.1.103/linux/arch/sparc64/solaris/misc.c	Thu Apr 23 20:21:32 1998
+++ linux/arch/sparc64/solaris/misc.c	Wed May 20 18:54:36 1998
@@ -164,7 +164,7 @@
 {
 	switch (which) {
 	case 0:	/* old uname */
-		/* Lets cheat */
+		/* Let's cheat */
 		set_utsfield(((struct sol_uname *)A(buf))->sysname, 
 			"SunOS", 1, 0);
 		set_utsfield(((struct sol_uname *)A(buf))->nodename, 
diff -u --recursive --new-file v2.1.103/linux/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c
--- v2.1.103/linux/drivers/acorn/block/fd1772.c	Thu May  7 22:51:47 1998
+++ linux/drivers/acorn/block/fd1772.c	Wed May 20 18:54:37 1998
@@ -507,7 +507,7 @@
 	if (fdc_busy)
 		return;		/* Don't start poking about if the fdc is busy */
 
-	return;			/* lets just forget it for the mo DAG */
+	return;			/* let's just forget it for the mo DAG */
 
 	if (++drive > 1 || !unit[drive].connected)
 		drive = 0;
@@ -533,7 +533,7 @@
 
 
 /* Handling of the Head Settling Flag: This flag should be set after each
- * seek operation, because we dont't use seeks with verify.
+ * seek operation, because we don't use seeks with verify.
  */
 
 static __inline__ void set_head_settle_flag(void)
diff -u --recursive --new-file v2.1.103/linux/drivers/acorn/block/mfm.S linux/drivers/acorn/block/mfm.S
--- v2.1.103/linux/drivers/acorn/block/mfm.S	Fri May  8 23:14:46 1998
+++ linux/drivers/acorn/block/mfm.S	Wed May 20 18:54:37 1998
@@ -150,7 +150,7 @@
   subs r7,r7,#4        @ Decrement bytes to go
   bne readdma_loop
 
-  @ Try reading multiple blocks - if this was fast enough then I dont think
+  @ Try reading multiple blocks - if this was fast enough then I do not think
   @ this should help - NO taken out DAG - new interrupt handler has
   @ non-consecutive memory blocks
   @ sub r0,r0,#8
diff -u --recursive --new-file v2.1.103/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- v2.1.103/linux/drivers/acorn/block/mfmhd.c	Thu May  7 22:51:47 1998
+++ linux/drivers/acorn/block/mfmhd.c	Wed May 20 18:54:37 1998
@@ -447,7 +447,7 @@
 
   /* Now don't handle the error until BSY drops */
 	if ((mfm_status & (STAT_DER | STAT_ABN)) && ((mfm_status&STAT_BSY)==0)) {
-		/* Something has gone wrong - lets try that again */
+		/* Something has gone wrong - let's try that again */
 		outw(CMD_RCAL, MFM_COMMAND);	/* Clear interrupt condition */
 		if (cont) {
 			DBG("mfm_rw_intr: DER/ABN err\n");
@@ -530,7 +530,7 @@
 	old_status = mfm_status;
 	mfm_status = inw(MFM_STATUS);
 	if (mfm_status & (STAT_DER | STAT_ABN)) {
-		/* Something has gone wrong - lets try that again */
+		/* Something has gone wrong - let's try that again */
 		if (cont) {
 			DBG("mfm_rw_intr: DER/ABN error\n");
 			cont->error();
@@ -726,7 +726,7 @@
 	if (uptodate) {
 		unsigned char block[2] = {0, 0};
 
-		/* Apparently worked - lets check bytes left to DMA */
+		/* Apparently worked - let's check bytes left to DMA */
 		if (hdc63463_dataleft != (PartFragRead_SectorsLeft * 256)) {
 			printk("mfm: request_done - dataleft=%d - should be %d - Eek!\n", hdc63463_dataleft, PartFragRead_SectorsLeft * 256);
 			end_request(0);
@@ -734,7 +734,7 @@
 		};
 		/* Potentially this means that we've done; but we might be doing
 		   a partial access, (over two cylinders) or we may have a number
-		   of fragments in an image file.  First lets deal with partial accesss
+		   of fragments in an image file.  First let's deal with partial accesss
 		 */
 		if (PartFragRead) {
 			/* Yep - a partial access */
diff -u --recursive --new-file v2.1.103/linux/drivers/acorn/net/etherh.c linux/drivers/acorn/net/etherh.c
--- v2.1.103/linux/drivers/acorn/net/etherh.c	Fri May  8 23:14:46 1998
+++ linux/drivers/acorn/net/etherh.c	Thu May 21 14:24:05 1998
@@ -429,7 +429,7 @@
 	ei_status.interface_num = 0;
 	if_type = "10BaseT";
 	etherh_setif(dev);
-	udelay(1000);
+	mdelay(1);
 	if (!etherh_getifstat(dev)) {
 		if_type = "10Base2";
 		ei_status.interface_num = 1;
diff -u --recursive --new-file v2.1.103/linux/drivers/block/hd.c linux/drivers/block/hd.c
--- v2.1.103/linux/drivers/block/hd.c	Fri May  8 23:14:47 1998
+++ linux/drivers/block/hd.c	Wed May 20 18:54:37 1998
@@ -804,7 +804,7 @@
 #define DEVICE_BUSY busy[target]
 #define USAGE access_count[target]
 #define CAPACITY (hd_info[target].head*hd_info[target].sect*hd_info[target].cyl)
-/* We assume that the the bios parameters do not change, so the disk capacity
+/* We assume that the BIOS parameters do not change, so the disk capacity
    will not change */
 #undef MAYBE_REINIT
 #define GENDISK_STRUCT hd_gendisk
diff -u --recursive --new-file v2.1.103/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.1.103/linux/drivers/block/md.c	Fri May  8 23:14:47 1998
+++ linux/drivers/block/md.c	Wed May 20 18:54:37 1998
@@ -290,7 +290,7 @@
 	}
 
 	/*
-	 * Ok, we have all disks and the array is ready to run. Lets
+	 * OK, we have all disks and the array is ready to run. Let's
 	 * find the freshest superblock, that one will be the superblock
 	 * that represents the whole array.
 	 */
@@ -1134,7 +1134,7 @@
 		}
 
 		/*
-		 * Lets sleep some if we are faster than our speed limit:
+		 * Let's sleep some if we are faster than our speed limit:
 		 */
 		while (blocksize*j/(jiffies-starttime+1)*HZ/1024 > SPEED_LIMIT)
 		{
diff -u --recursive --new-file v2.1.103/linux/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c
--- v2.1.103/linux/drivers/block/paride/pcd.c	Wed May 20 19:10:38 1998
+++ linux/drivers/block/paride/pcd.c	Thu May 21 14:24:05 1998
@@ -521,7 +521,7 @@
 	int 	r;
 
 	r = pcd_command(unit,rs_cmd,16,"Request sense");
-	udelay(1000);
+	mdelay(1);
 	if (!r) pcd_completion(unit,buf,"Request sense");
 
 	PCD.last_sense = -1;
@@ -538,7 +538,7 @@
 {	int r;
 
 	r = pcd_command(unit,cmd,dlen,fun);
-	udelay(1000);
+	mdelay(1);
 	if (!r) r = pcd_completion(unit,buf,fun);
 	if (r) pcd_req_sense(unit,!fun);
 	
@@ -768,7 +768,7 @@
 		return;
 	}
 
-	udelay(1000);
+	mdelay(1);
 
 	ps_set_intr(do_pcd_read_drq,pcd_ready,PCD_TMO,nice);
 
@@ -802,7 +802,7 @@
 
 	if (pcd_completion(unit,pcd_buffer,"read block")) {
                 if (pcd_retries < PCD_RETRIES) {
-                        udelay(1000);
+                        mdelay(1);
                         pcd_retries++;
 			pi_do_claimed(PI,pcd_start);
                         return;
diff -u --recursive --new-file v2.1.103/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
--- v2.1.103/linux/drivers/block/paride/pf.c	Wed May 20 19:10:38 1998
+++ linux/drivers/block/paride/pf.c	Thu May 21 14:24:05 1998
@@ -617,7 +617,7 @@
         int     r;
 
         r = pf_command(unit,rs_cmd,16,"Request sense");
-        udelay(1000);
+        mdelay(1);
         if (!r) pf_completion(unit,buf,"Request sense");
 
         if ((!r)&&(!quiet)) 
@@ -630,7 +630,7 @@
 {       int r;
 
         r = pf_command(unit,cmd,dlen,fun);
-        udelay(1000);
+        mdelay(1);
         if (!r) r = pf_completion(unit,buf,fun);
         if (r) pf_req_sense(unit,!fun);
         
@@ -864,7 +864,7 @@
 
 	i = pf_command(unit,io_cmd,c*512,"start i/o");
 
-        udelay(1000);
+        mdelay(1);
 
 	return i;	
 }
diff -u --recursive --new-file v2.1.103/linux/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
--- v2.1.103/linux/drivers/block/paride/pt.c	Wed May 20 19:10:38 1998
+++ linux/drivers/block/paride/pt.c	Thu May 21 14:24:05 1998
@@ -436,7 +436,7 @@
         int     r;
 
         r = pt_command(unit,rs_cmd,16,"Request sense");
-        udelay(1000);
+        mdelay(1);
         if (!r) pt_completion(unit,buf,"Request sense");
 
 	PT.last_sense = -1;
@@ -453,7 +453,7 @@
 {       int r;
 
         r = pt_command(unit,cmd,dlen,fun);
-        udelay(1000);
+        mdelay(1);
         if (!r) r = pt_completion(unit,buf,fun);
         if (r) pt_req_sense(unit,!fun);
         
@@ -820,7 +820,7 @@
 
 	    r = pt_command(unit,rd_cmd,n,"read");
 
-	    udelay(1000);
+	    mdelay(1);
 
 	    if (r) {
 	        pt_req_sense(unit,0);
@@ -906,7 +906,7 @@
 
             r = pt_command(unit,wr_cmd,n,"write");
 
-            udelay(1000);
+            mdelay(1);
 
             if (r) {			/* error delivering command only */
                 pt_req_sense(unit,0);
diff -u --recursive --new-file v2.1.103/linux/drivers/block/raid1.c linux/drivers/block/raid1.c
--- v2.1.103/linux/drivers/block/raid1.c	Sat Nov  8 11:39:12 1997
+++ linux/drivers/block/raid1.c	Wed May 20 18:54:37 1998
@@ -164,7 +164,7 @@
 	PRINTK(("raid1_end_request(), write branch.\n"));
 
 	/*
-	 * lets see if all mirrored write operations have finished 
+	 * Let's see if all mirrored write operations have finished 
 	 * already [we have irqs off, so we can decrease]:
 	 */
 
diff -u --recursive --new-file v2.1.103/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c
--- v2.1.103/linux/drivers/cdrom/cm206.c	Thu Feb 12 20:56:05 1998
+++ linux/drivers/cdrom/cm206.c	Thu May 21 14:24:06 1998
@@ -299,7 +299,7 @@
 {
   int loop=POLLOOP;
   while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0) {
-    udelay(1000);		/* one millisec delay */
+    mdelay(1);		/* one millisec delay */
     --loop;
   }
   outw(command, r_uart_transmit);
@@ -309,7 +309,7 @@
 {
   int loop=POLLOOP;
   while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) {
-    udelay(1000);
+    mdelay(1);
     --loop;
   }
   return ((uch) inw(r_uart_receive));
@@ -1194,7 +1194,7 @@
   stop_read();
   reset_cm260();
   outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
-  udelay(1000);			/* 750 musec minimum */
+  mdelay(1);			/* 750 musec minimum */
   outw(dc_normal | READ_AHEAD, r_data_control);
   cd->sector_last = -1;		/* flag no data buffered */
   cd->adapter_last = -1;    
@@ -1358,7 +1358,7 @@
   /* Now, the problem here is that reset_cm260 can generate an
      interrupt. It seems that this can cause a kernel oops some time
      later. So we wait a while and `service' this interrupt. */
-  udelay(1000);
+  mdelay(1);
   outw(dc_normal | READ_AHEAD, r_data_control);
   sti();
   printk(" using IRQ %d\n", cm206_irq);
diff -u --recursive --new-file v2.1.103/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v2.1.103/linux/drivers/cdrom/sbpcd.c	Wed May 20 19:10:38 1998
+++ linux/drivers/cdrom/sbpcd.c	Thu May 21 13:45:01 1998
@@ -5124,14 +5124,16 @@
 		msg(DBG_000, "sbp_data: beginning to read.\n");
 		p = D_S[d].sbp_buf + frame *  CD_FRAMESIZE;
 		if (sbpro_type==1) OUT(CDo_sel_i_d,1);
-		if (cmd_type==READ_M2)
+		if (cmd_type==READ_M2) {
                         if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
                         else insb(CDi_data, xa_head_buf, CD_XA_HEAD);
+		}
 		if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1);
 		else insb(CDi_data, p, CD_FRAMESIZE);
-		if (cmd_type==READ_M2)
+		if (cmd_type==READ_M2) {
                         if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
                         else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
+		}
 		D_S[d].sbp_current++;
 		if (sbpro_type==1) OUT(CDo_sel_i_d,0);
 		if (cmd_type==READ_M2)
diff -u --recursive --new-file v2.1.103/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c
--- v2.1.103/linux/drivers/cdrom/sonycd535.c	Tue Dec  2 11:41:45 1997
+++ linux/drivers/cdrom/sonycd535.c	Wed May 20 18:54:37 1998
@@ -4,7 +4,7 @@
  * This is a modified version of the CDU-31A device driver (see below).
  * Changes were made using documentation for the CDU-531 (which Sony
  * assures me is very similar to the 535) and partial disassembly of the
- * DOS driver.  I used Minyard's driver and replaced the the CDU-31A
+ * DOS driver.  I used Minyard's driver and replaced the CDU-31A
  * commands with the CDU-531 commands.  This was complicated by a different
  * interface protocol with the drive.  The driver is still polled.
  *
diff -u --recursive --new-file v2.1.103/linux/drivers/char/ChangeLog linux/drivers/char/ChangeLog
--- v2.1.103/linux/drivers/char/ChangeLog	Tue Mar 17 22:18:14 1998
+++ linux/drivers/char/ChangeLog	Wed May 20 18:54:37 1998
@@ -84,7 +84,7 @@
 
 	* serial.c (change_speed): Add support for the termios flag
 		CMSPAR, which allows the user to select stick parity.
-		(i.e, if PARODD is set, the the parity bit is always 1; if
+		(i.e, if PARODD is set, the parity bit is always 1; if
 		PARRODD is not set, then the parity bit is always 0).
 
 Wed Feb 26 19:03:10 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
@@ -479,7 +479,7 @@
 Fri Feb 17 09:34:09 1995  Theodore Y. Ts'o  (tytso@rt-11)
 
 	* serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi): 
-		Change the the number of passes made from 64 to be 256,
+		Change the number of passes made from 64 to be 256,
 		configurable with the #define RS_ISR_PASS_LIMIT.
 
 	* serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
diff -u --recursive --new-file v2.1.103/linux/drivers/char/README.epca linux/drivers/char/README.epca
--- v2.1.103/linux/drivers/char/README.epca	Tue May 13 22:41:06 1997
+++ linux/drivers/char/README.epca	Wed May 20 18:54:37 1998
@@ -44,7 +44,7 @@
    as it does not require the rebuilding of the kernel.  In order to use lilo
    to configure Digi boards at boot time an appropriate append command should
    be added to /etc/lilo.conf below the appropriate label decleration.  
-   See footer 4.  The append commands format is a string of comma seperated
+   See footer 4.  The append commands format is a string of comma separated
    identifiers or integers used to configure supported boards.  These six
    values in order are:
 
diff -u --recursive --new-file v2.1.103/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c
--- v2.1.103/linux/drivers/char/apm_bios.c	Thu May  7 22:51:49 1998
+++ linux/drivers/char/apm_bios.c	Wed May 20 18:54:37 1998
@@ -38,7 +38,7 @@
  *         Linux 1.3.85
  *    1.1: support user-space standby and suspend, power off after system
  *         halted, Linux 1.3.98
- *    1.2: When resetting RTC after resume, take care so that the the time
+ *    1.2: When resetting RTC after resume, take care so that the time
  *         is only incorrect by 30-60mS (vs. 1S previously) (Gabor J. Toth
  *         <jtoth@princeton.edu>); improve interaction between
  *         screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
diff -u --recursive --new-file v2.1.103/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.1.103/linux/drivers/char/bttv.c	Wed May 20 19:10:38 1998
+++ linux/drivers/char/bttv.c	Thu May 21 14:24:06 1998
@@ -242,7 +242,7 @@
 		stat=btread(BT848_INT_STAT);
 		if (stat & BT848_INT_I2CDONE)
                         break;
-                udelay(1000);
+                mdelay(1);
 	}
   
 	if (!i) 
@@ -284,7 +284,7 @@
 		stat=btread(BT848_INT_STAT);
 		if (stat & BT848_INT_I2CDONE)
 			break;
-                udelay(1000);
+                mdelay(1);
 	}
   
 	if (!i) 
@@ -475,7 +475,7 @@
 
 	/* This seems to get rid of some synchronization problems */
 	btand(~(3<<5), BT848_IFORM);
-	udelay(10000); 
+	mdelay(10); 
 
 	if (input==3) 
 	{
@@ -1587,12 +1587,13 @@
 				return -EFAULT;
 			if(v.depth!=8 && v.depth!=16 && v.depth!=24 && v.depth!=32)
 				return -EINVAL;
-			if (v.base)
+			if (v.base) {
 			        /* also handle virtual base addresses */
 			        if ((unsigned int)v.base>=0xe0000000UL)
 			                btv->win.vidadr=(uint)v.base;
 				else 
 				  btv->win.vidadr= __va(uvirt_to_bus((uint)v.base));
+			}
 			btv->win.sheight=v.height;
 			btv->win.swidth=v.width;
 			btv->win.bpp=v.depth/8;
diff -u --recursive --new-file v2.1.103/linux/drivers/char/bw-qcam.c linux/drivers/char/bw-qcam.c
--- v2.1.103/linux/drivers/char/bw-qcam.c	Wed Apr  8 19:36:25 1998
+++ linux/drivers/char/bw-qcam.c	Thu May 21 14:24:06 1998
@@ -112,7 +112,7 @@
 	do {
 		qc_command(q, 33);
 		value = qc_readparam(q);
-		udelay(1000);
+		mdelay(1);
 		schedule();
 		count++;
 	} while (value == 0xff && count<2048);
@@ -296,7 +296,7 @@
 		if (reg != lastreg)
 			count++;
 		lastreg = reg;
-		udelay(1000);
+		mdelay(1);
 	}
 
 	/* Be liberal in what you accept...  */
diff -u --recursive --new-file v2.1.103/linux/drivers/char/c-qcam.c linux/drivers/char/c-qcam.c
--- v2.1.103/linux/drivers/char/c-qcam.c	Wed Apr  8 19:36:25 1998
+++ linux/drivers/char/c-qcam.c	Thu May 21 14:24:06 1998
@@ -149,7 +149,7 @@
 	ostat = stat = parport_read_status(qcam->pport);
 	for (i=0; i<250; i++) 
 	{
-		udelay(1000);
+		mdelay(1);
 		stat = parport_read_status(qcam->pport);
 		if (ostat != stat) 
 		{
@@ -166,9 +166,9 @@
 {
 	parport_write_control(qcam->pport, 0xc);
 	parport_write_control(qcam->pport, 0x8);
-	udelay(1000);
+	mdelay(1);
 	parport_write_control(qcam->pport, 0xc);
-	udelay(1000);          
+	mdelay(1);          
 }
 
 /* Reset the QuickCam and program for brightness, contrast,
@@ -325,7 +325,7 @@
 	{
 		/* Turn the port around */
 		parport_frob_control(q->pport, 0x20, 0x20);
-		udelay(3000);
+		mdelay(3);
 		qcam_set_ack(q, 0);
 		if (qcam_await_ready1(q, 1)) {
 			kfree(tmpbuf);
@@ -392,7 +392,7 @@
 			return len;
 		}
 		parport_frob_control(q->pport, 0x20, 0);
-		udelay(3000);
+		mdelay(3);
 		qcam_set_ack(q, 1);
 		if (qcam_await_ready1(q, 0))
 		{
diff -u --recursive --new-file v2.1.103/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.1.103/linux/drivers/char/cyclades.c	Thu May 14 19:47:39 1998
+++ linux/drivers/char/cyclades.c	Wed Jun  3 11:04:16 1998
@@ -1,9 +1,7 @@
 #define BLOCKMOVE
-#define	NEW_INTR_FLOW
 #define	Z_WAKE
-#define	NEW_PCI
 static char rcsid[] =
-"$Revision: 2.2.1.1 $$Date: 1998/03/19 16:43:12 $";
+"$Revision: 2.2.1.3 $$Date: 1998/06/01 12:09:10 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -33,6 +31,13 @@
  *   void cleanup_module(void);
  *
  * $Log: cyclades.c,v $
+ * Revision 2.2.1.3  1998/06/01 12:09:10 ivan
+ * General code review in order to comply with 2.1 kernel standards;
+ * data loss prevention for slow devices revisited (cy_wait_until_sent
+ * was created);
+ * removed conditional compilation for new/old PCI structure support 
+ * (now the driver only supports the new PCI structure).
+ *
  * Revision 2.2.1.1  1998/03/19 16:43:12 ivan
  * added conditional compilation for new/old PCI structure support;
  * removed kernel series (2.0.x / 2.1.x) conditional compilation.
@@ -40,7 +45,7 @@
  * Revision 2.1.1.3  1998/03/16 18:01:12 ivan
  * cleaned up the data loss fix;
  * fixed XON/XOFF handling once more (Cyclades-Z);
- * general revision in the driver routines;
+ * general review of the driver routines;
  * introduction of a mechanism to prevent data loss with slow 
  * printers, by forcing a delay before closing the port.
  *
@@ -482,14 +487,15 @@
 #define ZE_V1	2
 
 #define	SERIAL_PARANOIA_CHECK
-#undef	SERIAL_DEBUG_OPEN
-#undef	SERIAL_DEBUG_THROTTLE
-#undef	SERIAL_DEBUG_OTHER
-#undef	SERIAL_DEBUG_IO
-#undef	SERIAL_DEBUG_COUNT
-#undef	SERIAL_DEBUG_DTR
-#undef	CYCLOM_16Y_HACK
-#undef	CYCLOM_ENABLE_MONITORING
+#undef	CY_DEBUG_OPEN
+#undef	CY_DEBUG_THROTTLE
+#undef	CY_DEBUG_OTHER
+#undef	CY_DEBUG_IO
+#undef	CY_DEBUG_COUNT
+#undef	CY_DEBUG_DTR
+#undef	CY_DEBUG_WAIT_UNTIL_SENT
+#undef	CY_16Y_HACK
+#undef	CY_ENABLE_MONITORING
 #undef	CY_PCI_DEBUG
 
 #if 0
@@ -519,40 +525,38 @@
 		  (cy_readl(&buf_ctrl->tx_bufsize) - 1))
 #endif
 
+/*
+ * Include section 
+ */
+#include <linux/config.h>
 #include <linux/module.h>
-
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
+#include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
-#include <linux/interrupt.h>
+#include <linux/major.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
 #include <linux/cyclades.h>
-#include <linux/delay.h>
-#include <linux/major.h>
 #include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/delay.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/segment.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
 #include <asm/bitops.h>
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#ifndef NEW_PCI
-#include <linux/bios32.h>
-#endif
 #include <linux/pci.h>
-
 #include <linux/version.h>
 
-#include <asm/uaccess.h>
-#include <linux/init.h>
 
 #define cy_put_user	put_user
 
@@ -585,19 +589,16 @@
 
 #define STD_COM_FLAGS (0)
 
-#define SERIAL_TYPE_NORMAL  1
-#define SERIAL_TYPE_CALLOUT 2
-
 static DECLARE_TASK_QUEUE(tq_cyclades);
 
 static struct tty_driver cy_serial_driver, cy_callout_driver;
+static int serial_refcount;
 
 static volatile int cy_irq_triggered;
 static volatile int cy_triggered;
 static int cy_wild_int_mask;
 static volatile ucchar *intr_base_addr;
 
-
 /* This is the address lookup table. The driver will probe for
    Cyclom-Y/ISA boards at all addresses in here. If you want the
    driver to probe addresses at a different address, add it to
@@ -632,8 +633,6 @@
 
 static int cy_next_channel = 0; /* next minor available */
 
-static int serial_refcount;
-
 static struct tty_struct *serial_table[NR_PORTS];
 static struct termios *serial_termios[NR_PORTS];
 static struct termios *serial_termios_locked[NR_PORTS];
@@ -641,8 +640,7 @@
 /* This is the per-irq data structure,
    it maps an irq to the corresponding card */
 
-static struct cyclades_card     *IRQ_cards[16];
-
+static struct cyclades_card     *IRQ_cards[NR_IRQS];
 
 /*
  * tmp_buf is used as a temporary buffer by serial_write.  We need to
@@ -654,7 +652,7 @@
  * memory if large numbers of serial ports are open.  This buffer is
  * allocated when the first cy_open occurs.
  */
-static unsigned char *tmp_buf = 0;
+static unsigned char *tmp_buf;
 static struct semaphore tmp_buf_sem = MUTEX;
 
 /*
@@ -799,41 +797,6 @@
         return 0;
 } /* serial_paranoia_check */
 
-
-/* The following diagnostic routines allow the driver to spew
-   information on the screen, even (especially!) during interrupts.
- */
-static void
-SP(char *data){
-  unsigned long flags;
-    save_flags(flags); cli();
-        console_print(data);
-    restore_flags(flags);
-}/* SP */
-
-static void
-CP(char data){
-  unsigned long flags;
-  char scrn[2];
-    save_flags(flags); cli();
-        scrn[0] = data;
-        scrn[1] = '\0';
-        console_print(scrn);
-    restore_flags(flags);
-}/* CP */
-
-static void CP4(int data)
-    { (data<10)?  CP(data+'0'): CP(data+'A'-10); }/* CP4 */
-static void CP8(int data)
-    { CP4((data>>4) & 0x0f); CP4( data & 0x0f); }/* CP8 */
-#if 0
-static void CP16(int data)
-    { CP8((data>>8) & 0xff); CP8(data & 0xff); }/* CP16 */
-static void CP32(long data)
-    { CP16((data>>16) & 0xffff); CP16(data & 0xffff); }/* CP32 */
-#endif
-
-
 /*
  * This routine is used by the interrupt handler to schedule
  * processing in the software interrupt portion of the driver
@@ -1125,11 +1088,6 @@
         if(cy_readb(intr_base_addr+(CySVRR<<index)) != 0) {
             save_xir = (u_char) cy_readb(intr_base_addr+(CyTIR<<index));
             save_car = cy_readb(intr_base_addr+(CyCAR<<index));
-            if ((save_xir & 0x3) != 0){
-                SP("channel ");
-                CP8(save_xir);
-                SP(" requesting unexpected interrupt\n");
-            }
             cy_writeb((u_long)intr_base_addr+(CyCAR<<index), (save_xir & 0x3));
             cy_writeb((u_long)intr_base_addr+(CySRER<<index),
                 cy_readb(intr_base_addr+(CySRER<<index)) & ~CyTxMpty);
@@ -1286,7 +1244,7 @@
                             /* load # chars available from the chip */
                             char_count = cy_readb(base_addr+(CyRDCR<<index));
 
-#ifdef CYCLOM_ENABLE_MONITORING
+#ifdef CY_ENABLE_MONITORING
                             ++info->mon.int_count;
                             info->mon.char_count += char_count;
                             if (char_count > info->mon.char_max)
@@ -1301,7 +1259,7 @@
                                 data = cy_readb(base_addr+(CyRDSR<<index));
                                 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
                                 *tty->flip.char_buf_ptr++ = data;
-#ifdef CYCLOM_16Y_HACK
+#ifdef CY_16Y_HACK
                                 udelay(10L);
 #endif
                             }
@@ -1387,11 +1345,9 @@
                         info->x_break = 0;
                     }
 
-#ifdef NEW_INTR_FLOW
                     if (!info->xmit_cnt){
                         cy_writeb((u_long)base_addr+(CySRER<<index),
                            cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
-                        cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
                         goto txdone;
                     }
                     if (info->xmit_buf == 0){
@@ -1404,28 +1360,10 @@
                            cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
                         goto txdone;
                     }
-#endif
                     while (char_count-- > 0){
-#ifdef NEW_INTR_FLOW
                         if (!info->xmit_cnt){
                             goto txdone;
                         }
-#else
-                        if (!info->xmit_cnt){
-                            cy_writeb((u_long)base_addr+(CySRER<<index),
-                               cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
-                            goto txdone;
-                        }
-                        if (info->xmit_buf == 0){
-                            cy_writeb((u_long)base_addr+(CySRER<<index),
-                               cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
-                            goto txdone;
-                        }
-                        if (info->tty->stopped || info->tty->hw_stopped){
-                            cy_writeb((u_long)base_addr+(CySRER<<index),
-                               cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
-			}
-#endif
                         /* Because the Embedded Transmit Commands have
                            been enabled, we must check to see if the
 			   escape character, NULL, is being sent.  If it
@@ -1725,14 +1663,12 @@
 		    if ((fw_ver > 241 ? 
                           ((u_long)param) : 
                           cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
-			/* SP("Open Wakeup\n"); */
 			cy_sched_event(info,
 			    Cy_EVENT_OPEN_WAKEUP);
 		    }else if(!((info->flags
 				& ASYNC_CALLOUT_ACTIVE)
 			 &&(info->flags
 			    & ASYNC_CALLOUT_NOHUP))){
-			/* SP("Hangup\n"); */
 			cy_sched_event(info,
 			    Cy_EVENT_HANGUP);
 		    }
@@ -1744,7 +1680,6 @@
 			if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
 			    /* cy_start isn't used because... 
 			       HW flow is handled by the board */
-			    /* SP("Write Wakeup\n"); */
 			    cy_sched_event(info,
 				Cy_EVENT_WRITE_WAKEUP);
 			}
@@ -1752,7 +1687,6 @@
 			if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
 			    /* cy_stop isn't used because 
 			       HW flow is handled by the board */
-			    /* SP("Write stop\n"); */
 			}
 		    }
 		}
@@ -1796,7 +1730,7 @@
 		info->last_active = jiffies;
 		info->jiffies[1] = jiffies;
 
-#ifdef CYCLOM_ENABLE_MONITORING
+#ifdef CY_ENABLE_MONITORING
 		info->mon.int_count++;
 		info->mon.char_count += char_count;
 		if (char_count > info->mon.char_max)
@@ -1806,7 +1740,6 @@
 		if( tty == 0){
 		    /* flush received characters */
 		    rx_get = (rx_get + char_count) & (rx_bufsize - 1);
-		    /* SP("-"); */
 		    info->rflush_count++;
 		}else{
 #ifdef BLOCKMOVE
@@ -1986,7 +1919,7 @@
 	base_addr = (unsigned char*)
 		   (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
 
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
 	printk("cyc startup card %d, chip %d, channel %d, base_addr %lx\n",
 	     card, chip, channel, (long)base_addr);/**/
 #endif
@@ -2004,7 +1937,7 @@
 	    cy_writeb((ulong)base_addr+(CyMSVR1<<index), CyRTS);
 	    cy_writeb((ulong)base_addr+(CyMSVR2<<index), CyDTR);
 
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 	    printk("cyc:startup raising DTR\n");
 	    printk("     status: 0x%x, 0x%x\n",
 		   cy_readb(base_addr+(CyMSVR1<<index)), 
@@ -2040,7 +1973,7 @@
 	board_ctrl = &zfw_ctrl->board_ctrl;
 	ch_ctrl = zfw_ctrl->ch_ctrl;
 
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
 	printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
 	     card, channel, (long)base_addr);/**/
 #endif
@@ -2068,7 +2001,7 @@
 	if (retval != 0){
 	    printk("cyc:startup(2) retval was %x\n", retval);
 	}
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 	    printk("cyc:startup raising Z DTR\n");
 #endif
 
@@ -2082,7 +2015,7 @@
 
     }
 
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
 	printk(" cyc startup done\n");
 #endif
 	return 0;
@@ -2142,7 +2075,7 @@
 		       (cy_card[card].base_addr
 		       + (cy_chip_offset[chip]<<index));
 
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk("cyc shutdown Y card %d, chip %d, channel %d, base_addr %lx\n",
 		card, chip, channel, (long)base_addr);
 #endif
@@ -2159,7 +2092,7 @@
 	    if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
 		cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
 		cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc shutdown dropping DTR\n");
 		printk("     status: 0x%x, 0x%x\n",
 		    cy_readb(base_addr+(CyMSVR1<<index)), 
@@ -2183,7 +2116,7 @@
       int retval;
 
 	base_addr = (unsigned char*) (cy_card[card].base_addr);
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
 		card, channel, (long)base_addr);
 #endif
@@ -2217,7 +2150,7 @@
 		if (retval != 0){
 		    printk("cyc:shutdown retval (2) was %x\n", retval);
 		}
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc:shutdown dropping Z DTR\n");
 #endif
 	    }
@@ -2230,7 +2163,7 @@
 	restore_flags(flags);
     }
 
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk(" cyc shutdown done\n");
 #endif
     return;
@@ -2262,11 +2195,7 @@
 	if (info->flags & ASYNC_CLOSING) {
             interruptible_sleep_on(&info->close_wait);
 	}
-        if (info->flags & ASYNC_HUP_NOTIFY){
-            return -EAGAIN;
-        }else{
-            return -ERESTARTSYS;
-        }
+        return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
     }
 
     /*
@@ -2313,7 +2242,7 @@
      */
     retval = 0;
     add_wait_queue(&info->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
            info->line, info->count);/**/
 #endif
@@ -2321,7 +2250,7 @@
     if (!tty_hung_up_p(filp))
 	info->count--;
     restore_flags(flags);
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
     printk("cyc block_til_ready: (%d): decrementing count to %d\n",
         current->pid, info->count);
 #endif
@@ -2338,11 +2267,12 @@
 
 	while (1) {
 	    save_flags(flags); cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE)){
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD)){
 		    cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
 		    cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
 		    cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		    printk("cyc:block_til_ready raising DTR\n");
 		    printk("     status: 0x%x, 0x%x\n",
 			cy_readb(base_addr+(CyMSVR1<<index)), 
@@ -2353,11 +2283,8 @@
 	    current->state = TASK_INTERRUPTIBLE;
 	    if (tty_hung_up_p(filp)
 	    || !(info->flags & ASYNC_INITIALIZED) ){
-		if (info->flags & ASYNC_HUP_NOTIFY) {
-		    retval = -EAGAIN;
-		}else{
-		    retval = -ERESTARTSYS;
-		}
+		return ((info->flags & ASYNC_HUP_NOTIFY) ? 
+		    -EAGAIN : -ERESTARTSYS);
 		break;
 	    }
 	    save_flags(flags); cli();
@@ -2374,7 +2301,7 @@
 		retval = -ERESTARTSYS;
 		break;
 	    }
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
 	    printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
 		   info->line, info->count);/**/
 #endif
@@ -2408,18 +2335,15 @@
 	    if (retval != 0){
 		printk("cyc:block_til_ready retval was %x\n", retval);
 	    }
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		    printk("cyc:block_til_ready raising Z DTR\n");
 #endif
 
 	    current->state = TASK_INTERRUPTIBLE;
 	    if (tty_hung_up_p(filp)
 	    || !(info->flags & ASYNC_INITIALIZED) ){
-		if (info->flags & ASYNC_HUP_NOTIFY) {
-		    retval = -EAGAIN;
-		}else{
-		    retval = -ERESTARTSYS;
-		}
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+		    -EAGAIN : -ERESTARTSYS);
 		break;
 	    }
 	    if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
@@ -2432,7 +2356,7 @@
 		retval = -ERESTARTSYS;
 		break;
 	    }
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
 	    printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
 		   info->line, info->count);/**/
 #endif
@@ -2443,13 +2367,13 @@
     remove_wait_queue(&info->open_wait, &wait);
     if (!tty_hung_up_p(filp)){
 	info->count++;
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
 	printk("cyc:block_til_ready (%d): incrementing count to %d\n",
 	    current->pid, info->count);
 #endif
     }
     info->blocked_open--;
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
 	   info->line, info->count);/**/
 #endif
@@ -2464,11 +2388,12 @@
  * This routine is called whenever a serial port is opened.  It
  * performs the serial-specific initialization for the tty structure.
  */
-int
+static int
 cy_open(struct tty_struct *tty, struct file * filp)
 {
   struct cyclades_port  *info;
   int retval, line;
+  unsigned long page;
 
     line = MINOR(tty->device) - tty->driver.minor_start;
     if ((line < 0) || (NR_PORTS <= line)){
@@ -2491,46 +2416,50 @@
 		(ZFIRM_HLT==cy_readl(&((struct FIRM_ID *)
 		((cy_card[info->card]).base_addr+ID_ADDRESS))->signature)))
 	    {
-		printk ("Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
+		printk ("cyc:Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
 	    } else {
-		printk("Cyclades-Z firmware not yet loaded\n");
+		printk("cyc:Cyclades-Z firmware not yet loaded\n");
 	    }
 	    return -ENODEV;
 	}
     }
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk("cyc:cy_open ttyC%d\n", info->line); /* */
 #endif
     if (serial_paranoia_check(info, tty->device, "cy_open")){
         return -ENODEV;
     }
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk("cyc:cy_open ttyC%d, count = %d\n",
         info->line, info->count);/**/
 #endif
     info->count++;
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
     printk("cyc:cy_open (%d): incrementing count to %d\n",
         current->pid, info->count);
 #endif
     tty->driver_data = info;
     info->tty = tty;
 
-    /* Some drivers have (incorrect/incomplete) code to test
-       against a race condition.  Should add good code here!!! */
     if (!tmp_buf) {
-        tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
-        if (!tmp_buf){
-            return -ENOMEM;
-        }
+	page = get_free_page(GFP_KERNEL);
+	if (!page)
+	    return -ENOMEM;
+	if (tmp_buf)
+	    free_page(page);
+	else
+	    tmp_buf = (unsigned char *) page;
     }
 
-    if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-        if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-            *tty->termios = info->normal_termios;
-        else 
-            *tty->termios = info->callout_termios;
+    /*
+     * If the port is the middle of closing, bail out now
+     */
+    if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
+	if (info->flags & ASYNC_CLOSING)
+	    interruptible_sleep_on(&info->close_wait);
+	return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
     }
+
     /*
      * Start up serial port
      */
@@ -2543,17 +2472,24 @@
 
     retval = block_til_ready(tty, filp, info);
     if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
         printk("cyc:cy_open returning after block_til_ready with %d\n",
                retval);
 #endif
         return retval;
     }
 
+    if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
+        if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+            *tty->termios = info->normal_termios;
+        else 
+            *tty->termios = info->callout_termios;
+    }
+
     info->session = current->session;
     info->pgrp = current->pgrp;
 
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk(" cyc:cy_open done\n");/**/
 #endif
 
@@ -2562,6 +2498,76 @@
 
 
 /*
+ * cy_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
+  unsigned char *base_addr;
+  int card,chip,channel,index;
+  unsigned long orig_jiffies, char_time;
+	
+    if (serial_paranoia_check(info, tty->device, "cy_wait_until_sent"))
+	return;
+
+    orig_jiffies = jiffies;
+    /*
+     * Set the check interval to be 1/5 of the estimated time to
+     * send a single character, and make it at least 1.  The check
+     * interval should also be less than the timeout.
+     * 
+     * Note: we have to use pretty tight timings here to satisfy
+     * the NIST-PCTS.
+     */
+    char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+    char_time = char_time / 5;
+    if (char_time == 0)
+	char_time = 1;
+    if (timeout < 0)
+	timeout = 0;
+    if (timeout)
+	char_time = MIN(char_time, timeout);
+#ifdef CY_DEBUG_WAIT_UNTIL_SENT
+    printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
+    printk("jiff=%lu...", jiffies);
+#endif
+    card = info->card;
+    channel = (info->line) - (cy_card[card].first_line);
+    if (!IS_CYC_Z(cy_card[card])) {
+	chip = channel>>2;
+	channel &= 0x03;
+	index = cy_card[card].bus_index;
+	base_addr = (unsigned char *)
+		(cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
+	while (cy_readb(base_addr+(CySRER<<index)) & CyTxMpty) {
+#ifdef CY_DEBUG_WAIT_UNTIL_SENT
+	    printk("Not clean (jiff=%lu)...", jiffies);
+#endif
+	    current->state = TASK_INTERRUPTIBLE;
+	    current->counter = 0;	/* make us low-priority */
+	    current->timeout = jiffies + char_time;
+	    schedule();
+	    if (signal_pending(current))
+		break;
+	    if (timeout && ((orig_jiffies + timeout) < jiffies))
+		break;
+	}
+	current->state = TASK_RUNNING;
+    } else {
+	// Nothing to do!
+    }
+    /* Run one more char cycle */
+    current->state = TASK_INTERRUPTIBLE;
+    current->counter = 0;	/* make us low-priority */
+    current->timeout = jiffies + (char_time * 5);
+    schedule();
+    current->state = TASK_RUNNING;
+#ifdef CY_DEBUG_WAIT_UNTIL_SENT
+    printk("Clean (jiff=%lu)...done\n", jiffies);
+#endif
+}
+
+/*
  * This routine is called when a particular tty device is closed.
  */
 static void
@@ -2570,7 +2576,7 @@
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
   unsigned long flags;
 
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk("cyc:cy_close ttyC%d\n", info->line);
 #endif
 
@@ -2578,7 +2584,7 @@
     || serial_paranoia_check(info, tty->device, "cy_close")){
         return;
     }
-#ifdef SERIAL_DEBUG_OPEN
+#ifdef CY_DEBUG_OPEN
     printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
 #endif
 
@@ -2586,6 +2592,7 @@
 
     /* If the TTY is being hung up, nothing to do */
     if (tty_hung_up_p(filp)) {
+	MOD_DEC_USE_COUNT;
         restore_flags(flags);
         return;
     }
@@ -2602,18 +2609,18 @@
            "info->count is %d\n", info->count);
         info->count = 1;
     }
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
     printk("cyc:cy_close at (%d): decrementing count to %d\n",
         current->pid, info->count - 1);
 #endif
     if (--info->count < 0) {
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
     printk("cyc:cyc_close setting count to 0\n");
 #endif
         info->count = 0;
     }
     if (info->count) {
-        MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
         restore_flags(flags);
         return;
     }
@@ -2632,28 +2639,25 @@
     * the line discipline to only process XON/XOFF characters.
     */
     tty->closing = 1;
-    if (info->closing_wait2 != 0) { /* The port's being forced to wait, 
-				       independent on the port settings */
-	tty_wait_until_sent(tty, info->closing_wait2*HZ);
-    } else {
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-	    tty_wait_until_sent(tty, info->closing_wait*HZ);
+    if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
+	tty_wait_until_sent(tty, info->closing_wait);
     }
 
-    /* Waiting for on-board buffers to be empty before closing the port */
     if (!IS_CYC_Z(cy_card[info->card])) {
-#ifdef NEW_INTR_FLOW
 	unsigned char *base_addr = (unsigned char *) 
 					cy_card[info->card].base_addr;
 	int index = cy_card[info->card].bus_index;
-
-	if (cy_readb(base_addr+(CySRER<<index)) & CyTxMpty) {
-	    /* Interrupts are enabled, so go to sleep */
-            interruptible_sleep_on(&info->shutdown_wait);
+	/* Stop accepting input */
+	cy_writeb((u_long)base_addr+(CySRER<<index),
+			cy_readb(base_addr+(CySRER<<index)) & ~CyRxData);
+	if (info->flags & ASYNC_INITIALIZED) {
+	    /* Waiting for on-board buffers to be empty before closing 
+	       the port */
+	    cy_wait_until_sent(tty, info->timeout);
 	}
-#endif
     } else {
 #ifdef Z_WAKE
+	/* Waiting for on-board buffers to be empty before closing the port */
 	unsigned char *base_addr = (unsigned char *) 
 					cy_card[info->card].base_addr;
 	struct FIRM_ID *firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
@@ -2693,7 +2697,7 @@
                      ASYNC_CLOSING);
     wake_up_interruptible(&info->close_wait);
 
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk(" cyc:cy_close done\n");
 #endif
 
@@ -2722,9 +2726,9 @@
 {
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
   unsigned long flags;
-  int c, total = 0;
+  int c, ret = 0;
 
-#ifdef SERIAL_DEBUG_IO
+#ifdef CY_DEBUG_IO
     printk("cyc:cy_write ttyC%d\n", info->line); /* */
 #endif
 
@@ -2736,42 +2740,57 @@
         return 0;
     }
 
-    if (from_user)
-	down(&tmp_buf_sem);
     save_flags(flags);               
-    while (1) {
-        cli();               
-        c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-                           SERIAL_XMIT_SIZE - info->xmit_head));
-        if (c <= 0)
-            break;
 
-        if (from_user) {
-            copy_from_user(tmp_buf, buf, c);
-            c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-                       SERIAL_XMIT_SIZE - info->xmit_head));
-            memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-        } else
-            memcpy(info->xmit_buf + info->xmit_head, buf, c);
-        info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-        info->xmit_cnt += c;
-        restore_flags(flags);
-        buf += c;
-        count -= c;
-        total += c;
-#if 0
-        SP("CW");
-	CP16(c);
-	SP(" ");
-#endif
-    }
-    if (from_user)
+    if (from_user) {
+	down(&tmp_buf_sem);
+	while (1) {
+	    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				SERIAL_XMIT_SIZE - info->xmit_head));
+	    if (c <= 0)
+		break;
+
+	    c -= copy_from_user(tmp_buf, buf, c);
+	    if (!c) {
+		if (!ret) {
+		    ret = -EFAULT;
+		}
+		break;
+	    }
+	    cli();               
+	    c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+			SERIAL_XMIT_SIZE - info->xmit_head));
+	    memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+	    info->xmit_head = ((info->xmit_head + c) & (SERIAL_XMIT_SIZE-1));
+	    info->xmit_cnt += c;
+	    restore_flags(flags);
+	    buf += c;
+	    count -= c;
+	    ret += c;
+	}
 	up(&tmp_buf_sem);
+    } else {
+	while (1) {
+	    cli();
+	    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, 
+			SERIAL_XMIT_SIZE - info->xmit_head));
+	    if (c <= 0) {
+		restore_flags(flags);
+		break;
+	    }
+	    memcpy(info->xmit_buf + info->xmit_head, buf, c);
+	    info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+	    info->xmit_cnt += c;
+	    restore_flags(flags);
+	    buf += c;
+	    count -= c;
+	    ret += c;
+	}
+    }
     if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
         start_xmit(info);
     }
-    restore_flags(flags);
-    return total;
+    return ret;
 } /* cy_write */
 
 
@@ -2788,7 +2807,7 @@
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
   unsigned long flags;
 
-#ifdef SERIAL_DEBUG_IO
+#ifdef CY_DEBUG_IO
     printk("cyc:cy_put_char ttyC%d\n", info->line);
 #endif
 
@@ -2808,9 +2827,6 @@
         info->xmit_head &= SERIAL_XMIT_SIZE - 1;
         info->xmit_cnt++;
     restore_flags(flags);
-#if 0
-	SP("+");
-#endif
 } /* cy_put_char */
 
 
@@ -2826,7 +2842,7 @@
   unsigned char *base_addr;
   int card,chip,channel,index;
                                 
-#ifdef SERIAL_DEBUG_IO
+#ifdef CY_DEBUG_IO
     printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */
 #endif
 
@@ -2871,7 +2887,7 @@
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
   int   ret;
                                 
-#ifdef SERIAL_DEBUG_IO
+#ifdef CY_DEBUG_IO
     printk("cyc:cy_write_room ttyC%d\n", info->line); /* */
 #endif
 
@@ -2897,7 +2913,7 @@
     channel = (info->line) - (cy_card[card].first_line);
 
     if (!IS_CYC_Z(cy_card[card])) {
-#ifdef SERIAL_DEBUG_IO
+#ifdef CY_DEBUG_IO
 	printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
 		info->line, info->xmit_cnt); /* */
 #endif
@@ -2923,7 +2939,7 @@
 	    char_count = tx_put - tx_get;
 	else
 	    char_count = tx_put - tx_get + tx_bufsize;
-#ifdef SERIAL_DEBUG_IO
+#ifdef CY_DEBUG_IO
 	printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
 		info->line, info->xmit_cnt + char_count); /* */
 #endif
@@ -2951,6 +2967,7 @@
   int card,chip,channel,index;
   unsigned cflag, iflag;
   unsigned short chip_number;
+  int baud;
   int   i;
 
 
@@ -2972,47 +2989,21 @@
 	index = cy_card[card].bus_index;
 
 	/* baud rate */
-	i = cflag & CBAUD;
-     
-	if (i & CBAUDEX) {
-	    if (i == B57600)
-		i = 16;
-#ifdef B76800
-	    else if(i == B76800) 
-		i = 17;
-#endif
-	    else if(i == B115200) 
-		i = 18;
-	    else if(i == B230400 && (info->chip_rev >= CD1400_REV_J)) {
-		/* It is a CD1400 rev. J or later */
-		i = 20;
+	baud = tty_get_baud_rate(info->tty);
+	if (baud > CD1400_MAX_SPEED) {
+	    baud = CD1400_MAX_SPEED;
+	}
+	/* find the baud index */
+	for (i = 0; i < 20; i++) {
+	    if (baud == baud_table[i]) {
+		break;
 	    }
-	    else
-		info->tty->termios->c_cflag &= ~CBAUDEX;
 	}
+	if (i == 20) {
+	    i = 19; /* CD1400_MAX_SPEED */
+	} 
+
 
-	if (i == 15) {
-	    if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-		i += 1;
-	    if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-		i += 3;
-       	    if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST){
-                switch(info->baud) {
-		    case 57600:
-			i += 1; break;
-#ifdef B76800
-		    case 76800: 
-			i += 2; break;
-#endif
-		    case 115200:
-			i += 3; break;
-		    case 230400:
-			i += 5; break;
-		    default:
-			break;
-	        }
-            }
-	}
 	if(info->chip_rev >= CD1400_REV_J) {
 	    /* It is a CD1400 rev. J or later */
 	    info->tbpr = baud_bpr_60[i]; /* Tx BPR */
@@ -3026,7 +3017,7 @@
 	    info->rco = baud_co_25[i]; /* Rx CO */
 	}
 	if (baud_table[i] == 134) {
-	    info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
+	    info->timeout = (info->xmit_fifo_size*HZ*15/269) + 2;
 	    /* get it right for 134.5 baud */
 	} else if (baud_table[i]) {
 	    info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
@@ -3168,7 +3159,7 @@
 		} else {
                         cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
 		}
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc:set_line_char dropping DTR\n");
 		printk("     status: 0x%x,
 		    0x%x\n", cy_readb(base_addr+(CyMSVR1<<index)),
@@ -3180,7 +3171,7 @@
                 } else {
 			cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
                 }
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc:set_line_char raising DTR\n");
 		printk("     status: 0x%x, 0x%x\n",
 		    cy_readb(base_addr+(CyMSVR1<<index)),
@@ -3214,49 +3205,17 @@
 	buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
 
 	/* baud rate */
-	switch(i = cflag & CBAUD){
-	/*
-        case B0: cy_writel(&ch_ctrl->comm_baud , 0); break;
-	*/
-        case B50: cy_writel(&ch_ctrl->comm_baud , 50); break;
-        case B75: cy_writel(&ch_ctrl->comm_baud , 75); break;
-        case B110: cy_writel(&ch_ctrl->comm_baud , 110); break;
-        case B134: cy_writel(&ch_ctrl->comm_baud , 134); break;
-        case B150: cy_writel(&ch_ctrl->comm_baud , 150); break;
-        case B200: cy_writel(&ch_ctrl->comm_baud , 200); break;
-        case B300: cy_writel(&ch_ctrl->comm_baud , 300); break;
-        case B600: cy_writel(&ch_ctrl->comm_baud , 600); break;
-        case B1200: cy_writel(&ch_ctrl->comm_baud , 1200); break;
-        case B1800: cy_writel(&ch_ctrl->comm_baud , 1800); break;
-        case B2400: cy_writel(&ch_ctrl->comm_baud , 2400); break;
-        case B4800: cy_writel(&ch_ctrl->comm_baud , 4800); break;
-        case B9600: cy_writel(&ch_ctrl->comm_baud , 9600); break;
-        case B19200: cy_writel(&ch_ctrl->comm_baud , 19200); break;
-        case B38400:
-            if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI){
-                cy_writel(&ch_ctrl->comm_baud , 57600);
-            }else if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI){
-                cy_writel(&ch_ctrl->comm_baud , 115200);
-            }else if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST){
-                cy_writel(&ch_ctrl->comm_baud , info->baud);
-            }else{
-                cy_writel(&ch_ctrl->comm_baud , 38400);
-            }
-            break;
-        case B57600: cy_writel(&ch_ctrl->comm_baud , 57600); break;
-#ifdef B76800
-        case B76800: cy_writel(&ch_ctrl->comm_baud , 76800); break;
-#endif
-        case B115200: cy_writel(&ch_ctrl->comm_baud , 115200); break;
-        case B230400: cy_writel(&ch_ctrl->comm_baud , 230400); break;
-        case B460800: cy_writel(&ch_ctrl->comm_baud , 460800); break;
+	baud = tty_get_baud_rate(info->tty);
+	if (baud > CD1400_MAX_SPEED) {
+	    baud = CD1400_MAX_SPEED;
 	}
+	cy_writel(&ch_ctrl->comm_baud , baud);
 
-	if ((i = cy_readl(&ch_ctrl->comm_baud)) == 134) {
+	if (baud == 134) {
 	    info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
 	    /* get it right for 134.5 baud */
-	} else if (i) {
-	    info->timeout = (info->xmit_fifo_size*HZ*15/i) + 2;
+	} else if (baud) {
+	    info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
 	    /* this needs to be propagated into the card info */
 	} else {
 	    info->timeout = 0;
@@ -3318,16 +3277,16 @@
 		cy_readl(&ch_ctrl->sw_flow) & ~C_FL_OXX);
 	}
 
-	if(i == 0){ /* baud rate is zero, turn off line */
+	if(baud == 0){ /* baud rate is zero, turn off line */
 	    cy_writel(&ch_ctrl->rs_control,
                cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 	    printk("cyc:set_line_char dropping Z DTR\n");
 #endif
 	}else{
 	    cy_writel(&ch_ctrl->rs_control,
                cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 	    printk("cyc:set_line_char raising Z DTR\n");
 #endif
 	}
@@ -3343,6 +3302,21 @@
 	}
     }
 
+    /*
+     * Set up the tty->alt_speed kludge
+     */
+    if (info->tty) {
+	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+	    info->tty->alt_speed = 57600;
+	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+	    info->tty->alt_speed = 115200;
+	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+	    info->tty->alt_speed = 230400;
+	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+	    info->tty->alt_speed = 460800;
+    }
+
+
 } /* set_line_char */
 
 
@@ -3377,9 +3351,8 @@
   struct serial_struct new_serial;
   struct cyclades_port old_info;
 
-    if (!new_info)
-            return -EFAULT;
-    copy_from_user(&new_serial,new_info,sizeof(new_serial));
+    if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+	return -EFAULT;
     old_info = *info;
 
     if (!capable(CAP_SYS_ADMIN)) {
@@ -3405,7 +3378,6 @@
                     (new_serial.flags & ASYNC_FLAGS));
     info->close_delay = new_serial.close_delay * HZ/100;
     info->closing_wait = new_serial.closing_wait * HZ/100;
- 
 
 check_and_exit:
     if (info->flags & ASYNC_INITIALIZED){
@@ -3486,8 +3458,7 @@
 	}
 
     }
-    cy_put_user(result,(unsigned long *) value);
-    return 0;
+    return cy_put_user(result,(unsigned long *) value);
 } /* get_modem_info */
 
 
@@ -3535,7 +3506,7 @@
                 } else {
 		    cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
                 }
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc:set_modem_info raising DTR\n");
 		printk("     status: 0x%x, 0x%x\n",
 		    cy_readb(base_addr+(CyMSVR1<<index)), 
@@ -3564,7 +3535,7 @@
                 } else {
 			cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
                 }
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc:set_modem_info dropping DTR\n");
 		printk("     status: 0x%x, 0x%x\n",
 		    cy_readb(base_addr+(CyMSVR1<<index)), 
@@ -3601,7 +3572,7 @@
                 } else {
 			cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
                 }
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc:set_modem_info raising DTR\n");
 		printk("     status: 0x%x, 0x%x\n",
 		    cy_readb(base_addr+(CyMSVR1<<index)), 
@@ -3617,7 +3588,7 @@
 			cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
                 }
 
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		printk("cyc:set_modem_info dropping DTR\n");
 		printk("     status: 0x%x, 0x%x\n",
 		    cy_readb(base_addr+(CyMSVR1<<index)), 
@@ -3649,7 +3620,7 @@
 		if (arg & TIOCM_DTR){
 		    cy_writel(&ch_ctrl[channel].rs_control,
                        cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		    printk("cyc:set_modem_info raising Z DTR\n");
 #endif
 		}
@@ -3662,7 +3633,7 @@
 		if (arg & TIOCM_DTR){
 		    cy_writel(&ch_ctrl[channel].rs_control,
                        cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		    printk("cyc:set_modem_info clearing Z DTR\n");
 #endif
 		}
@@ -3678,13 +3649,13 @@
 		if (arg & TIOCM_DTR){
 		    cy_writel(&ch_ctrl[channel].rs_control,
                        cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		    printk("cyc:set_modem_info raising Z DTR\n");
 #endif
 		}else{
 		    cy_writel(&ch_ctrl[channel].rs_control,
                        cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
-#ifdef SERIAL_DEBUG_DTR
+#ifdef CY_DEBUG_DTR
 		    printk("cyc:set_modem_info clearing Z DTR\n");
 #endif
 		}
@@ -3705,7 +3676,6 @@
     return 0;
 } /* set_modem_info */
 
-
 static void
 send_break( struct cyclades_port * info, int duration)
 {
@@ -3737,7 +3707,6 @@
     }
 } /* send_break */
 
-
 static int
 get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
 {
@@ -3796,11 +3765,11 @@
 		       + (cy_chip_offset[chip]<<index));
 
 	tmp = cy_readb(base_addr+(CyCOR3<<index)) & CyREC_FIFO;
-	cy_put_user(tmp,value);
+	return cy_put_user(tmp,value);
     } else {
 	// Nothing to do!
+	return 0;
     }
-    return 0;
 }/* get_threshold */
 
 
@@ -3815,8 +3784,7 @@
 static int
 get_default_threshold(struct cyclades_port * info, unsigned long *value)
 {
-    cy_put_user(info->default_threshold,value);
-    return 0;
+    return cy_put_user(info->default_threshold,value);
 }/* get_default_threshold */
 
 
@@ -3862,11 +3830,11 @@
 		       + (cy_chip_offset[chip]<<index));
 
 	tmp = cy_readb(base_addr+(CyRTPR<<index));
-	cy_put_user(tmp,value);
+	return cy_put_user(tmp,value);
     } else {
 	// Nothing to do!
+	return 0;
     }
-    return 0;
 }/* get_timeout */
 
 
@@ -3881,8 +3849,7 @@
 static int
 get_default_timeout(struct cyclades_port * info, unsigned long *value)
 {
-    cy_put_user(info->default_timeout,value);
-    return 0;
+    return cy_put_user(info->default_timeout,value);
 }/* get_default_timeout */
 
 /*
@@ -3894,68 +3861,40 @@
 cy_ioctl(struct tty_struct *tty, struct file * file,
             unsigned int cmd, unsigned long arg)
 {
-  int error;
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
   int ret_val = 0;
 
-#ifdef SERIAL_DEBUG_OTHER
+    if (serial_paranoia_check(info, tty->device, "cy_ioctl"))
+	return -ENODEV;
+
+#ifdef CY_DEBUG_OTHER
     printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
         info->line, cmd, arg); /* */
 #endif
 
     switch (cmd) {
         case CYGETMON:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(struct cyclades_monitor));
-            if (error){
-                ret_val = error;
-                break;
-            }
             ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
             break;
         case CYGETTHRESH:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(unsigned long));
-            if (error){
-                ret_val = error;
-                break;
-            }
             ret_val = get_threshold(info, (unsigned long *)arg);
             break;
         case CYSETTHRESH:
             ret_val = set_threshold(info, (unsigned long)arg);
             break;
         case CYGETDEFTHRESH:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(unsigned long));
-            if (error){
-                ret_val = error;
-                break;
-            }
             ret_val = get_default_threshold(info, (unsigned long *)arg);
             break;
         case CYSETDEFTHRESH:
             ret_val = set_default_threshold(info, (unsigned long)arg);
             break;
         case CYGETTIMEOUT:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(unsigned long));
-            if (error){
-                ret_val = error;
-                break;
-            }
             ret_val = get_timeout(info, (unsigned long *)arg);
             break;
         case CYSETTIMEOUT:
             ret_val = set_timeout(info, (unsigned long)arg);
             break;
         case CYGETDEFTIMEOUT:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(unsigned long));
-            if (error){
-                ret_val = error;
-                break;
-            }
             ret_val = get_default_timeout(info, (unsigned long *)arg);
             break;
         case CYSETDEFTIMEOUT:
@@ -3976,14 +3915,10 @@
 	    ret_val = info->rtsdtr_inv;
 	    break;
 	case CYGETCARDINFO:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(struct cyclades_card));
-            if (error){
-                ret_val = error;
-                break;
-            }
-            copy_to_user((void *)arg, (void *)&cy_card[info->card], 
-			 sizeof (struct cyclades_card));
+            if (copy_to_user((void *)arg, (void *)&cy_card[info->card], 
+			sizeof (struct cyclades_card))) {
+		ret_val = -EFAULT;
+	    }
 	    ret_val = 0;
             break;
 	case CYGETCD1400VER:
@@ -3994,91 +3929,46 @@
 	    ret_val = 0;
 	    break;
 	case CYSETWAIT:
-    	    info->closing_wait2 = (unsigned short)arg;
+    	    info->closing_wait = (unsigned short)arg * HZ/100;
 	    ret_val = 0;
 	    break;
 	case CYGETWAIT:
-	    ret_val = info->closing_wait2;
+	    ret_val = info->closing_wait / (HZ/100);
 	    break;
-        case TCSBRK:    /* SVID version: non-zero arg --> no break */
-            ret_val = tty_check_change(tty);
-            if (ret_val)
-                return ret_val;
-            tty_wait_until_sent(tty,0);
-            if (!arg)
-                send_break(info, HZ/4); /* 1/4 second */
-            break;
-        case TCSBRKP:   /* support for POSIX tcsendbreak() */
-            ret_val = tty_check_change(tty);
-            if (ret_val)
-                return ret_val;
-            tty_wait_until_sent(tty,0);
-            send_break(info, arg ? arg*(HZ/10) : HZ/4);
+	case TCSBRK:    /* SVID version: non-zero arg --> no break */
+	    ret_val = tty_check_change(tty);
+	    if (ret_val)
+		return ret_val;
+	    tty_wait_until_sent(tty,0);
+	    if (!arg)
+		send_break(info, HZ/4); /* 1/4 second */
+	    break;
+	case TCSBRKP:   /* support for POSIX tcsendbreak() */
+	    ret_val = tty_check_change(tty);
+	    if (ret_val)
+		return ret_val;
+	    tty_wait_until_sent(tty,0);
+	    send_break(info, arg ? arg*(HZ/10) : HZ/4);
+	    break;
+        case TIOCMGET:
+            ret_val = get_modem_info(info, (unsigned int *) arg);
             break;
         case TIOCMBIS:
         case TIOCMBIC:
         case TIOCMSET:
             ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
             break;
-
-/* The following commands are incompletely implemented!!! */
-        case TIOCGSOFTCAR:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(unsigned int *));
-            if (error){
-                ret_val = error;
-                break;
-            }
-            cy_put_user(C_CLOCAL(tty) ? 1 : 0,
-                        (unsigned long *) arg);
-            break;
-        case TIOCSSOFTCAR:
-           error = verify_area(VERIFY_READ, (void *) arg
-                                ,sizeof(unsigned long *));
-           if (error) {
-                ret_val = error;
-                break;
-           }
-
-            arg = cy_get_user((unsigned long *) arg);
-            tty->termios->c_cflag =
-                    ((tty->termios->c_cflag & ~CLOCAL) |
-                     (arg ? CLOCAL : 0));
-            break;
-        case TIOCMGET:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(unsigned int *));
-            if (error){
-                ret_val = error;
-                break;
-            }
-            ret_val = get_modem_info(info, (unsigned int *) arg);
-            break;
         case TIOCGSERIAL:
-            error = verify_area(VERIFY_WRITE, (void *) arg
-                                ,sizeof(struct serial_struct));
-            if (error){
-                ret_val = error;
-                break;
-            }
-            ret_val = get_serial_info(info,
-                                   (struct serial_struct *) arg);
+            ret_val = get_serial_info(info, (struct serial_struct *) arg);
             break;
         case TIOCSSERIAL:
-            error = verify_area(VERIFY_READ, (void *) arg
-                                ,sizeof(struct serial_struct));
-            if (error){
-                ret_val = error;
-                break;
-            }
-            ret_val = set_serial_info(info,
-                                   (struct serial_struct *) arg);
+            ret_val = set_serial_info(info, (struct serial_struct *) arg);
             break;
         default:
             ret_val = -ENOIOCTLCMD;
     }
 
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk(" cyc:cy_ioctl done\n");
 #endif
 
@@ -4097,7 +3987,7 @@
 {
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk("cyc:cy_set_termios ttyC%d\n", info->line);
 #endif
 
@@ -4141,7 +4031,7 @@
   unsigned char *base_addr;
   int card,chip,channel,index;
 
-#ifdef SERIAL_DEBUG_THROTTLE
+#ifdef CY_DEBUG_THROTTLE
   char buf[64];
 
     printk("cyc:throttle %s: %d....ttyC%d\n", 
@@ -4197,7 +4087,7 @@
   unsigned char *base_addr;
   int card,chip,channel,index;
 
-#ifdef SERIAL_DEBUG_THROTTLE
+#ifdef CY_DEBUG_THROTTLE
   char buf[64];
         
     printk("cyc:unthrottle %s: %d....ttyC%d\n", 
@@ -4255,7 +4145,7 @@
   int chip,channel,index;
   unsigned long flags;
 
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk("cyc:cy_stop ttyC%d\n", info->line); /* */
 #endif
 
@@ -4295,7 +4185,7 @@
   int chip,channel,index;
   unsigned long flags;
 
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk("cyc:cy_start ttyC%d\n", info->line); /* */
 #endif
 
@@ -4333,7 +4223,7 @@
   int card, channel;
   unsigned long flags;
                                 
-#ifdef SERIAL_DEBUG_IO
+#ifdef CY_DEBUG_IO
     printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */
 #endif
 
@@ -4377,7 +4267,7 @@
 {
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
         
-#ifdef SERIAL_DEBUG_OTHER
+#ifdef CY_DEBUG_OTHER
     printk("cyc:cy_hangup ttyC%d\n", info->line); /* */
 #endif
 
@@ -4388,7 +4278,7 @@
     shutdown(info);
     info->event = 0;
     info->count = 0;
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
     printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
 #endif
     info->tty = 0;
@@ -4422,7 +4312,7 @@
     for(chip_number=0; chip_number<CyMAX_CHIPS_PER_CARD; chip_number++){
         base_addr = true_base_addr
 	               + (cy_chip_offset[chip_number]<<index);
-        udelay(1000L);
+        mdelay(1);
         if(cy_readb(base_addr+(CyCCR<<index)) != 0x00){
             /*************
             printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
@@ -4448,7 +4338,7 @@
         }
 
         cy_writeb((u_long)base_addr+(CyCCR<<index), CyCHIP_RESET);
-        udelay(1000L);
+        mdelay(1);
 
         if(cy_readb(base_addr+(CyGFRCR<<index)) == 0x00){
             /*
@@ -4593,88 +4483,45 @@
 {
 #ifdef CONFIG_PCI
 
-#ifdef NEW_PCI
   struct pci_dev	*pdev = NULL;
   unsigned char		cyy_rev_id;
-#else
-  unsigned char         cyy_bus, cyy_dev_fn, cyy_rev_id;
-#endif
   unsigned long         pci_intr_ctrl;
-  unsigned char         cy_pci_irq;
+  unsigned char         cy_pci_irq = 0;
   uclong                cy_pci_addr0, cy_pci_addr1, cy_pci_addr2;
   unsigned short        i,j,cy_pci_nchan;
   unsigned short        device_id,dev_index = 0;
-#ifndef NEW_PCI
-  unsigned short	board_index = 0;
-#endif
   uclong		mailbox;
   uclong		Ze_addr0[NR_CARDS], Ze_addr2[NR_CARDS], ZeIndex = 0;
 
-#ifdef NEW_PCI
         if(pci_present() == 0) {    /* PCI bus not present */
-#else
-        if(pcibios_present() == 0) {    /* PCI bus not present */
-#endif
                 return(0);
         }
         for (i = 0; i < NR_CARDS; i++) {
                 /* look for a Cyclades card by vendor and device id */
                 while((device_id = cy_pci_dev_id[dev_index]) != 0) {
-#ifdef NEW_PCI
                         if((pdev = pci_find_device(PCI_VENDOR_ID_CYCLADES,
                                         device_id, pdev)) == NULL) {
                                 dev_index++;    /* try next device id */
                         } else {
                                 break;          /* found a board */
                         }
-#else
-                        if(pcibios_find_device(PCI_VENDOR_ID_CYCLADES,
-                                        device_id,board_index,
-                                        &cyy_bus, &cyy_dev_fn) != 0) {
-                                dev_index++;    /* try next device id */
-                                board_index = 0;
-                        } else {
-                                board_index++;
-                                break;          /* found a board */
-                        }
-#endif
                 }
 
 		if (device_id == 0)
 		    break;
 
                 /* read PCI configuration area */
-#ifdef NEW_PCI
 		cy_pci_irq = pdev->irq;
 		cy_pci_addr0 = pdev->base_address[0];
 		cy_pci_addr1 = pdev->base_address[1]; 
 		cy_pci_addr2 = pdev->base_address[2]; 
                 pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
-#else
-                pcibios_read_config_byte(cyy_bus, cyy_dev_fn,
-                                 PCI_INTERRUPT_LINE, &cy_pci_irq);
-                pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
-                                  PCI_BASE_ADDRESS_0, 
-				  (unsigned int *) &cy_pci_addr0);
-                pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
-                                  PCI_BASE_ADDRESS_1, 
-				  (unsigned int *) &cy_pci_addr1);
-                pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
-                                  PCI_BASE_ADDRESS_2, 
-				  (unsigned int *) &cy_pci_addr2);
-                pcibios_read_config_byte(cyy_bus, cyy_dev_fn,
-                                  PCI_REVISION_ID, &cyy_rev_id);
-#endif
 
     if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo)
 	   || (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){
 #ifdef CY_PCI_DEBUG
             printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
-#ifdef NEW_PCI
 		pdev->bus->number, pdev->devfn);
-#else
-		cyy_bus, cyy_dev_fn);
-#endif
             printk("rev_id=%d) IRQ%d\n",
 		cyy_rev_id, (int)cy_pci_irq);
             printk("Cyclom-Y/PCI:found  winaddr=0x%lx ioaddr=0x%lx\n",
@@ -4686,11 +4533,7 @@
 #if defined(__alpha__)
                 if (device_id  == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
 		    printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
-#ifdef NEW_PCI
 			pdev->bus->number, pdev->devfn);
-#else
-			cyy_bus, cyy_dev_fn);
-#endif
 		    printk("rev_id=%d) IRQ%d\n",
 		        cyy_rev_id, (int)cy_pci_irq);
                     printk("Cyclom-Y/PCI:found  winaddr=0x%lx ioaddr=0x%lx\n",
@@ -4775,11 +4618,7 @@
     }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo){
 	    /* print message */
 		printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
-#ifdef NEW_PCI
 		    pdev->bus->number, pdev->devfn);
-#else
-		    cyy_bus, cyy_dev_fn);
-#endif
 		printk("rev_id=%d) IRQ%d\n",
 		    cyy_rev_id, (int)cy_pci_irq);
 		printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
@@ -4789,11 +4628,7 @@
     }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){
 #ifdef CY_PCI_DEBUG
             printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
-#ifdef NEW_PCI
 	        pdev->bus->number, pdev->devfn);
-#else
-	        cyy_bus, cyy_dev_fn);
-#endif
             printk("rev_id=%d) IRQ%d\n",
 		cyy_rev_id, (int)cy_pci_irq);
             printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
@@ -5077,6 +4912,7 @@
     
     memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
     cy_serial_driver.magic = TTY_DRIVER_MAGIC;
+    cy_serial_driver.name = "cyclades";
     cy_serial_driver.name = "ttyC";
     cy_serial_driver.major = CYCLADES_MAJOR;
     cy_serial_driver.minor_start = 0;
@@ -5106,6 +4942,7 @@
     cy_serial_driver.stop = cy_stop;
     cy_serial_driver.start = cy_start;
     cy_serial_driver.hangup = cy_hangup;
+    cy_serial_driver.wait_until_sent = cy_wait_until_sent;
 
     /*
      * The callout device is just like normal device except for
@@ -5115,6 +4952,9 @@
     cy_callout_driver.name = "cub";
     cy_callout_driver.major = CYCLADESAUX_MAJOR;
     cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+    cy_callout_driver.read_proc = 0;
+    cy_callout_driver.proc_entry = 0;
+
 
     if (tty_register_driver(&cy_serial_driver))
             panic("Couldn't register Cyclades serial driver\n");
@@ -5123,7 +4963,7 @@
 
     init_bh(CYCLADES_BH, do_cyclades_bh);
 
-    for (i = 0; i < 16; i++) {
+    for (i = 0; i < NR_IRQS; i++) {
             IRQ_cards[i] = 0;
     }
 
@@ -5199,11 +5039,10 @@
                     info->rco = 0;
                     info->close_delay = 5*HZ/10;
 		    info->closing_wait = CLOSING_WAIT_DELAY;
-		    info->closing_wait2 = 0;
                     info->x_char = 0;
                     info->event = 0;
                     info->count = 0;
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
 //        printk("cyc:cy_init(1) setting Z count to 0\n");
 #endif
                     info->blocked_open = 0;
@@ -5250,7 +5089,6 @@
                     info->cor5 = 0;
                     info->close_delay = 5*HZ/10;
 		    info->closing_wait = CLOSING_WAIT_DELAY;
-		    info->closing_wait2 = 0;
 		    chip_number = (port - cinfo->first_line) / 4;
                     if ((info->chip_rev = cy_readb(cinfo->base_addr +
 	               		 (cy_chip_offset[chip_number]<<index) +
@@ -5273,7 +5111,7 @@
                     info->x_char = 0;
                     info->event = 0;
                     info->count = 0;
-#ifdef SERIAL_DEBUG_COUNT
+#ifdef CY_DEBUG_COUNT
 //        printk("cyc:cy_init(2) setting Y count to 0\n");
 #endif
                     info->blocked_open = 0;
diff -u --recursive --new-file v2.1.103/linux/drivers/char/epca.c linux/drivers/char/epca.c
--- v2.1.103/linux/drivers/char/epca.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/char/epca.c	Wed May 20 18:54:37 1998
@@ -3956,7 +3956,7 @@
 					translate (To an unsigned long obviously),  the second argument
 					can be the address of any character variable or a NULL.  If a
 					variable is given, the end pointer of the string will be stored 
-					in that variable; if a NULL is given the the end pointer will 
+					in that variable; if a NULL is given the end pointer will 
 					not be returned.  The last argument is the base to use.  If 
 					a 0 is indicated, the routine will attempt to determine the 
 					proper base by looking at the values prefix (A '0' for octal,
diff -u --recursive --new-file v2.1.103/linux/drivers/char/ftape/lowlevel/fdc-io.c linux/drivers/char/ftape/lowlevel/fdc-io.c
--- v2.1.103/linux/drivers/char/ftape/lowlevel/fdc-io.c	Mon Feb 23 18:12:04 1998
+++ linux/drivers/char/ftape/lowlevel/fdc-io.c	Wed May 20 18:54:37 1998
@@ -214,7 +214,7 @@
 		 * sending the step pulses to the drive. Therefore the
 		 * non-interrupt level driver has no chance to tell
 		 * whether the isr() just has issued a seek. Therefore
-		 * we HAVE TO have a look at the the ft_hide_interrupt
+		 * we HAVE TO have a look at the ft_hide_interrupt
 		 * flag: it signals the non-interrupt level part of
 		 * the driver that it has to wait for the fdc until it
 		 * has completet seeking.
diff -u --recursive --new-file v2.1.103/linux/drivers/char/ftape/lowlevel/ftape_syms.c linux/drivers/char/ftape/lowlevel/ftape_syms.c
--- v2.1.103/linux/drivers/char/ftape/lowlevel/ftape_syms.c	Tue Nov 25 14:45:27 1997
+++ linux/drivers/char/ftape/lowlevel/ftape_syms.c	Wed May 20 18:54:37 1998
@@ -20,7 +20,7 @@
  * $Revision: 1.4 $
  * $Date: 1997/10/17 00:03:51 $
  *
- *      This file contains the the symbols that the ftape low level
+ *      This file contains the symbols that the ftape low level
  *      part of the QIC-40/80/3010/3020 floppy-tape driver "ftape"
  *      exports to it's high level clients
  */
diff -u --recursive --new-file v2.1.103/linux/drivers/char/ftape/zftape/zftape_syms.c linux/drivers/char/ftape/zftape/zftape_syms.c
--- v2.1.103/linux/drivers/char/ftape/zftape/zftape_syms.c	Mon Feb 23 18:12:04 1998
+++ linux/drivers/char/ftape/zftape/zftape_syms.c	Wed May 20 18:54:37 1998
@@ -20,7 +20,7 @@
  * $Revision: 1.3 $
  * $Date: 1997/10/05 19:19:14 $
  *
- *      This file contains the the symbols that the zftape frontend to 
+ *      This file contains the symbols that the zftape frontend to 
  *      the ftape floppy tape driver exports 
  */		 
 
diff -u --recursive --new-file v2.1.103/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
--- v2.1.103/linux/drivers/char/istallion.c	Thu May  7 22:51:49 1998
+++ linux/drivers/char/istallion.c	Thu May 21 14:24:06 1998
@@ -3361,7 +3361,6 @@
 static void stli_onbinit(stlibrd_t *brdp)
 {
 	unsigned long	memconf;
-	int		i;
 
 #if DEBUG
 	printk("stli_onbinit(brdp=%d)\n", (int) brdp);
@@ -3370,13 +3369,12 @@
 	outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
 	udelay(10);
 	outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 
 	memconf = (brdp->memaddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT;
 	outb(memconf, (brdp->iobase + ONB_ATMEMAR));
 	outb(0x1, brdp->iobase);
-	udelay(1000);
+	mdelay(1);
 }
 
 /*****************************************************************************/
@@ -3425,7 +3423,6 @@
 
 static void stli_onbreset(stlibrd_t *brdp)
 {	
-	int	i;
 
 #if DEBUG
 	printk("stli_onbreset(brdp=%x)\n", (int) brdp);
@@ -3434,8 +3431,7 @@
 	outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
 	udelay(10);
 	outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 }
 
 /*****************************************************************************/
@@ -3447,7 +3443,6 @@
 static void stli_onbeinit(stlibrd_t *brdp)
 {
 	unsigned long	memconf;
-	int		i;
 
 #if DEBUG
 	printk("stli_onbeinit(brdp=%d)\n", (int) brdp);
@@ -3457,15 +3452,14 @@
 	outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
 	udelay(10);
 	outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 
 	memconf = (brdp->memaddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL;
 	outb(memconf, (brdp->iobase + ONB_EIMEMARL));
 	memconf = (brdp->memaddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH;
 	outb(memconf, (brdp->iobase + ONB_EIMEMARH));
 	outb(0x1, brdp->iobase);
-	udelay(1000);
+	mdelay(1);
 }
 
 /*****************************************************************************/
@@ -3521,7 +3515,6 @@
 
 static void stli_onbereset(stlibrd_t *brdp)
 {	
-	int	i;
 
 #if DEBUG
 	printk("stli_onbereset(brdp=%x)\n", (int) brdp);
@@ -3530,8 +3523,7 @@
 	outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
 	udelay(10);
 	outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 }
 
 /*****************************************************************************/
@@ -3542,7 +3534,6 @@
 
 static void stli_bbyinit(stlibrd_t *brdp)
 {
-	int	i;
 
 #if DEBUG
 	printk("stli_bbyinit(brdp=%d)\n", (int) brdp);
@@ -3551,10 +3542,9 @@
 	outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
 	udelay(10);
 	outb(0, (brdp->iobase + BBY_ATCONFR));
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 	outb(0x1, brdp->iobase);
-	udelay(1000);
+	mdelay(1);
 }
 
 /*****************************************************************************/
@@ -3587,7 +3577,6 @@
 
 static void stli_bbyreset(stlibrd_t *brdp)
 {	
-	int	i;
 
 #if DEBUG
 	printk("stli_bbyreset(brdp=%x)\n", (int) brdp);
@@ -3596,8 +3585,7 @@
 	outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
 	udelay(10);
 	outb(0, (brdp->iobase + BBY_ATCONFR));
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 }
 
 /*****************************************************************************/
@@ -3608,15 +3596,13 @@
 
 static void stli_stalinit(stlibrd_t *brdp)
 {
-	int	i;
 
 #if DEBUG
 	printk("stli_stalinit(brdp=%d)\n", (int) brdp);
 #endif
 
 	outb(0x1, brdp->iobase);
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 }
 
 /*****************************************************************************/
@@ -3646,7 +3632,6 @@
 static void stli_stalreset(stlibrd_t *brdp)
 {	
 	volatile unsigned long	*vecp;
-	int			i;
 
 #if DEBUG
 	printk("stli_stalreset(brdp=%x)\n", (int) brdp);
@@ -3655,8 +3640,7 @@
 	vecp = (volatile unsigned long *) (brdp->membase + 0x30);
 	*vecp = 0xffff0000;
 	outb(0, brdp->iobase);
-	for (i = 0; (i < 1000); i++)
-		udelay(1000);
+	mdelay(1000);
 }
 
 /*****************************************************************************/
@@ -4167,10 +4151,9 @@
 		outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
 		udelay(10);
 		outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
-		for (i = 0; (i < 100); i++)
-			udelay(1000);
+		mdelay(100);
 		outb(0x1, brdp->iobase);
-		udelay(1000);
+		mdelay(1);
 		stli_onbeenable(brdp);
 	} else {
 		return(-ENODEV);
diff -u --recursive --new-file v2.1.103/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v2.1.103/linux/drivers/char/lp.c	Thu May  7 22:51:49 1998
+++ linux/drivers/char/lp.c	Sun May 24 12:09:36 1998
@@ -16,6 +16,8 @@
  * 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>
+ * Interrupt handling workaround for printers with buggy handshake
+ *				by Andrea Arcangeli, 11 May 98
  */
 
 /* This driver should, in theory, work with any parallel port that has an
@@ -62,6 +64,23 @@
  * can force it using the parameters described above.
  */
 
+/*
+ * The new interrupt handling code take care of the buggy handshake
+ * of some HP and Epson printer:
+ * ___
+ * ACK    _______________    ___________
+ *                       |__|
+ * ____
+ * BUSY   _________              _______
+ *                 |____________|
+ *
+ * I discovered this using the printer scanner:
+ *
+ *	http://www.cs.unibo.it/~arcangel/pscan/pscan-0.4.tar.gz
+ *
+ *					11 May 98, Andrea Arcangeli
+ */
+
 #include <linux/module.h>
 #include <linux/init.h>
 
@@ -93,7 +112,7 @@
 #ifdef LP_STATS
 			   0, 0, {0},
 #endif
-			   NULL, 0}
+			   NULL, 0, 0}
 };
 
 /* Test if printer is ready (and optionally has no error conditions) */
@@ -135,8 +154,12 @@
 
 static __inline__ void lp_yield (int minor)
 {
-	if (!parport_yield_blocking (lp_table[minor].dev) && need_resched)
-		schedule ();
+	if (!parport_yield_blocking (lp_table[minor].dev))
+	{
+		if (need_resched)
+			schedule ();
+	} else
+		lp_table[minor].irq_missed = 1;
 }
 
 static __inline__ void lp_schedule(int minor)
@@ -145,6 +168,7 @@
 	register unsigned long int timeslip = (jiffies - dev->time);
 	if ((timeslip > dev->timeslice) && (dev->port->waithead != NULL)) {
 		lp_parport_release(minor);
+		lp_table[minor].irq_missed = 1;
 		schedule ();
 		lp_parport_claim(minor);
 	} else
@@ -165,7 +189,6 @@
 
 static inline int lp_char(char lpchar, int minor)
 {
-	unsigned char status;
 	unsigned int wait = 0;
 	unsigned long count = 0;
 #ifdef LP_STATS
@@ -175,12 +198,10 @@
 	for (;;)
 	{
 		lp_yield(minor);
-		status = r_str (minor);
-		if (LP_READY(minor, status))
+		if (LP_READY(minor, r_str(minor)))
 			break;
-		if (!LP_POLLED(minor) || ++count == LP_CHAR(minor) ||
-		     signal_pending(current))
-			return 0;
+ 		if (++count == LP_CHAR(minor) || signal_pending(current))
+ 			return 0;
 	}
 
 	w_dtr(minor, lpchar);
@@ -205,7 +226,15 @@
 	udelay(1);
 #endif
 	/* take strobe low */
-	w_ctr(minor, LP_PSELECP | LP_PINITP);
+	if (LP_POLLED(minor))
+		/* take strobe low */
+		w_ctr(minor, LP_PSELECP | LP_PINITP);
+	else
+	{
+		lp_table[minor].irq_detected = 0;
+		lp_table[minor].irq_missed = 0;
+		w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PINTEN);
+	}
 
 #ifdef LP_STATS
 	/* update waittime statistics */
@@ -231,6 +260,9 @@
 
 	if (waitqueue_active (&lp_dev->wait_q))
 		wake_up_interruptible(&lp_dev->wait_q);
+
+	lp_dev->irq_detected = 1;
+	lp_dev->irq_missed = 0;
 }
 
 static void lp_error(int minor)
@@ -241,10 +273,12 @@
 		lp_parport_release(minor);
 		schedule();
 		lp_parport_claim(minor);
+		lp_table[minor].irq_missed = 1;
 	}
 }
 
-static int lp_check_status(int minor) {
+static int lp_check_status(int minor)
+{
 	unsigned int last = lp_table[minor].last_error;
 	unsigned char status = r_str(minor);
 	if ((status & LP_POUTPA)) {
@@ -282,7 +316,6 @@
 	unsigned long total_bytes_written = 0;
 	unsigned long bytes_written;
 	struct lp_struct *lp = &lp_table[minor];
-	unsigned char status;
 
 	if (minor >= LP_NO)
 		return -ENXIO;
@@ -290,13 +323,21 @@
 		return -ENXIO;
 
 	lp_table[minor].last_error = 0;
+	lp_table[minor].irq_detected = 0;
+	lp_table[minor].irq_missed = 0;
+
+	if (!LP_POLLED(minor))
+		w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PINTEN);
 
 	do {
 		bytes_written = 0;
 		copy_size = (count <= LP_BUFFER_SIZE ? count : LP_BUFFER_SIZE);
 
 		if (copy_from_user(lp->lp_buffer, buf, copy_size))
+		{
+			w_ctr(minor, LP_PINITP);
 			return -EFAULT;
+		}
 
 		while (copy_size) {
 			if (lp_char(lp->lp_buffer[bytes_written], minor)) {
@@ -314,7 +355,9 @@
 				LP_STAT(minor).sleeps++;
 #endif
 
-				if (signal_pending(current)) {
+				if (signal_pending(current))
+				{
+					w_ctr(minor, LP_PINITP);
 					if (total_bytes_written + bytes_written)
 						return total_bytes_written + bytes_written;
 					else
@@ -325,9 +368,15 @@
 				lp->runchars = 0;
 #endif
 
-				if (LP_POLLED(minor)) {
-					if (lp_check_status(minor))
-						return rc ? rc : -EIO;
+				if (lp_check_status(minor))
+				{
+					w_ctr(minor, LP_PINITP);
+					return rc ? rc : -EIO;
+				}
+
+				if (LP_POLLED(minor) ||
+				    lp_table[minor].irq_missed)
+				{
 				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));
@@ -342,28 +391,19 @@
 						/*
 						 * We can' t sleep on the interrupt
 						 * since another pardevice need the port.
+						 * We must check this in a cli() protected
+						 * envinroment to avoid parport sharing
+						 * starvation.
 						 */
 						sti();
 						goto lp_polling;
 					}
-					w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PINTEN);
-					status = r_str(minor);
-					if (!(status & LP_PACK) || (status & LP_PBUSY))
+					if (!lp_table[minor].irq_detected)
 					{
-						/*
-						 * 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->wait_q);
 					}
-					current->timeout = jiffies + LP_TIMEOUT_INTERRUPT;
-					interruptible_sleep_on(&lp->wait_q);
-					w_ctr(minor, LP_PSELECP | LP_PINITP);
 					sti();
-					if (lp_check_status(minor))
-						return rc ? rc : -EIO;
 				}
 			}
 		}
@@ -374,6 +414,7 @@
 
 	} while (count > 0);
 
+	w_ctr(minor, LP_PINITP);
 	return total_bytes_written;
 }
 
diff -u --recursive --new-file v2.1.103/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.1.103/linux/drivers/char/mem.c	Thu May 14 19:47:39 1998
+++ linux/drivers/char/mem.c	Wed May 20 18:54:37 1998
@@ -284,7 +284,7 @@
 			return 0;
 	}
 	
-	/* The shared case is hard. Lets do the conventional zeroing. */ 
+	/* The shared case is hard. Let's do the conventional zeroing. */ 
 	do {
 		unsigned long unwritten = clear_user(buf, PAGE_SIZE);
 		if (unwritten)
diff -u --recursive --new-file v2.1.103/linux/drivers/char/msp3400.c linux/drivers/char/msp3400.c
--- v2.1.103/linux/drivers/char/msp3400.c	Wed Apr  8 19:36:26 1998
+++ linux/drivers/char/msp3400.c	Thu May 21 14:24:06 1998
@@ -88,14 +88,14 @@
 {
 	int ret = 0;
     
-	udelay(2000);
+	mdelay(2);
 	i2c_start(bus);
 	i2c_sendbyte(bus, I2C_MSP3400C,2000);
 	i2c_sendbyte(bus, 0x00,0);
 	i2c_sendbyte(bus, 0x80,0);
 	i2c_sendbyte(bus, 0x00,0);
 	i2c_stop(bus);
-	udelay(2000);
+	mdelay(2);
 	i2c_start(bus);
 	if (0 != i2c_sendbyte(bus, I2C_MSP3400C,2000) ||
 		0 != i2c_sendbyte(bus, 0x00,0) ||
@@ -106,7 +106,7 @@
 		printk(KERN_ERR "msp3400: chip reset failed, penguin on i2c bus?\n");
 	}
 	i2c_stop(bus);
-	udelay(2000);
+	mdelay(2);
 	return ret;
 }
 
diff -u --recursive --new-file v2.1.103/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- v2.1.103/linux/drivers/char/pc_keyb.c	Tue Apr 14 14:29:20 1998
+++ linux/drivers/char/pc_keyb.c	Thu May 21 14:24:06 1998
@@ -231,7 +231,7 @@
 	do {
 		if (! (inb_p(KBD_STATUS_REG) & KBD_STAT_IBF))
 			return;
-		udelay(1000);
+		mdelay(1);
 		timeout--;
 	} while (timeout);
 #ifdef KBD_REPORT_TIMEOUTS
@@ -583,7 +583,7 @@
 				return 1;
 			if (resend)
 				break;
-			udelay(1000);
+			mdelay(1);
 			if (!--timeout) {
 #ifdef KBD_REPORT_TIMEOUTS
 				printk(KERN_WARNING "Keyboard timeout\n");
diff -u --recursive --new-file v2.1.103/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c
--- v2.1.103/linux/drivers/char/pcwd.c	Mon Jan 12 15:12:42 1998
+++ linux/drivers/char/pcwd.c	Thu May 21 14:24:06 1998
@@ -126,7 +126,7 @@
 
 	/* Sleep 1/2 second (or 500000 microseconds :) */
 
-		udelay(500000L);
+		mdelay(500);
 		done = 0;
 
 	/* If there's a heart beat in both instances, then this means we
@@ -455,7 +455,7 @@
 	int i;
 
 	outb_p(cmd, current_readport + 2);
-	udelay(1000L);
+	mdelay(1);
 
 	i = inb(current_readport);
 	i = inb(current_readport);
diff -u --recursive --new-file v2.1.103/linux/drivers/char/pcxx.c linux/drivers/char/pcxx.c
--- v2.1.103/linux/drivers/char/pcxx.c	Sat Sep 20 14:51:54 1997
+++ linux/drivers/char/pcxx.c	Wed May 20 18:54:37 1998
@@ -619,7 +619,7 @@
 ** worth noting that while I'm not sure what this hunk of code is supposed
 ** to do, it is not present in the serial.c driver.  Hmmm.  If you know,
 ** please send me a note.  brian@ilinx.com
-** Dont know either what this is supposed to do clameter@waterf.org.
+** Don't know either what this is supposed to do clameter@waterf.org.
 */
 		if(tty->ldisc.num != ldiscs[N_TTY].num) {
 			if(tty->ldisc.close)
diff -u --recursive --new-file v2.1.103/linux/drivers/char/pms.c linux/drivers/char/pms.c
--- v2.1.103/linux/drivers/char/pms.c	Wed Apr  8 19:36:26 1998
+++ linux/drivers/char/pms.c	Wed May 20 18:54:37 1998
@@ -630,7 +630,7 @@
 		while (cnt <= 0) 
 		{ 
 			/*
-			 *	Dont copy too far
+			 *	Don't copy too far
 			 */
 			int dt=dw;
 			if(dt+len>count)
diff -u --recursive --new-file v2.1.103/linux/drivers/char/random.c linux/drivers/char/random.c
--- v2.1.103/linux/drivers/char/random.c	Thu May  7 22:51:49 1998
+++ linux/drivers/char/random.c	Mon May 25 10:32:52 1998
@@ -1,9 +1,10 @@
 /*
  * random.c -- A strong random number generator
  *
- * Version 1.03, last modified 26-Apr-97
+ * Version 1.04, last modified 26-Apr-98
  * 
- * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997.  All rights reserved.
+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998.  All rights
+ * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -73,12 +74,12 @@
  * an *estimate* of how many bits of randomness have been stored into
  * the random number generator's internal state.
  * 
- * When random bytes are desired, they are obtained by taking the MD5
- * hash of the contents of the "entropy pool".  The MD5 hash avoids
+ * When random bytes are desired, they are obtained by taking the SHA
+ * hash of the contents of the "entropy pool".  The SHA hash avoids
  * exposing the internal state of the entropy pool.  It is believed to
  * be computationally infeasible to derive any useful information
- * about the input of MD5 from its output.  Even if it is possible to
- * analyze MD5 in some clever way, as long as the amount of data
+ * about the input of SHA from its output.  Even if it is possible to
+ * analyze SHA in some clever way, as long as the amount of data
  * returned from the generator is less than the inherent entropy in
  * the pool, the output data is totally unpredictable.  For this
  * reason, the routine decreases its internal estimate of how many
@@ -88,7 +89,7 @@
  * If this estimate goes to zero, the routine can still generate
  * random numbers; however, an attacker may (at least in theory) be
  * able to infer the future output of the generator from prior
- * outputs.  This requires successful cryptanalysis of MD5, which is
+ * outputs.  This requires successful cryptanalysis of SHA, which is
  * not believed to be feasible, but there is a remote possibility.
  * Nonetheless, these numbers should be useful for the vast majority
  * of purposes.
@@ -162,12 +163,14 @@
  * sequence: 
  *
  *	echo "Initializing random number generator..."
+ * 	random_seed=/var/run/random-seed
  *	# Carry a random seed from start-up to start-up
  *	# Load and then save 512 bytes, which is the size of the entropy pool
- * 	if [ -f /etc/random-seed ]; then
- *		cat /etc/random-seed >/dev/urandom
+ * 	if [ -f $random_seed ]; then
+ *		cat $random_seed >/dev/urandom
  * 	fi
- *	dd if=/dev/urandom of=/etc/random-seed count=1
+ *	dd if=/dev/urandom of=$random_seed count=1
+ * 	chmod 600 $random_seed
  *
  * and the following lines in an appropriate script which is run as
  * the system is shutdown:
@@ -175,10 +178,14 @@
  *	# Carry a random seed from shut-down to start-up
  *	# Save 512 bytes, which is the size of the entropy pool
  *	echo "Saving random seed..."
- *	dd if=/dev/urandom of=/etc/random-seed count=1
- * 
- * For example, on many Linux systems, the appropriate scripts are
- * usually /etc/rc.d/rc.local and /etc/rc.d/rc.0, respectively.
+ * 	random_seed=/var/run/random-seed
+ *	dd if=/dev/urandom of=$random_seed count=1
+ * 	chmod 600 $random_seed
+ * 
+ * For example, on most modern systems using the System V init
+ * scripts, such code fragments would be found in
+ * /etc/rc.d/init.d/random.  On older Linux systems, the correct script
+ * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
  * 
  * Effectively, these commands cause the contents of the entropy pool
  * to be saved at shut-down time and reloaded into the entropy pool at
@@ -204,18 +211,17 @@
  * =================
  *
  * Ideas for constructing this random number generator were derived
- * from the Pretty Good Privacy's random number generator, and from
- * private discussions with Phil Karn.  Colin Plumb provided a faster
- * random number generator, which speed up the mixing function of the
- * entropy pool, taken from PGP 3.0 (under development).  It has since
- * been modified by myself to provide better mixing in the case where
- * the input values to add_entropy_word() are mostly small numbers.
- * Dale Worley has also contributed many useful ideas and suggestions
- * to improve this driver.
+ * from Pretty Good Privacy's random number generator, and from private
+ * discussions with Phil Karn.  Colin Plumb provided a faster random
+ * number generator, which speed up the mixing function of the entropy
+ * pool, taken from PGPfone.  Dale Worley has also contributed many
+ * useful ideas and suggestions to improve this driver.
  * 
  * Any flaws in the design are solely my responsibility, and should
  * not be attributed to the Phil, Colin, or any of authors of PGP.
  * 
+ * The code for SHA transform was taken from Peter Gutmann's
+ * implementation, which has been placed in the public domain.
  * The code for MD5 transform was taken from Colin Plumb's
  * implementation, which has been placed in the public domain.  The
  * MD5 cryptographic checksum was devised by Ronald Rivest, and is
@@ -246,26 +252,66 @@
  */
 #undef RANDOM_BENCHMARK
 #undef BENCHMARK_NOINT
+#define ROTATE_PARANOIA
 
-/*
- * The pool is stirred with a primitive polynomial of degree 128
- * over GF(2), namely x^128 + x^99 + x^59 + x^31 + x^9 + x^7 + 1.
- * For a pool of size 64, try x^64+x^62+x^38+x^10+x^6+x+1.
- */
 #define POOLWORDS 128    /* Power of 2 - note that this is 32-bit words */
 #define POOLBITS (POOLWORDS*32)
-#if POOLWORDS == 128
-#define TAP1    99     /* The polynomial taps */
-#define TAP2    59
-#define TAP3    31
-#define TAP4    9
-#define TAP5    7
-#elif POOLWORDS == 64
-#define TAP1    62      /* The polynomial taps */
-#define TAP2    38
-#define TAP3    10
-#define TAP4    6
-#define TAP5    1
+/*
+ * The pool is stirred with a primitive polynomial of degree POOLWORDS
+ * over GF(2).  The taps for various sizes are defined below.  They are
+ * chosen to be evenly spaced (minimum RMS distance from evenly spaced;
+ * the numbers in the comments are a scaled squared error sum) except
+ * for the last tap, which is 1 to get the twisting happening as fast
+ * as possible.
+ */
+#if POOLWORDS == 2048	/* 115 x^2048+x^1638+x^1231+x^819+x^411+x^1+1 */
+#define TAP1	1638
+#define TAP2	1231
+#define TAP3	819
+#define TAP4	411
+#define TAP5	1
+#elif POOLWORDS == 1024	/* 290 x^1024+x^817+x^615+x^412+x^204+x^1+1 */
+/* Alt: 115 x^1024+x^819+x^616+x^410+x^207+x^2+1 */
+#define TAP1	817
+#define TAP2	615
+#define TAP3	412
+#define TAP4	204
+#define TAP5	1
+#elif POOLWORDS == 512	/* 225 x^512+x^411+x^308+x^208+x^104+x+1 */
+/* Alt: 95 x^512+x^409+x^307+x^206+x^102+x^2+1
+ *      95 x^512+x^409+x^309+x^205+x^103+x^2+1 */
+#define TAP1	411
+#define TAP2	308
+#define TAP3	208
+#define TAP4	104
+#define TAP5	1
+#elif POOLWORDS == 256	/* 125 x^256+x^205+x^155+x^101+x^52+x+1 */
+#define TAP1	205
+#define TAP2	155
+#define TAP3	101
+#define TAP4	52
+#define TAP5	1
+#elif POOLWORDS == 128	/* 105 x^128+x^103+x^76+x^51+x^25+x+1 */
+/* Alt: 70 x^128+x^103+x^78+x^51+x^27+x^2+1 */
+#define TAP1	103
+#define TAP2	76
+#define TAP3	51
+#define TAP4	25
+#define TAP5	1
+#elif POOLWORDS == 64	/* 15 x^64+x^52+x^39+x^26+x^14+x+1 */
+#define TAP1	52
+#define TAP2	39
+#define TAP3	26
+#define TAP4	14
+#define TAP5	1
+#elif POOLWORDS == 32	/* 15 x^32+x^26+x^20+x^14+x^7+x^1+1 */
+#define TAP1	26
+#define TAP2	20
+#define TAP3	14
+#define TAP4	7
+#define TAP5	1
+#elif POOLWORDS & (POOLWORDS-1)
+#error POOLWORDS must be a power of 2
 #else
 #error No primitive polynomial available for chosen POOLWORDS
 #endif
@@ -279,11 +325,38 @@
  * Also see M. Matsumoto & Y. Kurita, 1994.  Twisted GFSR generators
  * II.  ACM Transactions on Mdeling and Computer Simulation 4:254-266)
  *
- * Thanks to Colin Plumb for suggesting this.  (Note that the behavior
- * of the 1.0 version of the driver was equivalent to using a second
- * element of 0x80000000).
+ * Thanks to Colin Plumb for suggesting this.
+ * We have not analyzed the resultant polynomial to prove it primitive;
+ * in fact it almost certainly isn't.  Nonetheless, the irreducible factors
+ * of a random large-degree polynomial over GF(2) are more than large enough
+ * that periodicity is not a concern.
+ *
+ * The input hash is much less sensitive than the output hash.  All that
+ * we want of it is that it be a good non-cryptographic hash; i.e. it
+ * not produce collisions when fed "random" data of the sort we expect
+ * to see.  As long as the pool state differs for different inputs, we
+ * have preserved the input entropy and done a good job.  The fact that an
+ * intelligent attacker can construct inputs that will produce controlled
+ * alterations to the pool's state is not important because we don't
+ * consider such inputs to contribute any randomness.
+ * The only property we need with respect to them is
+ * that the attacker can't increase his/her knowledge of the pool's state.
+ * Since all additions are reversible (knowing the final state and the
+ * input, you can reconstruct the initial state), if an attacker has
+ * any uncertainty about the initial state, he/she can only shuffle that
+ * uncertainty about, but never cause any collisions (which would
+ * decrease the uncertainty).
+ *
+ * The chosen system lets the state of the pool be (essentially) the input
+ * modulo the generator polymnomial.  Now, for random primitive polynomials,
+ * this is a universal class of hash functions, meaning that the chance
+ * of a collision is limited by the attacker's knowledge of the generator
+ * polynomail, so if it is chosen at random, an attacker can never force
+ * a collision.  Here, we use a fixed polynomial, but we *can* assume that
+ * ###--> it is unknown to the processes generating the input entropy. <-###
+ * Because of this important property, this is a good, collision-resistant
+ * hash; hash collisions will occur no more often than chance.
  */
-static __u32 twist_table[2] = { 0, 0xEDB88320 };
 
 /*
  * The minimum number of bits to release a "wait on input".  Should
@@ -303,7 +376,9 @@
 struct random_bucket {
 	unsigned add_ptr;
 	unsigned entropy_count;
+#ifdef ROTATE_PARANOIA	
 	int input_rotate;
+#endif
 	__u32 pool[POOLWORDS];
 };
 
@@ -332,8 +407,8 @@
 
 /* There is one of these per entropy source */
 struct timer_rand_state {
-	unsigned long	last_time;
-	int 		last_delta,last_delta2;
+	__u32		last_time;
+	__s32		last_delta,last_delta2;
 	int		dont_count_entropy:1;
 };
 
@@ -356,11 +431,10 @@
 static int random_ioctl(struct inode * inode, struct file * file,
 			unsigned int cmd, unsigned long arg);
 
-static inline void fast_add_entropy_word(struct random_bucket *r,
-					 const __u32 input);
+static inline void fast_add_entropy_words(struct random_bucket *r,
+					 __u32 x, __u32 y);
 
-static void add_entropy_word(struct random_bucket *r,
-				    const __u32 input);
+static void add_entropy_words(struct random_bucket *r, __u32 x, __u32 y);
 
 #ifndef MIN
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
@@ -391,33 +465,36 @@
  * More asm magic....
  * 
  * For entropy estimation, we need to do an integral base 2
- * logarithm.  By default, use an open-coded C version, although we do
- * have a version which takes advantage of the Intel's x86's "bsr"
- * instruction.
+ * logarithm.  
+ *
+ * Note the "12bits" suffix - this is used for numbers between
+ * 0 and 4095 only.  This allows a few shortcuts.
  */
-#if (!defined (__i386__))
-static inline __u32 int_ln(__u32 word)
+#if 0	/* Slow but clear version */
+static inline __u32 int_ln_12bits(__u32 word)
 {
 	__u32 nbits = 0;
 	
-	while (1) {
-		word >>= 1;
-		if (!word)
-			break;
+	while (word >>= 1)
 		nbits++;
-	}
 	return nbits;
 }
-#else
-static inline __u32 int_ln(__u32 word)
+#else	/* Faster (more clever) version, courtesy Colin Plumb */
+static inline __u32 int_ln_12bits(__u32 word)
 {
-	__asm__("bsrl %1,%0\n\t"
-		"jnz 1f\n\t"
-		"movl $0,%0\n"
-		"1:"
-		:"=r" (word)
-		:"r" (word));
-	return word;
+	/* Smear msbit right to make an n-bit mask */
+	word |= word >> 8;
+	word |= word >> 4;
+	word |= word >> 2;
+	word |= word >> 1;
+	/* Remove one bit to make this a logarithm */
+	word >>= 1;
+	/* Count the bits set in the word */
+	word -= (word >> 1) & 0x555;
+	word = (word & 0x333) + ((word >> 2) & 0x333);
+	word += (word >> 4);
+	word += (word >> 8);
+	return word & 15;
 }
 #endif
 
@@ -429,19 +506,18 @@
  */
 static void init_std_data(struct random_bucket *r)
 {
-	__u32 word, *p;
+	__u32 words[2], *p;
 	int i;
 	struct timeval 	tv;
 
 	do_gettimeofday(&tv);
-	add_entropy_word(r, tv.tv_sec);
-	add_entropy_word(r, tv.tv_usec);
+	add_entropy_words(r, tv.tv_sec, tv.tv_usec);
 
-	for (p = (__u32 *) &system_utsname,
-	     i = sizeof(system_utsname) / sizeof(__u32);
-	     i ; i--, p++) {
-		memcpy(&word, p, sizeof(__u32));
-		add_entropy_word(r, word);
+	p = (__u32 *)&system_utsname;
+	for (i = sizeof(system_utsname) / sizeof(words); i; i--) {
+		memcpy(words, p, sizeof(words));
+		add_entropy_words(r, words[0], words[1]);
+		p += sizeof(words)/sizeof(*words);
 	}
 	
 }
@@ -513,54 +589,90 @@
  * This function adds a byte into the entropy "pool".  It does not
  * update the entropy estimate.  The caller must do this if appropriate.
  *
- * The pool is stirred with a primitive polynomial of degree 128
- * over GF(2), namely x^128 + x^99 + x^59 + x^31 + x^9 + x^7 + 1.
- * For a pool of size 64, try x^64+x^62+x^38+x^10+x^6+x+1.
- * 
- * We rotate the input word by a changing number of bits, to help
- * assure that all bits in the entropy get toggled.  Otherwise, if we
- * consistently feed the entropy pool small numbers (like jiffies and
- * scancodes, for example), the upper bits of the entropy pool don't
- * get affected. --- TYT, 10/11/95
- */
-static inline void fast_add_entropy_word(struct random_bucket *r,
-					 const __u32 input)
-{
-	unsigned i;
-	int new_rotate;
-	__u32 w;
+ * This function is tuned for speed above most other considerations.
+ *
+ * The pool is stirred with a primitive polynomial of the appropriate degree,
+ * and then twisted.  We twist by three bits at a time because it's
+ * cheap to do so and helps slightly in the expected case where the
+ * entropy is concentrated in the low-order bits.
+ */
+#define MASK(x) ((x) & (POOLWORDS-1))	/* Convenient abreviation */
+static inline void fast_add_entropy_words(struct random_bucket *r,
+					 __u32 x, __u32 y)
+{
+	static __u32 const twist_table[8] = {
+		         0, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
+		0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
+	unsigned i, j;
+
+	i = MASK(r->add_ptr - 2);	/* i is always even */
+	r->add_ptr = i;
+
+#ifdef ROTATE_PARANOIA
+	j = r->input_rotate + 14;
+	if (i)
+		j -= 7;
+	r->input_rotate = j & 31;
+
+	x = rotate_left(r->input_rotate, x);
+	y = rotate_left(r->input_rotate, y);
+#endif
 
 	/*
-	 * Normally, we add 7 bits of rotation to the pool.  At the
-	 * beginning of the pool, add an extra 7 bits rotation, so
-	 * that successive passes spread the input bits across the
-	 * pool evenly.
+	 * XOR in the various taps.  Even though logically, we compute
+	 * x and then compute y, we read in y then x order because most
+	 * caches work slightly better with increasing read addresses.
+	 * If a tap is even then we can use the fact that i is even to
+	 * avoid a masking operation.  Every polynomial has at least one
+	 * even tap, so j is always used.
+	 * (Is there a nicer way to arrange this code?)
 	 */
-	new_rotate = r->input_rotate + 14;
-	if ((i = r->add_ptr--))
-		new_rotate -= 7;
-	r->input_rotate = new_rotate & 31;
-
-	w = rotate_left(r->input_rotate, input);
-	
-	/* XOR in the various taps */
-	w ^= r->pool[(i+TAP1)&(POOLWORDS-1)];
-	w ^= r->pool[(i+TAP2)&(POOLWORDS-1)];
-	w ^= r->pool[(i+TAP3)&(POOLWORDS-1)];
-	w ^= r->pool[(i+TAP4)&(POOLWORDS-1)];
-	w ^= r->pool[(i+TAP5)&(POOLWORDS-1)];
-	w ^= r->pool[i&(POOLWORDS-1)];
-	/* Use a twisted GFSR for the mixing operation */
-	r->pool[i&(POOLWORDS-1)] = (w >> 1) ^ twist_table[w & 1];
+#if TAP1 & 1
+	y ^= r->pool[MASK(i+TAP1)];	x ^= r->pool[MASK(i+TAP1+1)];
+#else
+	j = MASK(i+TAP1);	y ^= r->pool[j];	x ^= r->pool[j+1];
+#endif
+#if TAP2 & 1
+	y ^= r->pool[MASK(i+TAP2)];	x ^= r->pool[MASK(i+TAP2+1)];
+#else
+	j = MASK(i+TAP2);	y ^= r->pool[j];	x ^= r->pool[j+1];
+#endif
+#if TAP3 & 1
+	y ^= r->pool[MASK(i+TAP3)];	x ^= r->pool[MASK(i+TAP3+1)];
+#else
+	j = MASK(i+TAP3);	y ^= r->pool[j];	x ^= r->pool[j+1];
+#endif
+#if TAP4 & 1
+	y ^= r->pool[MASK(i+TAP4)];	x ^= r->pool[MASK(i+TAP4+1)];
+#else
+	j = MASK(i+TAP4);	y ^= r->pool[j];	x ^= r->pool[j+1];
+#endif
+#if TAP5 == 1
+	/* We need to pretend to write pool[i+1] before computing y */
+	y ^= r->pool[i];
+	x ^= r->pool[i+1];
+	x ^= r->pool[MASK(i+TAP5+1)];
+	y ^= r->pool[i+1] = x = (x >> 3) ^ twist_table[x & 7];
+	r->pool[i] = (y >> 3) ^ twist_table[y & 7];
+#else
+# if TAP5 & 1
+	y ^= r->pool[MASK(i+TAP5)];	x ^= r->pool[MASK(i+TAP5+1)];
+# else
+	j = MASK(i+TAP5);	y ^= r->pool[j];	x ^= r->pool[j+1];
+# endif
+	y ^= r->pool[i];
+	x ^= r->pool[i+1];
+	r->pool[i] = (y >> 3) ^ twist_table[y & 7];
+	r->pool[i+1] = (x >> 3) ^ twist_table[x & 7];
+#endif
 }
 
 /*
  * For places where we don't need the inlined version
  */
-static void add_entropy_word(struct random_bucket *r,
-				    const __u32 input)
+static void add_entropy_words(struct random_bucket *r, __u32 x, __u32 y)
 {
-	fast_add_entropy_word(r, input);
+	fast_add_entropy_words(r, x, y);
 }
 
 /*
@@ -578,19 +690,18 @@
 static void add_timer_randomness(struct random_bucket *r,
 				 struct timer_rand_state *state, unsigned num)
 {
-	int	delta, delta2, delta3;
 	__u32		time;
+	__s32		delta, delta2, delta3;
 
 #ifdef RANDOM_BENCHMARK
 	begin_benchmark(&timer_benchmark);
 #endif
 #if defined (__i386__)
 	if (boot_cpu_data.x86_capability & 16) {
-		unsigned long low, high;
+		__u32 high;
 		__asm__(".byte 0x0f,0x31"
-			:"=a" (low), "=d" (high));
-		time = (__u32) low;
-		num ^= (__u32) high;
+			:"=a" (time), "=d" (high));
+		num ^= high;
 	} else {
 		time = jiffies;
 	}
@@ -598,42 +709,53 @@
 	time = jiffies;
 #endif
 
-	fast_add_entropy_word(r, (__u32) num);
-	fast_add_entropy_word(r, time);
+	fast_add_entropy_words(r, (__u32)num, time);
 	
 	/*
-	 * Calculate number of bits of randomness we probably
-	 * added.  We take into account the first and second order
-	 * deltas in order to make our estimate.
+	 * Calculate number of bits of randomness we probably added.
+	 * We take into account the first, second and third-order deltas
+	 * in order to make our estimate.
 	 */
-	if (!state->dont_count_entropy &&
-	    (r->entropy_count < POOLBITS)) {
+	if ((r->entropy_count < POOLBITS) && !state->dont_count_entropy) {
 		delta = time - state->last_time;
 		state->last_time = time;
-		if (delta < 0) delta = -delta;
 
 		delta2 = delta - state->last_delta;
 		state->last_delta = delta;
-		if (delta2 < 0) delta2 = -delta2;
 
 		delta3 = delta2 - state->last_delta2;
 		state->last_delta2 = delta2;
-		if (delta3 < 0) delta3 = -delta3;
 
-		delta = MIN(MIN(delta, delta2), delta3) >> 1;
-		/* Limit entropy estimate to 12 bits */
+		if (delta < 0)
+			delta = -delta;
+		if (delta2 < 0)
+			delta2 = -delta2;
+		if (delta3 < 0)
+			delta3 = -delta3;
+		if (delta > delta2)
+			delta = delta2;
+		if (delta > delta3)
+			delta = delta3;
+
+		/*
+		 * delta is now minimum absolute delta.
+		 * Round down by 1 bit on general principles,
+		 * and limit entropy entimate to 12 bits.
+		 */
+		delta >>= 1;
 		delta &= (1 << 12) - 1;
 
-		r->entropy_count += int_ln(delta);
+		r->entropy_count += int_ln_12bits(delta);
 
 		/* Prevent overflow */
 		if (r->entropy_count > POOLBITS)
 			r->entropy_count = POOLBITS;
+
+		/* Wake up waiting processes, if we have enough entropy. */
+		if (r->entropy_count >= WAIT_INPUT_BITS)
+			wake_up_interruptible(&random_read_wait);
 	}
 		
-	/* Wake up waiting processes, if we have enough entropy. */
-	if (r->entropy_count >= WAIT_INPUT_BITS)
-		wake_up_interruptible(&random_read_wait);
 #ifdef RANDOM_BENCHMARK
 	end_benchmark(&timer_benchmark);
 #endif
@@ -672,52 +794,84 @@
 			     0x200+major);
 }
 
+/*
+ * This chunk of code defines a function
+ * void HASH_TRANSFORM(__u32 digest[HASH_BUFFER_SIZE + HASH_EXTRA_SIZE],
+ * 		__u32 const data[16])
+ * 
+ * The function hashes the input data to produce a digest in the first
+ * HASH_BUFFER_SIZE words of the digest[] array, and uses HASH_EXTRA_SIZE
+ * more words for internal purposes.  (This buffer is exported so the
+ * caller can wipe it once rather than this code doing it each call,
+ * and tacking it onto the end of the digest[] array is the quick and
+ * dirty way of doing it.)
+ *
+ * It so happens that MD5 and SHA share most of the initial vector
+ * used to initialize the digest[] array before the first call:
+ * 1) 0x67452301
+ * 2) 0xefcdab89
+ * 3) 0x98badcfe
+ * 4) 0x10325476
+ * 5) 0xc3d2e1f0 (SHA only)
+ *
+ * For /dev/random purposes, the length of the data being hashed is
+ * fixed in length (at POOLWORDS words), so appending a bit count in
+ * the usual way is not cryptographically necessary.
+ */
 #define USE_SHA
 
 #ifdef USE_SHA
 
-#define SMALL_VERSION		/* Optimize for space over time */
-
 #define HASH_BUFFER_SIZE 5
+#define HASH_EXTRA_SIZE 80
 #define HASH_TRANSFORM SHATransform
 
+/* Various size/speed tradeoffs are available.  Choose 0..3. */
+#define SHA_CODE_SIZE 0
+
 /*
- * SHA transform algorithm, taken from code written by Peter Gutman,
- * and apparently in the public domain.
+ * SHA transform algorithm, taken from code written by Peter Gutmann,
+ * and placed in the public domain.
  */
 
 /* The SHA f()-functions.  */
 
-#define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
-#define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */
-#define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
-#define f4(x,y,z)   ( x ^ y ^ z )                       /* Rounds 60-79 */
+#define f1(x,y,z)   ( z ^ (x & (y^z)) )		/* Rounds  0-19: x ? y : z */
+#define f2(x,y,z)   (x ^ y ^ z)			/* Rounds 20-39: XOR */
+#define f3(x,y,z)   ( (x & y) + (z & (x ^ y)) )	/* Rounds 40-59: majority */
+#define f4(x,y,z)   (x ^ y ^ z)			/* Rounds 60-79: XOR */
 
 /* The SHA Mysterious Constants */
 
-#define K1  0x5A827999L                                 /* Rounds  0-19 */
-#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
-#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
-#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
+#define K1  0x5A827999L			/* Rounds  0-19: sqrt(2) * 2^30 */
+#define K2  0x6ED9EBA1L			/* Rounds 20-39: sqrt(3) * 2^30 */
+#define K3  0x8F1BBCDCL			/* Rounds 40-59: sqrt(5) * 2^30 */
+#define K4  0xCA62C1D6L			/* Rounds 60-79: sqrt(10) * 2^30 */
 
 #define ROTL(n,X)  ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
 
-#define expand(W,i) ( W[ i & 15 ] = \
-		     ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
-			        W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
-
 #define subRound(a, b, c, d, e, f, k, data) \
     ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
 
 
-static void SHATransform(__u32 *digest, __u32 *data)
-    {
+static void SHATransform(__u32 digest[85], __u32 const data[16])
+{
     __u32 A, B, C, D, E;     /* Local vars */
-    __u32 eData[ 16 ];       /* Expanded data */
-#ifdef SMALL_VERSION
-    int	i;
     __u32 TEMP;
-#endif
+    int	i;
+#define W (digest + HASH_BUFFER_SIZE)	/* Expanded data array */
+
+    /*
+     * Do the preliminary expansion of 16 to 80 words.  Doing it
+     * out-of-line line this is faster than doing it in-line on
+     * register-starved machines like the x86, and not really any
+     * slower on real processors.
+     */
+    memcpy(W, data, 16*sizeof(__u32));
+    for (i = 0; i < 64; i++) {
+	    TEMP = W[i] ^ W[i+2] ^ W[i+8] ^ W[i+13];
+	    W[i+16] = ROTL(1, TEMP);
+    }
 
     /* Set up first buffer and local data buffer */
     A = digest[ 0 ];
@@ -725,112 +879,161 @@
     C = digest[ 2 ];
     D = digest[ 3 ];
     E = digest[ 4 ];
-    memcpy( eData, data, 16*sizeof(__u32));
 
-#ifdef SMALL_VERSION
+    /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
+#if SHA_CODE_SIZE == 0
     /*
-     * Approximately 50% of the speed of the optimized version, but
+     * Approximately 50% of the speed of the largest version, but
      * takes up 1/16 the space.  Saves about 6k on an i386 kernel.
      */
-    for (i=0; i < 80; i++) {
+    for (i = 0; i < 80; i++) {
+	if (i < 40) {
 	    if (i < 20)
-		    TEMP = f1(B, C, D) + K1;
-	    else if (i < 40)
-		    TEMP = f2(B, C, D) + K2;
-	    else if (i < 60)
-		    TEMP = f3(B, C, D) + K3;
+		TEMP = f1(B, C, D) + K1;
+	    else
+		TEMP = f2(B, C, D) + K2;
+	} else {
+	    if (i < 60)
+		TEMP = f3(B, C, D) + K3;
 	    else
-		    TEMP = f4(B, C, D) + K4;
-	    TEMP += ROTL (5, A) + E +
-		    ((i > 15) ? expand(eData, i) : eData[i]);
-	    E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+		TEMP = f4(B, C, D) + K4;
+	}
+	TEMP += ROTL(5, A) + E + W[i];
+	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+    }
+#elif SHA_CODE_SIZE == 1
+    for (i = 0; i < 20; i++) {
+	TEMP = f1(B, C, D) + K1 + ROTL(5, A) + E + W[i];
+	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+    }
+    for (; i < 40; i++) {
+	TEMP = f2(B, C, D) + K2 + ROTL(5, A) + E + W[i];
+	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
     }
+    for (; i < 60; i++) {
+	TEMP = f3(B, C, D) + K3 + ROTL(5, A) + E + W[i];
+	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+    }
+    for (; i < 80; i++) {
+	TEMP = f4(B, C, D) + K4 + ROTL(5, A) + E + W[i];
+	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+    }
+#elif SHA_CODE_SIZE == 2
+    for (i = 0; i < 20; i += 5) {
+	subRound( A, B, C, D, E, f1, K1, W[ i   ] );
+	subRound( E, A, B, C, D, f1, K1, W[ i+1 ] );
+	subRound( D, E, A, B, C, f1, K1, W[ i+2 ] );
+	subRound( C, D, E, A, B, f1, K1, W[ i+3 ] );
+	subRound( B, C, D, E, A, f1, K1, W[ i+4 ] );
+    }
+    for (; i < 40; i += 5) {
+	subRound( A, B, C, D, E, f2, K2, W[ i   ] );
+	subRound( E, A, B, C, D, f2, K2, W[ i+1 ] );
+	subRound( D, E, A, B, C, f2, K2, W[ i+2 ] );
+	subRound( C, D, E, A, B, f2, K2, W[ i+3 ] );
+	subRound( B, C, D, E, A, f2, K2, W[ i+4 ] );
+    }
+    for (; i < 60; i += 5) {
+	subRound( A, B, C, D, E, f3, K3, W[ i   ] );
+	subRound( E, A, B, C, D, f3, K3, W[ i+1 ] );
+	subRound( D, E, A, B, C, f3, K3, W[ i+2 ] );
+	subRound( C, D, E, A, B, f3, K3, W[ i+3 ] );
+	subRound( B, C, D, E, A, f3, K3, W[ i+4 ] );
+    }
+    for (; i < 80; i += 5) {
+	subRound( A, B, C, D, E, f4, K4, W[ i   ] );
+	subRound( E, A, B, C, D, f4, K4, W[ i+1 ] );
+	subRound( D, E, A, B, C, f4, K4, W[ i+2 ] );
+	subRound( C, D, E, A, B, f4, K4, W[ i+3 ] );
+	subRound( B, C, D, E, A, f4, K4, W[ i+4 ] );
+    }
+#elif SHA_CODE_SIZE == 3 /* Really large version */
+    subRound( A, B, C, D, E, f1, K1, W[  0 ] );
+    subRound( E, A, B, C, D, f1, K1, W[  1 ] );
+    subRound( D, E, A, B, C, f1, K1, W[  2 ] );
+    subRound( C, D, E, A, B, f1, K1, W[  3 ] );
+    subRound( B, C, D, E, A, f1, K1, W[  4 ] );
+    subRound( A, B, C, D, E, f1, K1, W[  5 ] );
+    subRound( E, A, B, C, D, f1, K1, W[  6 ] );
+    subRound( D, E, A, B, C, f1, K1, W[  7 ] );
+    subRound( C, D, E, A, B, f1, K1, W[  8 ] );
+    subRound( B, C, D, E, A, f1, K1, W[  9 ] );
+    subRound( A, B, C, D, E, f1, K1, W[ 10 ] );
+    subRound( E, A, B, C, D, f1, K1, W[ 11 ] );
+    subRound( D, E, A, B, C, f1, K1, W[ 12 ] );
+    subRound( C, D, E, A, B, f1, K1, W[ 13 ] );
+    subRound( B, C, D, E, A, f1, K1, W[ 14 ] );
+    subRound( A, B, C, D, E, f1, K1, W[ 15 ] );
+    subRound( E, A, B, C, D, f1, K1, W[ 16 ] );
+    subRound( D, E, A, B, C, f1, K1, W[ 17 ] );
+    subRound( C, D, E, A, B, f1, K1, W[ 18 ] );
+    subRound( B, C, D, E, A, f1, K1, W[ 19 ] );
+
+    subRound( A, B, C, D, E, f2, K2, W[ 20 ] );
+    subRound( E, A, B, C, D, f2, K2, W[ 21 ] );
+    subRound( D, E, A, B, C, f2, K2, W[ 22 ] );
+    subRound( C, D, E, A, B, f2, K2, W[ 23 ] );
+    subRound( B, C, D, E, A, f2, K2, W[ 24 ] );
+    subRound( A, B, C, D, E, f2, K2, W[ 25 ] );
+    subRound( E, A, B, C, D, f2, K2, W[ 26 ] );
+    subRound( D, E, A, B, C, f2, K2, W[ 27 ] );
+    subRound( C, D, E, A, B, f2, K2, W[ 28 ] );
+    subRound( B, C, D, E, A, f2, K2, W[ 29 ] );
+    subRound( A, B, C, D, E, f2, K2, W[ 30 ] );
+    subRound( E, A, B, C, D, f2, K2, W[ 31 ] );
+    subRound( D, E, A, B, C, f2, K2, W[ 32 ] );
+    subRound( C, D, E, A, B, f2, K2, W[ 33 ] );
+    subRound( B, C, D, E, A, f2, K2, W[ 34 ] );
+    subRound( A, B, C, D, E, f2, K2, W[ 35 ] );
+    subRound( E, A, B, C, D, f2, K2, W[ 36 ] );
+    subRound( D, E, A, B, C, f2, K2, W[ 37 ] );
+    subRound( C, D, E, A, B, f2, K2, W[ 38 ] );
+    subRound( B, C, D, E, A, f2, K2, W[ 39 ] );
+    
+    subRound( A, B, C, D, E, f3, K3, W[ 40 ] );
+    subRound( E, A, B, C, D, f3, K3, W[ 41 ] );
+    subRound( D, E, A, B, C, f3, K3, W[ 42 ] );
+    subRound( C, D, E, A, B, f3, K3, W[ 43 ] );
+    subRound( B, C, D, E, A, f3, K3, W[ 44 ] );
+    subRound( A, B, C, D, E, f3, K3, W[ 45 ] );
+    subRound( E, A, B, C, D, f3, K3, W[ 46 ] );
+    subRound( D, E, A, B, C, f3, K3, W[ 47 ] );
+    subRound( C, D, E, A, B, f3, K3, W[ 48 ] );
+    subRound( B, C, D, E, A, f3, K3, W[ 49 ] );
+    subRound( A, B, C, D, E, f3, K3, W[ 50 ] );
+    subRound( E, A, B, C, D, f3, K3, W[ 51 ] );
+    subRound( D, E, A, B, C, f3, K3, W[ 52 ] );
+    subRound( C, D, E, A, B, f3, K3, W[ 53 ] );
+    subRound( B, C, D, E, A, f3, K3, W[ 54 ] );
+    subRound( A, B, C, D, E, f3, K3, W[ 55 ] );
+    subRound( E, A, B, C, D, f3, K3, W[ 56 ] );
+    subRound( D, E, A, B, C, f3, K3, W[ 57 ] );
+    subRound( C, D, E, A, B, f3, K3, W[ 58 ] );
+    subRound( B, C, D, E, A, f3, K3, W[ 59 ] );
+
+    subRound( A, B, C, D, E, f4, K4, W[ 60 ] );
+    subRound( E, A, B, C, D, f4, K4, W[ 61 ] );
+    subRound( D, E, A, B, C, f4, K4, W[ 62 ] );
+    subRound( C, D, E, A, B, f4, K4, W[ 63 ] );
+    subRound( B, C, D, E, A, f4, K4, W[ 64 ] );
+    subRound( A, B, C, D, E, f4, K4, W[ 65 ] );
+    subRound( E, A, B, C, D, f4, K4, W[ 66 ] );
+    subRound( D, E, A, B, C, f4, K4, W[ 67 ] );
+    subRound( C, D, E, A, B, f4, K4, W[ 68 ] );
+    subRound( B, C, D, E, A, f4, K4, W[ 69 ] );
+    subRound( A, B, C, D, E, f4, K4, W[ 70 ] );
+    subRound( E, A, B, C, D, f4, K4, W[ 71 ] );
+    subRound( D, E, A, B, C, f4, K4, W[ 72 ] );
+    subRound( C, D, E, A, B, f4, K4, W[ 73 ] );
+    subRound( B, C, D, E, A, f4, K4, W[ 74 ] );
+    subRound( A, B, C, D, E, f4, K4, W[ 75 ] );
+    subRound( E, A, B, C, D, f4, K4, W[ 76 ] );
+    subRound( D, E, A, B, C, f4, K4, W[ 77 ] );
+    subRound( C, D, E, A, B, f4, K4, W[ 78 ] );
+    subRound( B, C, D, E, A, f4, K4, W[ 79 ] );
 #else
-    /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
-    subRound( A, B, C, D, E, f1, K1, eData[  0 ] );
-    subRound( E, A, B, C, D, f1, K1, eData[  1 ] );
-    subRound( D, E, A, B, C, f1, K1, eData[  2 ] );
-    subRound( C, D, E, A, B, f1, K1, eData[  3 ] );
-    subRound( B, C, D, E, A, f1, K1, eData[  4 ] );
-    subRound( A, B, C, D, E, f1, K1, eData[  5 ] );
-    subRound( E, A, B, C, D, f1, K1, eData[  6 ] );
-    subRound( D, E, A, B, C, f1, K1, eData[  7 ] );
-    subRound( C, D, E, A, B, f1, K1, eData[  8 ] );
-    subRound( B, C, D, E, A, f1, K1, eData[  9 ] );
-    subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
-    subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
-    subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
-    subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
-    subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
-    subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
-    subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
-    subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
-    subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
-    subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
-
-    subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
-    subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
-    subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
-    subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
-    subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
-    subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
-    subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
-    subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
-    subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
-    subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
-    subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
-    subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
-    subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
-    subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
-    subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
-    subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
-    subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
-    subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
-    subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
-    subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
-
-    subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
-    subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
-    subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
-    subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
-    subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
-    subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
-    subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
-    subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
-    subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
-    subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
-    subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
-    subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
-    subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
-    subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
-    subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
-    subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
-    subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
-    subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
-    subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
-    subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
-
-    subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
-    subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
-    subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
-    subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
-    subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
-    subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
-    subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
-    subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
-    subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
-    subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
-    subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
-    subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
-    subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
-    subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
-    subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
-    subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
-    subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
-    subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
-    subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
-    subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
-#endif /* SMALL_VERSION */
+#error Illegal SHA_CODE_SIZE
+#endif
 
     /* Build message digest */
     digest[ 0 ] += A;
@@ -838,7 +1041,10 @@
     digest[ 2 ] += C;
     digest[ 3 ] += D;
     digest[ 4 ] += E;
-    }
+
+	/* W is wiped by the caller */
+#undef W
+}
 
 #undef ROTL
 #undef f1
@@ -849,11 +1055,12 @@
 #undef K2
 #undef K3	
 #undef K4	
-#undef expand
 #undef subRound
 	
-#else
+#else /* !USE_SHA - Use MD5 */
+
 #define HASH_BUFFER_SIZE 4
+#define HASH_EXTRA_SIZE 0
 #define HASH_TRANSFORM MD5Transform
 	
 /*
@@ -881,8 +1088,7 @@
  * reflect the addition of 16 longwords of new data.  MD5Update blocks
  * the data and converts bytes into longwords for this routine.
  */
-static void MD5Transform(__u32 buf[4],
-			 __u32 const in[16])
+static void MD5Transform(__u32 buf[HASH_BUFFER_SIZE], __u32 const in[16])
 {
 	__u32 a, b, c, d;
 
@@ -971,10 +1177,10 @@
 #undef F4
 #undef MD5STEP
 
-#endif
+#endif /* !USE_SHA */
 
 
-#if POOLWORDS % 16
+#if POOLWORDS % 16 != 0
 #error extract_entropy() assumes that POOLWORDS is a multiple of 16 words.
 #endif
 /*
@@ -987,8 +1193,8 @@
 			       size_t nbytes, int to_user)
 {
 	ssize_t ret, i;
-	__u32 tmp[HASH_BUFFER_SIZE];
-	char *cp,*dp;
+	__u32 tmp[HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
+	__u32 x;
 
 	add_timer_randomness(r, &extract_timer_state, nbytes);
 	
@@ -1016,31 +1222,33 @@
 #endif
 		for (i = 0; i < POOLWORDS; i += 16)
 			HASH_TRANSFORM(tmp, r->pool+i);
-		/* Modify pool so next hash will produce different results */
-		add_entropy_word(r, tmp[0]);
-		add_entropy_word(r, tmp[1]);
-		add_entropy_word(r, tmp[2]);
-		add_entropy_word(r, tmp[3]);
-#ifdef USE_SHA
-		add_entropy_word(r, tmp[4]);
-#endif
-		/*
-		 * Run the hash transform one more time, since we want
-		 * to add at least minimal obscuring of the inputs to
-		 * add_entropy_word().
-		 */
-		HASH_TRANSFORM(tmp, r->pool);
 
 		/*
-		 * In case the hash function has some recognizable
-		 * output pattern, we fold it in half.
+		 * The following code does two separate things that happen
+		 * to both work two words at a time, so are convenient
+		 * to do together.
+		 *
+		 * First, this feeds the output back into the pool so
+		 * that the next call will return different results.
+		 * Any perturbation of the pool's state would do, even
+		 * changing one bit, but this mixes the pool nicely.
+		 *
+		 * Second, this folds the output in half to hide the data
+		 * fed back into the pool from the user and further mask
+		 * any patterns in the hash output.  (The exact folding
+		 * pattern is not important; the one used here is quick.)
 		 */
-		cp = (char *) tmp;
-		dp = cp + (HASH_BUFFER_SIZE*sizeof(__u32)) - 1;
-		for (i=0; i <  HASH_BUFFER_SIZE*sizeof(__u32)/2; i++) {
-			*cp ^= *dp;
-			cp++;  dp--;
+		for (i = 0; i <  HASH_BUFFER_SIZE/2; i++) {
+			x = tmp[i + (HASH_BUFFER_SIZE+1)/2];
+			add_entropy_words(r, tmp[i], x);
+			tmp[i] ^= x;
 		}
+#if HASH_BUFFER_SIZE & 1	/* There's a middle word to deal with */
+		x = tmp[HASH_BUFFER_SIZE/2];
+		add_entropy_words(r, x, (__u32)buf);
+		x ^= (x >> 16);		/* Fold it in half */
+		((__u16 *)tmp)[HASH_BUFFER_SIZE-1] = (__u16)x;
+#endif
 		
 		/* Copy data to destination buffer */
 		i = MIN(nbytes, HASH_BUFFER_SIZE*sizeof(__u32)/2);
@@ -1059,7 +1267,7 @@
 			schedule();
 	}
 
-	/* Wipe data from memory */
+	/* Wipe data just returned from memory */
 	memset(tmp, 0, sizeof(tmp));
 	
 	return ret;
@@ -1105,8 +1313,7 @@
 		}
 		n = extract_entropy(&random_state, buf, n, 1);
 		if (n < 0) {
-			if (count == 0)
-				retval = n;
+			retval = n;
 			break;
 		}
 		count += n;
@@ -1154,33 +1361,36 @@
 random_write(struct file * file, const char * buffer,
 	     size_t count, loff_t *ppos)
 {
-	ssize_t		i, bytes, ret = 0;
+	int		ret = 0;
+	size_t		bytes;
+	unsigned	i;
 	__u32 		buf[16];
 	const char 	*p = buffer;
-	ssize_t		c = count;
+	size_t		c = count;
 
 	while (c > 0) {
 		bytes = MIN(c, sizeof(buf));
 
 		bytes -= copy_from_user(&buf, p, bytes);
 		if (!bytes) {
-			if (!ret)
-				ret = -EFAULT;
+			ret = -EFAULT;
 			break;
 		}
 		c -= bytes;
 		p += bytes;
-		ret += bytes;
 		
-		i = (bytes+sizeof(__u32)-1) / sizeof(__u32);
-		while (i--)
-			add_entropy_word(&random_state, buf[i]);
+		i = (unsigned)((bytes-1) / (2 * sizeof(__u32)));
+		do {
+			add_entropy_words(&random_state, buf[2*i], buf[2*i+1]);
+		} while (i--);
 	}
-	if (ret > 0) {
+	if (p == buffer) {
+		return (ssize_t)ret;
+	} else {
 		file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
 		mark_inode_dirty(file->f_dentry->d_inode);
+		return (ssize_t)(p - buffer);
 	}
-	return ret;
 }
 
 static int
@@ -1344,19 +1554,17 @@
 #define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
 #define H(x, y, z) ((x) ^ (y) ^ (z))
 
-#define ROTL(n,X)  ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
-
-/* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s) \
-  {(a) += F ((b), (c), (d)) + (x); \
-   (a) = ROTL ((s), (a));}
-#define GG(a, b, c, d, x, s) \
-  {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \
-   (a) = ROTL ((s), (a));}
-#define HH(a, b, c, d, x, s) \
-  {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \
-   (a) = ROTL ((s), (a));}
+/*
+ * The generic round function.  The application is so specific that
+ * we don't bother protecting all the arguments with parens, as is generally
+ * good macro practice, in favor of extra legibility.
+ * Rotation is separate from addition to prevent recomputation
+ */
+#define ROUND(f, a, b, c, d, x, s)	\
+	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
+#define K1 0
+#define K2 013240474631UL
+#define K3 015666365641UL
 
 /*
  * Basic cut-down MD4 transform.  Returns only 32 bits of result.
@@ -1366,39 +1574,100 @@
 	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
 
 	/* Round 1 */
-	FF (a, b, c, d, in[ 0],  3);
-	FF (d, a, b, c, in[ 1],  7);
-	FF (c, d, a, b, in[ 2], 11);
-	FF (b, c, d, a, in[ 3], 19);
-	FF (a, b, c, d, in[ 4],  3);
-	FF (d, a, b, c, in[ 5],  7);
-	FF (c, d, a, b, in[ 6], 11);
-	FF (b, c, d, a, in[ 7], 19);
+	ROUND(F, a, b, c, d, in[0] + K1,  3);
+	ROUND(F, d, a, b, c, in[1] + K1,  7);
+	ROUND(F, c, d, a, b, in[2] + K1, 11);
+	ROUND(F, b, c, d, a, in[3] + K1, 19);
+	ROUND(F, a, b, c, d, in[4] + K1,  3);
+	ROUND(F, d, a, b, c, in[5] + K1,  7);
+	ROUND(F, c, d, a, b, in[6] + K1, 11);
+	ROUND(F, b, c, d, a, in[7] + K1, 19);
 
 	/* Round 2 */
-	GG (a, b, c, d, in[ 0],  3);
-	GG (d, a, b, c, in[ 4],  5);
-	GG (c, d, a, b, in[ 1],  9);
-	GG (b, c, d, a, in[ 5], 13);
-	GG (a, b, c, d, in[ 2],  3);
-	GG (d, a, b, c, in[ 6],  5);
-	GG (c, d, a, b, in[ 3],  9);
-	GG (b, c, d, a, in[ 7], 13);
+	ROUND(G, a, b, c, d, in[1] + K2,  3);
+	ROUND(G, d, a, b, c, in[3] + K2,  5);
+	ROUND(G, c, d, a, b, in[5] + K2,  9);
+	ROUND(G, b, c, d, a, in[7] + K2, 13);
+	ROUND(G, a, b, c, d, in[0] + K2,  3);
+	ROUND(G, d, a, b, c, in[2] + K2,  5);
+	ROUND(G, c, d, a, b, in[4] + K2,  9);
+	ROUND(G, b, c, d, a, in[6] + K2, 13);
 
 	/* Round 3 */
-	HH (a, b, c, d, in[ 0],  3);
-	HH (d, a, b, c, in[ 4],  9);
-	HH (c, d, a, b, in[ 2], 11);
-	HH (b, c, d, a, in[ 6], 15);
-	HH (a, b, c, d, in[ 1],  3);
-	HH (d, a, b, c, in[ 5],  9);
-	HH (c, d, a, b, in[ 3], 11);
-	HH (b, c, d, a, in[ 7], 15);
+	ROUND(H, a, b, c, d, in[3] + K3,  3);
+	ROUND(H, d, a, b, c, in[7] + K3,  9);
+	ROUND(H, c, d, a, b, in[2] + K3, 11);
+	ROUND(H, b, c, d, a, in[6] + K3, 15);
+	ROUND(H, a, b, c, d, in[1] + K3,  3);
+	ROUND(H, d, a, b, c, in[5] + K3,  9);
+	ROUND(H, c, d, a, b, in[0] + K3, 11);
+	ROUND(H, b, c, d, a, in[4] + K3, 15);
 
 	return buf[1] + b;	/* "most hashed" word */
 	/* Alternative: return sum of all words? */
 }
 
+#if 0	/* May be needed for IPv6 */
+
+static __u32 twothirdsMD4Transform (__u32 const buf[4], __u32 const in[12])
+{
+	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+	/* Round 1 */
+	ROUND(F, a, b, c, d, in[ 0] + K1,  3);
+	ROUND(F, d, a, b, c, in[ 1] + K1,  7);
+	ROUND(F, c, d, a, b, in[ 2] + K1, 11);
+	ROUND(F, b, c, d, a, in[ 3] + K1, 19);
+	ROUND(F, a, b, c, d, in[ 4] + K1,  3);
+	ROUND(F, d, a, b, c, in[ 5] + K1,  7);
+	ROUND(F, c, d, a, b, in[ 6] + K1, 11);
+	ROUND(F, b, c, d, a, in[ 7] + K1, 19);
+	ROUND(F, a, b, c, d, in[ 8] + K1,  3);
+	ROUND(F, d, a, b, c, in[ 9] + K1,  7);
+	ROUND(F, c, d, a, b, in[10] + K1, 11);
+	ROUND(F, b, c, d, a, in[11] + K1, 19);
+
+	/* Round 2 */
+	ROUND(G, a, b, c, d, in[ 1] + K2,  3);
+	ROUND(G, d, a, b, c, in[ 3] + K2,  5);
+	ROUND(G, c, d, a, b, in[ 5] + K2,  9);
+	ROUND(G, b, c, d, a, in[ 7] + K2, 13);
+	ROUND(G, a, b, c, d, in[ 9] + K2,  3);
+	ROUND(G, d, a, b, c, in[11] + K2,  5);
+	ROUND(G, c, d, a, b, in[ 0] + K2,  9);
+	ROUND(G, b, c, d, a, in[ 2] + K2, 13);
+	ROUND(G, a, b, c, d, in[ 4] + K2,  3);
+	ROUND(G, d, a, b, c, in[ 6] + K2,  5);
+	ROUND(G, c, d, a, b, in[ 8] + K2,  9);
+	ROUND(G, b, c, d, a, in[10] + K2, 13);
+
+	/* Round 3 */
+	ROUND(H, a, b, c, d, in[ 3] + K3,  3);
+	ROUND(H, d, a, b, c, in[ 7] + K3,  9);
+	ROUND(H, c, d, a, b, in[11] + K3, 11);
+	ROUND(H, b, c, d, a, in[ 2] + K3, 15);
+	ROUND(H, a, b, c, d, in[ 6] + K3,  3);
+	ROUND(H, d, a, b, c, in[10] + K3,  9);
+	ROUND(H, c, d, a, b, in[ 1] + K3, 11);
+	ROUND(H, b, c, d, a, in[ 5] + K3, 15);
+	ROUND(H, a, b, c, d, in[ 9] + K3,  3);
+	ROUND(H, d, a, b, c, in[ 0] + K3,  9);
+	ROUND(H, c, d, a, b, in[ 4] + K3, 11);
+	ROUND(H, b, c, d, a, in[ 8] + K3, 15);
+
+	return buf[1] + b;	/* "most hashed" word */
+	/* Alternative: return sum of all words? */
+}
+#endif
+
+#undef ROUND
+#undef F
+#undef G
+#undef H
+#undef K1
+#undef K2
+#undef K3
+
 /* This should not be decreased so low that ISNs wrap too fast. */
 #define REKEY_INTERVAL	300
 #define HASH_BITS 24
@@ -1417,8 +1686,7 @@
 	 */
 	do_gettimeofday(&tv);	/* We need the usecs below... */
 
-	if (!rekey_time ||
-	    (tv.tv_sec - rekey_time) > REKEY_INTERVAL) {
+	if (!rekey_time || (tv.tv_sec - rekey_time) > REKEY_INTERVAL) {
 		rekey_time = tv.tv_sec;
 		/* First three words are overwritten below. */
 		get_random_bytes(&secret+3, sizeof(secret)-12);
@@ -1439,7 +1707,7 @@
 	secret[2]=(sport << 16) + dport;
 
 	seq = (halfMD4Transform(secret+8, secret) &
-	       ((1<<HASH_BITS)-1)) + (count << HASH_BITS);
+	       ((1<<HASH_BITS)-1)) + count;
 
 	/*
 	 *	As close as possible to RFC 793, which
@@ -1463,53 +1731,97 @@
  * Dan Bernstein and Eric Schenk.
  *
  * For linux I implement the 1 minute counter by looking at the jiffies clock.
- * The count is passed in as a parameter;
- *
+ * The count is passed in as a parameter, so this code doesn't much care.
  */
-__u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr,
-		 __u16 sport, __u16 dport, __u32 sseq, __u32 count)
+
+#define COOKIEBITS 24	/* Upper bits store count */
+#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
+
+static int	syncookie_init = 0;
+static __u32	syncookie_secret[2][16-3+HASH_BUFFER_SIZE];
+
+__u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
+		__u16 dport, __u32 sseq, __u32 count, __u32 data)
 {
-	static int	is_init = 0;
-	static __u32	secret[2][16];
-	__u32 		tmp[16];
-	__u32		seq;
+	__u32 	tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
+	__u32	seq;
 
 	/*
-	 * Pick two random secret the first time we open a TCP connection.
+	 * Pick two random secrets the first time we need a cookie.
 	 */
-	if (is_init == 0) {
-		get_random_bytes(&secret[0], sizeof(secret[0]));
-		get_random_bytes(&secret[1], sizeof(secret[1]));
-		is_init = 1;
+	if (syncookie_init == 0) {
+		get_random_bytes(syncookie_secret, sizeof(syncookie_secret));
+		syncookie_init = 1;
 	}
 
 	/*
 	 * Compute the secure sequence number.
 	 * The output should be:
-   	 *   MD5(sec1,saddr,sport,daddr,dport,sec1) + their sequence number
-         *      + (count * 2^24)
-	 *      + (MD5(sec2,saddr,sport,daddr,dport,count,sec2) % 2^24).
-	 * Where count increases every minute by 1.
+   	 *   HASH(sec1,saddr,sport,daddr,dport,sec1) + sseq + (count * 2^24)
+	 *      + (HASH(sec2,saddr,sport,daddr,dport,count,sec2) % 2^24).
+	 * Where sseq is their sequence number and count increases every
+	 * minute by 1.
+	 * As an extra hack, we add a small "data" value that encodes the
+	 * MSS into the second hash value.
 	 */
 
-	memcpy(tmp, secret[0], sizeof(tmp));
-	tmp[8]=saddr;
-	tmp[9]=daddr;
-	tmp[10]=(sport << 16) + dport;
-	HASH_TRANSFORM(tmp, tmp);
-	seq = tmp[1];
-
-	memcpy(tmp, secret[1], sizeof(tmp));
-	tmp[8]=saddr;
-	tmp[9]=daddr;
-	tmp[10]=(sport << 16) + dport;
-	tmp[11]=count;	/* minute counter */
-	HASH_TRANSFORM(tmp, tmp);
+	memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+	tmp[0]=saddr;
+	tmp[1]=daddr;
+	tmp[2]=(sport << 16) + dport;
+	HASH_TRANSFORM(tmp+16, tmp);
+	seq = tmp[17] + sseq + (count << COOKIEBITS);
+
+	memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1]));
+	tmp[0]=saddr;
+	tmp[1]=daddr;
+	tmp[2]=(sport << 16) + dport;
+	tmp[3] = count;	/* minute counter */
+	HASH_TRANSFORM(tmp+16, tmp);
 
-	seq += sseq + (count << 24) + (tmp[1] & 0x00ffffff);
+	/* Add in the second hash and the data */
+	return seq + ((tmp[17] + data) & COOKIEMASK);
+}
+
+/*
+ * This retrieves the small "data" value from the syncookie.
+ * If the syncookie is bad, the data returned will be out of
+ * range.  This must be checked by the caller.
+ *
+ * The count value used to generate the cookie must be within
+ * "maxdiff" if the current (passed-in) "count".  The return value
+ * is (__u32)-1 if this test fails.
+ */
+__u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport,
+		__u16 dport, __u32 sseq, __u32 count, __u32 maxdiff)
+{
+	__u32 	tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
+	__u32	diff;
+
+	if (syncookie_init == 0)
+		return (__u32)-1;	/* Well, duh! */
+
+	/* Strip away the layers from the cookie */
+	memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+	tmp[0]=saddr;
+	tmp[1]=daddr;
+	tmp[2]=(sport << 16) + dport;
+	HASH_TRANSFORM(tmp+16, tmp);
+	cookie -= tmp[17] + sseq;
+	/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
+
+	diff = (count - (cookie >> COOKIEBITS)) & ((__u32)-1 >> COOKIEBITS);
+	if (diff >= maxdiff)
+		return (__u32)-1;
+
+	memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1]));
+	tmp[0] = saddr;
+	tmp[1] = daddr;
+	tmp[2] = (sport << 16) + dport;
+	tmp[3] = count - diff;	/* minute counter */
+	HASH_TRANSFORM(tmp+16, tmp);
 
-	/* Zap lower 3 bits to leave room for the MSS representation */
-	return (seq & 0xfffff8);
+	return (cookie - tmp[17]) & COOKIEMASK;	/* Leaving the data behind */
 }
 #endif
 
@@ -1532,7 +1844,7 @@
 {
 	unsigned long low, high;
 	__asm__(".byte 0x0f,0x31" :"=a" (low), "=d" (high));
-	return (((unsigned long long) high << 31) | low); 
+	return (((unsigned long long) high << 32) | low); 
 }
 
 __initfunc(static void
diff -u --recursive --new-file v2.1.103/linux/drivers/char/rtrack.c linux/drivers/char/rtrack.c
--- v2.1.103/linux/drivers/char/rtrack.c	Tue Nov  4 10:23:25 1997
+++ linux/drivers/char/rtrack.c	Thu May 21 14:24:06 1998
@@ -143,7 +143,7 @@
 	outbits(8, 0xa0, myport);
 /* XXX - get rid of this once setvol is implemented properly - XXX */
 /* these insist on turning the thing on.  not sure I approve... */
-	udelay(1000);
+	mdelay(1);
 	outb(0, myport);
 	outb(0xc8, myport);
 
@@ -156,9 +156,9 @@
 int myport = *(int*)(dev->misc);
 
 	outb(0xf8, myport);
-	udelay(200000);
+	mdelay(200);
 	res = (int)inb(myport);
-	udelay(10000);
+	mdelay(10);
 	outb(0xe8, myport);
 	if(res == 0xfd)
 		return 1;
@@ -189,14 +189,14 @@
 void decvol(int port)
 {
 	outb(0x48, port);
-	udelay(100000);
+	mdelay(100);
 	outb(0xc8, port);
 }
 
 void incvol(int port)
 {
 	outb(0x88, port);
-	udelay(100000);
+	mdelay(100);
 	outb(0xc8, port);
 }
 
diff -u --recursive --new-file v2.1.103/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.1.103/linux/drivers/char/serial.c	Thu May  7 22:51:49 1998
+++ linux/drivers/char/serial.c	Mon May 25 10:32:52 1998
@@ -154,7 +154,7 @@
 #endif
 	
 static char *serial_name = "Serial driver";
-static char *serial_version = "4.25";
+static char *serial_version = "4.26";
 
 static DECLARE_TASK_QUEUE(tq_serial);
 
@@ -830,13 +830,14 @@
 	static unsigned long last_strobe = 0;
 	struct async_struct *info;
 	unsigned int	i;
+	unsigned long flags;
 
 	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
 		for (i=1; i < NR_IRQS; i++) {
 			info = IRQ_ports[i];
 			if (!info)
 				continue;
-			cli();
+			save_flags(flags); cli();
 #ifdef CONFIG_SERIAL_SHARE_IRQ
 			if (info->next_port) {
 				do {
@@ -854,7 +855,7 @@
 			} else
 #endif /* CONFIG_SERIAL_SHARE_IRQ */
 				rs_interrupt_single(i, NULL, NULL);
-			sti();
+			restore_flags(flags);
 		}
 	}
 	last_strobe = jiffies;
@@ -862,13 +863,13 @@
 	timer_active |= 1 << RS_TIMER;
 
 	if (IRQ_ports[0]) {
-		cli();
+		save_flags(flags); cli();
 #ifdef CONFIG_SERIAL_SHARE_IRQ
 		rs_interrupt(0, NULL, NULL);
 #else
 		rs_interrupt_single(0, NULL, NULL);
 #endif
-		sti();
+		restore_flags(flags);
 
 		timer_table[RS_TIMER].expires = jiffies + IRQ_timeout[0] - 2;
 	}
@@ -1501,12 +1502,13 @@
 static void rs_flush_buffer(struct tty_struct *tty)
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
-				
+	unsigned long flags;
+	
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
-	cli();
+	save_flags(flags); cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	sti();
+	restore_flags(flags);
 	wake_up_interruptible(&tty->write_wait);
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	    tty->ldisc.write_wakeup)
@@ -1543,6 +1545,7 @@
 static void rs_throttle(struct tty_struct * tty)
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
 	
@@ -1559,14 +1562,15 @@
 	if (tty->termios->c_cflag & CRTSCTS)
 		info->MCR &= ~UART_MCR_RTS;
 
-	cli();
+	save_flags(flags); cli();
 	serial_out(info, UART_MCR, info->MCR);
-	sti();
+	restore_flags(flags);
 }
 
 static void rs_unthrottle(struct tty_struct * tty)
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
 	
@@ -1585,9 +1589,9 @@
 	}
 	if (tty->termios->c_cflag & CRTSCTS)
 		info->MCR |= UART_MCR_RTS;
-	cli();
+	save_flags(flags); cli();
 	serial_out(info, UART_MCR, info->MCR);
-	sti();
+	restore_flags(flags);
 }
 
 /*
@@ -1656,7 +1660,9 @@
 	new_serial.irq = irq_cannonicalize(new_serial.irq);
 
 	if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) ||
-	    (new_serial.type < PORT_UNKNOWN) || (new_serial.type > PORT_MAX)) {
+	    (new_serial.type < PORT_UNKNOWN) ||
+	    (new_serial.type > PORT_MAX) ||
+	    (new_serial.xmit_fifo_size == 0)) {
 		return -EINVAL;
 	}
 
@@ -1745,10 +1751,11 @@
 {
 	unsigned char status;
 	unsigned int result;
+	unsigned long flags;
 
-	cli();
+	save_flags(flags); cli();
 	status = serial_in(info, UART_LSR);
-	sti();
+	restore_flags(flags);
 	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
 	return put_user(result,value);
 }
@@ -1758,11 +1765,12 @@
 {
 	unsigned char control, status;
 	unsigned int result;
+	unsigned long flags;
 
 	control = info->MCR;
-	cli();
+	save_flags(flags); cli();
 	status = serial_in(info, UART_MSR);
-	sti();
+	restore_flags(flags);
 	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
 		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
 #ifdef TIOCM_OUT1
@@ -1781,6 +1789,7 @@
 {
 	int error;
 	unsigned int arg;
+	unsigned long flags;
 
 	error = get_user(arg, value);
 	if (error)
@@ -1827,9 +1836,9 @@
 	default:
 		return -EINVAL;
 	}
-	cli();
+	save_flags(flags); cli();
 	serial_out(info, UART_MCR, info->MCR);
-	sti();
+	restore_flags(flags);
 	return 0;
 }
 
@@ -1846,7 +1855,9 @@
 	shutdown(info);
 
 	autoconfig(info->state);
-	if ((info->state->flags & ASYNC_AUTO_IRQ) && (info->state->port != 0))
+	if ((info->state->flags & ASYNC_AUTO_IRQ) &&
+	    (info->state->port != 0) &&
+	    (info->state->type != PORT_UNKNOWN))
 		info->state->irq = detect_uart_irq(info->state);
 
 	retval = startup(info);
@@ -2000,7 +2011,8 @@
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
 	struct async_icount cprev, cnow;	/* kernel counter temps */
 	struct serial_icounter_struct *p_cuser;	/* user space */
-
+	unsigned long flags;
+	
 	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
 		return -ENODEV;
 
@@ -2052,18 +2064,18 @@
 		 * Caller should use TIOCGICOUNT to see which one it was
 		 */
 		case TIOCMIWAIT:
-			cli();
+			save_flags(flags); cli();
 			/* note the counters on entry */
 			cprev = info->state->icount;
-			sti();
+			restore_flags(flags);
 			while (1) {
 				interruptible_sleep_on(&info->delta_msr_wait);
 				/* see if a signal did it */
 				if (signal_pending(current))
 					return -ERESTARTSYS;
-				cli();
+				save_flags(flags); cli();
 				cnow = info->state->icount; /* atomic copy */
-				sti();
+				restore_flags(flags);
 				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
 				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
 					return -EIO; /* no change => error */
@@ -2084,9 +2096,9 @@
 		 *     RI where only 0->1 is counted.
 		 */
 		case TIOCGICOUNT:
-			cli();
+			save_flags(flags); cli();
 			cnow = info->state->icount;
-			sti();
+			restore_flags(flags);
 			p_cuser = (struct serial_icounter_struct *) arg;
 			error = put_user(cnow.cts, &p_cuser->cts);
 			if (error) return error;
@@ -2096,6 +2108,26 @@
 			if (error) return error;
 			error = put_user(cnow.dcd, &p_cuser->dcd);
 			if (error) return error;
+			error = put_user(cnow.rx, &p_cuser->rx);
+			if (error) return error;
+			error = put_user(cnow.tx, &p_cuser->tx);
+			if (error) return error;
+			error = put_user(cnow.frame, &p_cuser->frame);
+			if (error) return error;
+			error = put_user(cnow.overrun, &p_cuser->overrun);
+			if (error) return error;
+			error = put_user(cnow.parity, &p_cuser->parity);
+			if (error) return error;
+			error = put_user(cnow.brk, &p_cuser->brk);
+			if (error) return error;
+			error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
+			if (error) return error;			
+			return 0;
+
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
 			return 0;
 
 		default:
@@ -2107,7 +2139,8 @@
 static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
+	unsigned long flags;
+	
 	if (   (tty->termios->c_cflag == old_termios->c_cflag)
 	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
@@ -2119,9 +2152,9 @@
 	if ((old_termios->c_cflag & CBAUD) &&
 	    !(tty->termios->c_cflag & CBAUD)) {
 		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-		cli();
+		save_flags(flags); cli();
 		serial_out(info, UART_MCR, info->MCR);
-		sti();
+		restore_flags(flags);
 	}
 	
 	/* Handle transition away from B0 status */
@@ -2132,9 +2165,9 @@
 		    !test_bit(TTY_THROTTLED, &tty->flags)) {
 			info->MCR |= UART_MCR_RTS;
 		}
-		cli();
+		save_flags(flags); cli();
 		serial_out(info, UART_MCR, info->MCR);
-		sti();
+		restore_flags(flags);
 	}
 	
 	/* Handle turning off CRTSCTS */
@@ -2284,6 +2317,9 @@
 	if (info->state->type == PORT_UNKNOWN)
 		return;
 
+	if (info->xmit_fifo_size == 0)
+		return; /* Just in case.... */
+
 	orig_jiffies = jiffies;
 	/*
 	 * Set the check interval to be 1/5 of the estimated time to
@@ -2355,7 +2391,8 @@
 	struct wait_queue wait = { current, NULL };
 	struct serial_state *state = info->state;
 	int		retval;
-	int		do_clocal = 0;
+	int		do_clocal = 0, extra_count = 0;
+	unsigned long	flags;
 
 	/*
 	 * If the device is in the middle of being closed, then block
@@ -2425,19 +2462,21 @@
 	printk("block_til_ready before block: ttys%d, count = %d\n",
 	       state->line, state->count);
 #endif
-	cli();
-	if (!tty_hung_up_p(filp)) 
+	save_flags(flags); cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
 		state->count--;
-	sti();
+	}
+	restore_flags(flags);
 	info->blocked_open++;
 	while (1) {
-		cli();
+		save_flags(flags); cli();
 		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
 		    (tty->termios->c_cflag & CBAUD))
 			serial_out(info, UART_MCR,
 				   serial_inp(info, UART_MCR) |
 				   (UART_MCR_DTR | UART_MCR_RTS));
-		sti();
+		restore_flags(flags);
 		current->state = TASK_INTERRUPTIBLE;
 		if (tty_hung_up_p(filp) ||
 		    !(info->flags & ASYNC_INITIALIZED)) {
@@ -2468,7 +2507,7 @@
 	}
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&info->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
+	if (extra_count)
 		state->count++;
 	info->blocked_open--;
 #ifdef SERIAL_DEBUG_OPEN
@@ -2619,6 +2658,7 @@
 	struct async_struct *info = state->info, scr_info;
 	char	stat_buf[30], control, status;
 	int	ret;
+	unsigned long flags;
 
 	ret = sprintf(buf, "%d: uart:%s port:%X irq:%d",
 		      state->line, uart_config[state->type].name, 
@@ -2641,10 +2681,10 @@
 		info->quot = 0;
 		info->tty = 0;
 	}
-	cli();
+	save_flags(flags); cli();
 	status = serial_in(info, UART_MSR);
 	control = info ? info->MCR : serial_in(info, UART_MCR);
-	sti();
+	restore_flags(flags); 
 	
 	stat_buf[0] = 0;
 	stat_buf[1] = 0;
@@ -2691,12 +2731,13 @@
 int rs_read_proc(char *page, char **start, off_t off, int count,
 		 int *eof, void *data)
 {
-	int i, len = 0;
+	int i, len = 0, l;
 	off_t	begin = 0;
 
 	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
 	for (i = 0; i < NR_PORTS && len < 4000; i++) {
-		len += line_info(page + len, &rs_table[i]);
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
 		if (len+begin > off+count)
 			goto done;
 		if (len+begin < off) {
@@ -2742,10 +2783,11 @@
 #endif
 #ifdef CONFIG_SERIAL_SHARE_IRQ
 	printk(" SHARE_IRQ");
-#endif
 #define SERIAL_OPT
+#endif
 #ifdef CONFIG_SERIAL_DETECT_IRQ
 	printk(" DETECT_IRQ");
+#define SERIAL_OPT
 #endif
 #ifdef SERIAL_OPT
 	printk(" enabled\n");
@@ -2766,7 +2808,7 @@
 {
 	int irq;
 	unsigned long irqs;
-	unsigned char save_mcr;
+	unsigned char save_mcr, save_ier;
 	struct async_struct scr_info; /* serial_{in,out} because HUB6 */
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
@@ -2790,15 +2832,30 @@
 	/* forget possible initially masked and pending IRQ */
 	probe_irq_off(probe_irq_on());
 	save_mcr = serial_inp(&scr_info, UART_MCR);
-
+	save_ier = serial_inp(&scr_info, UART_IER);
 	serial_outp(&scr_info, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+	
 	irqs = probe_irq_on();
 	serial_outp(&scr_info, UART_MCR, 0);
-	udelay (1);
+	udelay (10);
+	if (state->flags & ASYNC_FOURPORT)  {
+		serial_outp(&scr_info, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS);
+	} else {
+		serial_outp(&scr_info, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+	}
+	serial_outp(&scr_info, UART_IER, 0x0f);	/* enable all intrs */
+	(void)serial_inp(&scr_info, UART_LSR);
+	(void)serial_inp(&scr_info, UART_RX);
+	(void)serial_inp(&scr_info, UART_IIR);
+	(void)serial_inp(&scr_info, UART_MSR);
+	serial_outp(&scr_info, UART_TX, 0xFF);
+	udelay (20);
 	irq = probe_irq_off(irqs);
 
 	serial_outp(&scr_info, UART_MCR, save_mcr);
-
+	serial_outp(&scr_info, UART_IER, save_ier);
 #ifdef CONFIG_SERIAL_MANY_PORTS
 	if (state->flags & ASYNC_FOURPORT)
 		outb_p(save_ICP, ICP);
@@ -2866,11 +2923,9 @@
 	if (!(state->flags & ASYNC_SKIP_TEST)) {
 		scratch = serial_inp(info, UART_MCR);
 		serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
-		scratch2 = serial_inp(info, UART_MSR);
 		serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
 		status1 = serial_inp(info, UART_MSR) & 0xF0;
 		serial_outp(info, UART_MCR, scratch);
-		serial_outp(info, UART_MSR, scratch2);
 		if (status1 != 0x90) {
 			restore_flags(flags);
 			return;
@@ -3083,12 +3138,9 @@
 		state->icount.frame = state->icount.parity = 0;
 		state->icount.overrun = state->icount.brk = 0;
 		state->irq = irq_cannonicalize(state->irq);
-		if (check_region(state->port,8)) {
-			state->type = PORT_UNKNOWN;
+		if (check_region(state->port,8))
 			continue;
-		}
-		if (   (state->type == PORT_UNKNOWN)
-		    && (state->flags & ASYNC_BOOT_AUTOCONF))
+		if (state->flags & ASYNC_BOOT_AUTOCONF)
 			autoconfig(state);
 	}
 	/*
diff -u --recursive --new-file v2.1.103/linux/drivers/char/stallion.c linux/drivers/char/stallion.c
--- v2.1.103/linux/drivers/char/stallion.c	Thu May  7 22:51:49 1998
+++ linux/drivers/char/stallion.c	Wed May 20 18:54:37 1998
@@ -2193,7 +2193,7 @@
 	}
  
 /*
- *	Everything looks OK, so lets go ahead and probe for the hardware.
+ *	Everything looks OK, so let's go ahead and probe for the hardware.
  */
 	brdp->clk = CD1400_CLK;
 	brdp->isr = stl_eiointr;
@@ -2568,7 +2568,7 @@
 #endif
 
 /*
- *	We have all resources from the board, so lets setup the actual
+ *	We have all resources from the board, so let's setup the actual
  *	board structure now.
  */
 	switch (brdtype) {
diff -u --recursive --new-file v2.1.103/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v2.1.103/linux/drivers/char/tty_io.c	Thu Apr 23 20:21:33 1998
+++ linux/drivers/char/tty_io.c	Mon May 25 10:32:52 1998
@@ -1022,6 +1022,10 @@
 		}
 	}
 #endif
+
+	if (tty->driver.close)
+		tty->driver.close(tty, filp);
+
 	/*
 	 * Sanity check: if tty->count is going to zero, there shouldn't be
 	 * any waiters on tty->read_wait or tty->write_wait.  We test the
@@ -1078,9 +1082,6 @@
 	 * both sides, and we've completed the last operation that could 
 	 * block, so it's safe to proceed with closing.
 	 */
-
-	if (tty->driver.close)
-		tty->driver.close(tty, filp);
 
 	if (pty_master) {
 		if (--o_tty->count < 0) {
diff -u --recursive --new-file v2.1.103/linux/drivers/isdn/act2000/act2000_isa.c linux/drivers/isdn/act2000/act2000_isa.c
--- v2.1.103/linux/drivers/isdn/act2000/act2000_isa.c	Wed Apr  1 20:11:49 1998
+++ linux/drivers/isdn/act2000/act2000_isa.c	Thu May 21 14:24:06 1998
@@ -83,9 +83,9 @@
         found = 0;
         if ((reg = inb(portbase + ISA_COR)) != 0xff) {
                 outb(reg | ISA_COR_RESET, portbase + ISA_COR);
-                udelay(10000);
+                mdelay(10);
                 outb(reg, portbase + ISA_COR);
-                udelay(10000);
+                mdelay(10);
 
                 for (i = 0; i < 16; i++) {
                         if (inb(portbase + ISA_ISR) & ISA_ISR_SERIAL)
diff -u --recursive --new-file v2.1.103/linux/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- v2.1.103/linux/drivers/isdn/avmb1/b1pci.c	Wed Apr  1 20:11:49 1998
+++ linux/drivers/isdn/avmb1/b1pci.c	Thu May 21 13:45:01 1998
@@ -87,7 +87,7 @@
 
 	printk(KERN_INFO "b1pci: revision %s\n", rev);
 
-	while (dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev)) {
+	while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) {
 		unsigned int ioaddr = dev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK;
 		unsigned int irq = dev->irq;
 		printk(KERN_INFO
diff -u --recursive --new-file v2.1.103/linux/drivers/isdn/hisax/rawhdlc.c linux/drivers/isdn/hisax/rawhdlc.c
--- v2.1.103/linux/drivers/isdn/hisax/rawhdlc.c	Wed Apr  1 20:11:51 1998
+++ linux/drivers/isdn/hisax/rawhdlc.c	Wed May 20 18:54:37 1998
@@ -135,7 +135,7 @@
 #include "rawhdlc.h"
 
 /* There's actually an identical copy of this table in the PPP code
- * (ppp_crc16_table), but I don't want this code dependant on PPP
+ * (ppp_crc16_table), but I don't want this code dependent on PPP
  */
 
 // static 
diff -u --recursive --new-file v2.1.103/linux/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
--- v2.1.103/linux/drivers/isdn/icn/icn.c	Wed Apr  1 20:11:51 1998
+++ linux/drivers/isdn/icn/icn.c	Thu May 21 14:24:06 1998
@@ -1234,7 +1234,7 @@
 			icn_map_channel(lastmap_card, lastmap_channel);
 		restore_flags(flags);
 		if (len) {
-			udelay(1000);
+			mdelay(1);
 			if (loop++ > 20)
 				break;
 		} else
diff -u --recursive --new-file v2.1.103/linux/drivers/isdn/isdn_x25iface.c linux/drivers/isdn/isdn_x25iface.c
--- v2.1.103/linux/drivers/isdn/isdn_x25iface.c	Wed Apr  1 20:11:51 1998
+++ linux/drivers/isdn/isdn_x25iface.c	Wed May 20 18:54:37 1998
@@ -4,7 +4,7 @@
  * This module supports a network interface wich provides lapb_sematics
  * -- as defined in ../../Documentation/networking/x25-iface.txt -- to
  * the upper layer and assumes that the lower layer provides a reliable
- * data link service by means of the the concap_device_ops callbacks.
+ * data link service by means of the concap_device_ops callbacks.
  *
  * Only protocol specific stuff goes here. Device specific stuff
  * goes to another -- device related -- concap_proto support source file.
diff -u --recursive --new-file v2.1.103/linux/drivers/isdn/isdnloop/isdnloop.c linux/drivers/isdn/isdnloop/isdnloop.c
--- v2.1.103/linux/drivers/isdn/isdnloop/isdnloop.c	Wed Apr  8 19:36:26 1998
+++ linux/drivers/isdn/isdnloop/isdnloop.c	Wed May 20 18:54:41 1998
@@ -909,7 +909,7 @@
 					isdnloop_fake(card->rcard[ch - 1], buf, card->rch[ch - 1] + 1);
 					/* Fall through */
 				case 3:
-					/* si1 does not match, dont alert but start timer */
+					/* si1 does not match, don't alert but start timer */
 					isdnloop_start_ctimer(card, ch - 1);
 					break;
 				case 1:
diff -u --recursive --new-file v2.1.103/linux/drivers/isdn/pcbit/layer2.c linux/drivers/isdn/pcbit/layer2.c
--- v2.1.103/linux/drivers/isdn/pcbit/layer2.c	Wed Apr  1 20:11:52 1998
+++ linux/drivers/isdn/pcbit/layer2.c	Thu May 21 13:45:01 1998
@@ -721,7 +721,7 @@
 
 	if (unacked) {
 
-		if (dev->send_seq > dev->unack_seq)
+		if (dev->send_seq > dev->unack_seq) {
 			if (ack <= dev->unack_seq || ack > dev->send_seq) {
 				printk(KERN_DEBUG
 				     "layer 2 ack unacceptable - dev %d",
@@ -734,6 +734,7 @@
 				       dev->id);
 				pcbit_l2_error(dev);
 			}
+		}
 		/* ack is acceptable */
 
 
diff -u --recursive --new-file v2.1.103/linux/drivers/macintosh/imstt.c linux/drivers/macintosh/imstt.c
--- v2.1.103/linux/drivers/macintosh/imstt.c	Fri May  8 23:14:47 1998
+++ linux/drivers/macintosh/imstt.c	Wed May 20 18:54:50 1998
@@ -234,12 +234,12 @@
 struct ims_crmodevals
 {
 	int pitch;
-	struct tt_single_rmodevals tt[2];  // for each ramdac  seperate tt config
+	struct tt_single_rmodevals tt[2];  // for each RAMDAC separate tt config
 
-	struct tvp_single_rmodevals tvp_clock;  // for each ramdac  seperate clock config
+	struct tvp_single_rmodevals tvp_clock;  // for each RAMDAC separate clock config
 	struct tvp_single_crmodevals tvp[3]; 	   // for each colormode 
 
-	struct ibm_single_rmodevals ibm_clock;  // for each ramdac  seperate clock config
+	struct ibm_single_rmodevals ibm_clock;  // for each RAMDAC separate clock config
 //	struct ibm_single_crmodevals ibm[3];	   // for each color mode 
 };
 
@@ -661,7 +661,7 @@
 }
 
 /*
- * We dont need it ( all is done in ims_init )
+ * We don't need it ( all is done in ims_init )
 static void
 set_imstt_clock_tvp(char* tvprv)
 {
diff -u --recursive --new-file v2.1.103/linux/drivers/macintosh/via-cuda.c linux/drivers/macintosh/via-cuda.c
--- v2.1.103/linux/drivers/macintosh/via-cuda.c	Fri May  8 23:14:47 1998
+++ linux/drivers/macintosh/via-cuda.c	Thu May 21 14:24:06 1998
@@ -168,7 +168,7 @@
     eieio();
 
     /* delay 4ms and then clear any pending interrupt */
-    udelay(4000);
+    mdelay(4);
     x = via[SR]; eieio();
 
     /* sync with the CUDA - assert TACK without TIP */
diff -u --recursive --new-file v2.1.103/linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c
--- v2.1.103/linux/drivers/misc/parport_share.c	Thu May  7 22:51:50 1998
+++ linux/drivers/misc/parport_share.c	Thu May 21 17:05:00 1998
@@ -37,7 +37,6 @@
 #define PARPORT_DEFAULT_TIMESLICE	(HZ/5)
 
 static struct parport *portlist = NULL, *portlist_tail = NULL;
-static int portcount = 0;
 
 void (*parport_probe_hook)(struct parport *port) = NULL;
 
@@ -67,6 +66,7 @@
 				      struct parport_operations *ops)
 {
 	struct parport *tmp;
+	int portnum;
 
 	/* Check for a previously registered port.
 	   NOTE: we will ignore irq and dma if we find a previously
@@ -82,6 +82,22 @@
 		return NULL;
 	}
 
+	/* Search for the lowest free parport number. */
+	for (portnum = 0; ; portnum++) {
+		struct parport *itr = portlist;
+		while (itr) {
+			if (itr->number == portnum)
+				/* No good, already used. */
+				break;
+			else
+				itr = itr->next;
+		}
+
+		if (itr == NULL)
+			/* Got to the end of the list. */
+			break;
+	}
+	
 	/* Init our structure */
  	memset(tmp, 0, sizeof(struct parport));
 	tmp->base = base;
@@ -92,7 +108,7 @@
 	tmp->devices = tmp->cad = NULL;
 	tmp->flags = 0;
 	tmp->ops = ops;
-	tmp->number = portcount;
+	tmp->number = portnum;
 	spin_lock_init (&tmp->lock);
 
 	tmp->name = kmalloc(15, GFP_KERNEL);
@@ -101,7 +117,7 @@
 		kfree(tmp);
 		return NULL;
 	}
-	sprintf(tmp->name, "parport%d", portcount);
+	sprintf(tmp->name, "parport%d", portnum);
 
 	/* Chain the entry to our list. */
 	if (portlist_tail)
@@ -109,8 +125,6 @@
 	portlist_tail = tmp;
 	if (!portlist)
 		portlist = tmp;
-
-	portcount++;
 
 	tmp->probe_info.class = PARPORT_CLASS_LEGACY;  /* assume the worst */
 	tmp->waithead = tmp->waittail = NULL;
diff -u --recursive --new-file v2.1.103/linux/drivers/net/3c503.c linux/drivers/net/3c503.c
--- v2.1.103/linux/drivers/net/3c503.c	Mon Feb 23 18:12:05 1998
+++ linux/drivers/net/3c503.c	Thu May 21 14:24:06 1998
@@ -160,7 +160,7 @@
 
     /* Reset and/or avoid any lurking NE2000 */
     if (inb(ioaddr + 0x408) == 0xff) {
-    	udelay(1000);
+    	mdelay(1);
 	return ENODEV;
     }
 
diff -u --recursive --new-file v2.1.103/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.1.103/linux/drivers/net/3c59x.c	Thu May  7 22:51:50 1998
+++ linux/drivers/net/3c59x.c	Wed May 20 18:54:51 1998
@@ -186,7 +186,7 @@
 versions of the FastEtherLink cards.  The supported product IDs are
   3c590, 3c592, 3c595, 3c597, 3c900, 3c905
 
-The ISA 3c515 is supported with a seperate driver, 3c515.c, included with
+The ISA 3c515 is supported with a separate driver, 3c515.c, included with
 the kernel source or available from
     cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html
 
@@ -204,7 +204,7 @@
 series.  The primary interface is two programmed-I/O FIFOs, with an
 alternate single-contiguous-region bus-master transfer (see next).
 
-The 3c900 "Boomerang" series uses a full-bus-master interface with seperate
+The 3c900 "Boomerang" series uses a full-bus-master interface with separate
 lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
 DEC Tulip and Intel Speedo3.  The first chip version retains a compatible
 programmed-I/O interface that will be removed in the 'B' and subsequent
diff -u --recursive --new-file v2.1.103/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.1.103/linux/drivers/net/Config.in	Thu May 14 19:47:39 1998
+++ linux/drivers/net/Config.in	Wed May 20 18:54:51 1998
@@ -25,10 +25,10 @@
 bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
 if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
   if [ "$CONFIG_PMAC" = "y" ]; then
-    bool 'MACE (Power Mac ethernet) support' CONFIG_MACE
+    bool 'MACE (Power Mac Ethernet) support' CONFIG_MACE
   fi
   if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
-    bool 'MIPS JAZZ onboard SONIC ethernet support' CONFIG_MIPS_JAZZ_SONIC
+    bool 'MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC
   fi
   bool '3COM cards' CONFIG_NET_VENDOR_3COM
   if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
@@ -99,7 +99,7 @@
       tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
     fi
 
-    tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT
+    tristate 'Apricot Xen-II on board Ethernet' CONFIG_APRICOT
     tristate 'CS89x0 support' CONFIG_CS89x0
     tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
     tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP
diff -u --recursive --new-file v2.1.103/linux/drivers/net/cops.c linux/drivers/net/cops.c
--- v2.1.103/linux/drivers/net/cops.c	Tue Mar 10 10:03:32 1998
+++ linux/drivers/net/cops.c	Thu May 21 14:24:06 1998
@@ -417,7 +417,7 @@
         int timeout=0;
 
         while(timeout < 5000 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
-		udelay(1000);   /* Wait 1000 useconds */
+		mdelay(1);   /* Wait 1000 useconds */
 
 	return 0;
 }
diff -u --recursive --new-file v2.1.103/linux/drivers/net/cops_ffdrv.h linux/drivers/net/cops_ffdrv.h
--- v2.1.103/linux/drivers/net/cops_ffdrv.h	Mon Jul  7 08:19:59 1997
+++ linux/drivers/net/cops_ffdrv.h	Wed May 20 18:54:56 1998
@@ -1,7 +1,7 @@
 
 /*
  *	The firmware this driver downloads into the Localtalk card is a
- *	seperate program and is not GPL'd source code, even though the Linux
+ *	separate program and is not GPL'd source code, even though the Linux
  *	side driver and the routine that loads this data into the card are.
  *	
  *	It is taken from the COPS SDK and is under the following license
diff -u --recursive --new-file v2.1.103/linux/drivers/net/cops_ltdrv.h linux/drivers/net/cops_ltdrv.h
--- v2.1.103/linux/drivers/net/cops_ltdrv.h	Mon Jul  7 08:19:59 1997
+++ linux/drivers/net/cops_ltdrv.h	Wed May 20 18:54:57 1998
@@ -1,6 +1,6 @@
 /*
  *	The firmware this driver downloads into the Localtalk card is a
- *	seperate program and is not GPL'd source code, even though the Linux
+ *	separate program and is not GPL'd source code, even though the Linux
  *	side driver and the routine that loads this data into the card are.
  *	
  *	It is taken from the COPS SDK and is under the following license
diff -u --recursive --new-file v2.1.103/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.1.103/linux/drivers/net/de4x5.c	Thu May  7 22:51:50 1998
+++ linux/drivers/net/de4x5.c	Thu May 21 14:24:06 1998
@@ -1036,9 +1036,9 @@
 
 #define PHY_HARD_RESET {\
     outl(GEP_HRST, DE4X5_GEP);           /* Hard RESET the PHY dev. */\
-    udelay(1000);                        /* Assert for 1ms */\
+    mdelay(1);                        /* Assert for 1ms */\
     outl(0x00, DE4X5_GEP);\
-    udelay(2000);                        /* Wait for 2ms */\
+    mdelay(2);                        /* Wait for 2ms */\
 }
 
 
@@ -1430,7 +1430,7 @@
     /* Poll for setup frame completion (adapter interrupts are disabled now) */
     sti();                                       /* Ensure timer interrupts */
     for (j=0, i=0;(i<500) && (j==0);i++) {       /* Upto 500ms delay */
-	udelay(1000);
+	mdelay(1);
 	if ((s32)le32_to_cpu(lp->tx_ring[lp->tx_new].status) >= 0) j=1;
     }
     outl(omr, DE4X5_OMR);                        /* Stop everything! */
@@ -4415,7 +4415,7 @@
     while (count--) {
 	gep_wr(((lp->chipset==DC21140) && (lp->ibn!=5) ? 
 		                                   *p++ : TWIDDLE(w++)), dev);
-	udelay(2000);                       /* 2ms per action */
+	mdelay(2);                       /* 2ms per action */
     }
 
     if (lp->chipset != DC21140) {
diff -u --recursive --new-file v2.1.103/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.1.103/linux/drivers/net/eepro100.c	Thu May  7 22:51:50 1998
+++ linux/drivers/net/eepro100.c	Wed May 20 18:54:58 1998
@@ -1,4 +1,4 @@
-/* drivers/net/eepro100.c: An Intel i82557 ethernet driver for linux. */
+/* drivers/net/eepro100.c: An Intel i82557 Ethernet driver for Linux. */
 /*
    NOTICE: this version tested with kernels 1.3.72 and later only!
 	Written 1996-1997 by Donald Becker.
@@ -143,7 +143,7 @@
 I. Board Compatibility
 
 This device driver is designed for the Intel i82557 "Speedo3" chip, Intel's
-single-chip fast ethernet controller for PCI, as used on the Intel
+single-chip fast Ethernet controller for PCI, as used on the Intel
 EtherExpress Pro 100 adapter.
 
 II. Board-specific settings
@@ -197,7 +197,7 @@
 added asynchronous to the normal transmit queue, so we disable interrupts
 whenever the Tx descriptor ring is manipulated.
 
-A notable aspect of the these special configure commands is that they do
+A notable aspect of these special configure commands is that they do
 work with the normal Tx ring entry scavenge method.  The Tx ring scavenge
 is done at interrupt time using the 'dirty_tx' index, and checking for the
 command-complete bit.  While the setup frames may have the NoOp command on the
diff -u --recursive --new-file v2.1.103/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.1.103/linux/drivers/net/eexpress.c	Mon Feb 23 18:12:05 1998
+++ linux/drivers/net/eexpress.c	Thu May 21 14:24:06 1998
@@ -743,7 +743,7 @@
 		break;
 	}
 	outb(oldval, dev->base_addr+0x300e);
-	udelay(20000);
+	mdelay(20);
 }
 
 /*
@@ -1357,7 +1357,7 @@
 	eexp_hw_rxinit(dev);
 
 	outb(0,ioaddr+EEPROM_Ctrl);
-	udelay(5000);
+	mdelay(5);
 
 	scb_command(dev, 0xf000);
 	outb(0,ioaddr+SIGNAL_CA);
diff -u --recursive --new-file v2.1.103/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v2.1.103/linux/drivers/net/ewrk3.c	Thu May  7 22:51:50 1998
+++ linux/drivers/net/ewrk3.c	Thu May 21 14:24:06 1998
@@ -340,7 +340,7 @@
  */
 #define INIT_EWRK3 {\
     outb(EEPROM_INIT, EWRK3_IOPR);\
-    udelay(1000);\
+    mdelay(1);\
 }
 
 
@@ -1139,7 +1139,7 @@
 
 	/*
 	   ** Clean out the TX and RX queues here (note that one entry
-	   ** may get added to either the TXD or RX queues if the the TX or RX
+	   ** may get added to either the TXD or RX queues if the TX or RX
 	   ** just starts processing a packet before the STOP_EWRK3 command
 	   ** is received. This will be flushed in the ewrk3_open() call).
 	 */
diff -u --recursive --new-file v2.1.103/linux/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c
--- v2.1.103/linux/drivers/net/hamradio/mkiss.c	Thu Feb 12 20:56:08 1998
+++ linux/drivers/net/hamradio/mkiss.c	Wed May 20 18:55:04 1998
@@ -10,7 +10,7 @@
  * 		This module implements the AX.25 protocol for kernel-based
  *		devices like TTYs. It interfaces between a raw TTY, and the
  *		kernel's AX.25 protocol layers, just like slip.c.
- *		AX.25 needs to be seperated from slip.c while slip.c is no
+ *		AX.25 needs to be separated from slip.c while slip.c is no
  *		longer a static kernel device since it is a module.
  *		This method clears the way to implement other kiss protocols
  *		like mkiss smack g8bpq ..... so far only mkiss is implemented.
diff -u --recursive --new-file v2.1.103/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v2.1.103/linux/drivers/net/hp100.c	Thu Apr 23 20:21:33 1998
+++ linux/drivers/net/hp100.c	Thu May 21 14:24:07 1998
@@ -338,7 +338,7 @@
 /* TODO: This function should not really be needed in a good design... */
 static void wait( void )
 {
-  udelay( 1000 );
+  mdelay(1);
 }
 
 /*
@@ -1899,7 +1899,7 @@
 		if ( lp->lan_type == HP100_LAN_100 )
 		  lp->hub_status = hp100_login_to_vg_hub( dev, FALSE );
 		hp100_start_interface( dev );
-		udelay(1000);
+		mdelay(1);
 	      }
         }
       dev->trans_start = jiffies;
diff -u --recursive --new-file v2.1.103/linux/drivers/net/hp100.h linux/drivers/net/hp100.h
--- v2.1.103/linux/drivers/net/hp100.h	Tue Mar 17 22:18:14 1998
+++ linux/drivers/net/hp100.h	Wed May 20 18:55:04 1998
@@ -529,7 +529,7 @@
  */
 
 #define MAX_RX_PDL              30   /* Card limit = 31 */
-#define MAX_RX_FRAG             2    /* Dont need more... */
+#define MAX_RX_FRAG             2    /* Don't need more... */
 #define MAX_TX_PDL              29
 #define MAX_TX_FRAG             2   /* Limit = 31 */
 
diff -u --recursive --new-file v2.1.103/linux/drivers/net/lne390.c linux/drivers/net/lne390.c
--- v2.1.103/linux/drivers/net/lne390.c	Thu May 14 19:47:39 1998
+++ linux/drivers/net/lne390.c	Thu May 21 14:24:07 1998
@@ -56,7 +56,7 @@
 
 static void lne390_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page);
 static void lne390_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset);
-static void lne390_block_output(struct device *dev, int count, const unsigned char *buf, const start_page);
+static void lne390_block_output(struct device *dev, int count, const unsigned char *buf, const int start_page);
 
 #define LNE390_START_PG		0x00    /* First page of TX buffer	*/
 #define LNE390_STOP_PG		0x80    /* Last page +1 of RX ring	*/
@@ -279,7 +279,7 @@
 	outb(0x04, ioaddr + LNE390_RESET_PORT);
 	if (ei_debug > 1) printk("%s: resetting the LNE390...", dev->name);
 
-	udelay(2*1000);
+	mdelay(2);
 
 	ei_status.txing = 0;
 	outb(0x01, ioaddr + LNE390_RESET_PORT);
diff -u --recursive --new-file v2.1.103/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v2.1.103/linux/drivers/net/ne.c	Fri Apr 10 13:03:48 1998
+++ linux/drivers/net/ne.c	Fri May 22 15:19:12 1998
@@ -25,6 +25,9 @@
     Paul Gortmaker	: Support for PCI ne2k clones, similar to lance.c
     Paul Gortmaker	: Allow users with bad cards to avoid full probe.
     Paul Gortmaker	: PCI probe changes, more PCI cards supported.
+    rjohnson@analogic.com : Changed init order so an interrupt will only
+    occur after memory is allocated for dev->priv. Deallocated memory
+    last in cleanup_modue()
 
 */
 
@@ -401,7 +404,7 @@
 	outb_p(0x00, ioaddr + EN0_RCNTLO);
 	outb_p(0x00, ioaddr + EN0_RCNTHI);
 	outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
-	udelay(10000);		/* wait 10ms for interrupt to propagate */
+	mdelay(10);		/* wait 10ms for interrupt to propagate */
 	outb_p(0x00, ioaddr + EN0_IMR); 		/* Mask it again. */
 	dev->irq = autoirq_report(0);
 	if (ei_debug > 2)
@@ -416,6 +419,12 @@
 	return EAGAIN;
     }
 
+    /* Allocate dev->priv and fill in 8390 specific dev fields. */
+    if (ethdev_init(dev)) {
+        printk (" unable to get memory for dev->priv.\n");
+        return -ENOMEM;
+    }
+   
     /* Snarf the interrupt now.  There's no point in waiting since we cannot
        share and the board will usually be enabled. */
     {
@@ -423,19 +432,12 @@
 				 pci_irq_line ? SA_SHIRQ : 0, name, dev);
 	if (irqval) {
 	    printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
+
+            kfree(dev->priv);
 	    return EAGAIN;
 	}
     }
-
     dev->base_addr = ioaddr;
-
-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
-    if (ethdev_init(dev)) {
-	printk (" unable to get memory for dev->priv.\n");
-	free_irq(dev->irq, dev);
-	return -ENOMEM;
-    }
-
     request_region(ioaddr, NE_IO_EXTENT, name);
 
     for(i = 0; i < ETHER_ADDR_LEN; i++) {
@@ -773,11 +775,11 @@
 	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
 		struct device *dev = &dev_ne[this_dev];
 		if (dev->priv != NULL) {
+			free_irq(dev->irq, dev);
+			release_region(dev->base_addr, NE_IO_EXTENT);
 			unregister_netdev(dev);
 			kfree(dev->priv);
 			dev->priv = NULL;
-			free_irq(dev->irq, dev);
-			release_region(dev->base_addr, NE_IO_EXTENT);
 		}
 	}
 }
diff -u --recursive --new-file v2.1.103/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v2.1.103/linux/drivers/net/ni65.c	Mon Feb 23 18:12:05 1998
+++ linux/drivers/net/ni65.c	Thu May 21 14:24:07 1998
@@ -512,7 +512,7 @@
 
 	for(i=0;i<32;i++)
 	{
-		udelay(4000);
+		mdelay(4);
 		if(inw(PORT+L_DATAREG) & (CSR0_IDON | CSR0_MERR) )
 			break; /* init ok ? */
 	}
diff -u --recursive --new-file v2.1.103/linux/drivers/net/sdla.c linux/drivers/net/sdla.c
--- v2.1.103/linux/drivers/net/sdla.c	Wed May 20 19:10:39 1998
+++ linux/drivers/net/sdla.c	Thu May 21 13:45:02 1998
@@ -451,7 +451,7 @@
 			save_flags(pflags);
 			cli();
 			SDLA_WINDOW(dev, window);
-			waiting = ((volatile)(cmd_buf->opp_flag));
+			waiting = ((volatile int)(cmd_buf->opp_flag));
 			restore_flags(pflags);
 		}
 	}
diff -u --recursive --new-file v2.1.103/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v2.1.103/linux/drivers/net/sk_g16.c	Thu Mar 26 15:57:03 1998
+++ linux/drivers/net/sk_g16.c	Thu May 21 14:24:07 1998
@@ -1808,7 +1808,7 @@
 void SK_reset_board(void)
 {
     writeb(0x00, SK_PORT);       /* Reset active */
-    udelay(5000);                /* Delay min 5ms */
+    mdelay(5);                /* Delay min 5ms */
     writeb(SK_RESET, SK_PORT);   /* Set back to normal operation */
 
 } /* End of SK_reset_board() */
diff -u --recursive --new-file v2.1.103/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v2.1.103/linux/drivers/net/slip.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/net/slip.c	Wed May 20 18:55:04 1998
@@ -912,7 +912,7 @@
       shutdown,
 
    Seems, now it is clean. The solution is to consider netdevice and
-   line discipline sides as two independant threads.
+   line discipline sides as two independent threads.
 
    By-product (not desired): sl? does not feel hangups and remains open.
    It is supposed, that user level program (dip, diald, slattach...)
diff -u --recursive --new-file v2.1.103/linux/drivers/net/smc-mca.c linux/drivers/net/smc-mca.c
--- v2.1.103/linux/drivers/net/smc-mca.c	Thu May  7 22:51:50 1998
+++ linux/drivers/net/smc-mca.c	Thu May 21 13:45:02 1998
@@ -54,7 +54,7 @@
                                  int ring_offset);
 static void ultramca_block_output(struct device *dev, int count,
                                   const unsigned char *buf,
-                                  const start_page);
+                                  const int start_page);
 static int ultramca_close_card(struct device *dev);
 
 #define START_PG        0x00    /* First page of TX buffer */
diff -u --recursive --new-file v2.1.103/linux/drivers/net/smc-ultra32.c linux/drivers/net/smc-ultra32.c
--- v2.1.103/linux/drivers/net/smc-ultra32.c	Sat May  2 14:19:53 1998
+++ linux/drivers/net/smc-ultra32.c	Thu May 21 13:45:02 1998
@@ -69,7 +69,8 @@
 static void ultra32_block_input(struct device *dev, int count,
 				struct sk_buff *skb, int ring_offset);
 static void ultra32_block_output(struct device *dev, int count,
-				 const unsigned char *buf, const start_page);
+				 const unsigned char *buf,
+				 const int start_page);
 static int ultra32_close(struct device *dev);
 
 #define ULTRA32_CMDREG	0	/* Offset to ASIC command register. */
diff -u --recursive --new-file v2.1.103/linux/drivers/net/sunqe.c linux/drivers/net/sunqe.c
--- v2.1.103/linux/drivers/net/sunqe.c	Thu Feb 12 20:56:09 1998
+++ linux/drivers/net/sunqe.c	Thu May 21 14:24:07 1998
@@ -263,7 +263,7 @@
 
 	/* Wait a little bit for the link to come up... */
 	if(!(mregs->phyconfig & MREGS_PHYCONFIG_LTESTDIS)) {
-		udelay(5000);
+		mdelay(5);
 		if(!(mregs->phyconfig & MREGS_PHYCONFIG_LSTAT))
 			printk("%s: Warning, link state is down.\n", qep->dev->name);
 	}
diff -u --recursive --new-file v2.1.103/linux/drivers/net/tlan.c linux/drivers/net/tlan.c
--- v2.1.103/linux/drivers/net/tlan.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/net/tlan.c	Thu May 21 14:24:07 1998
@@ -1093,7 +1093,7 @@
 	 *	of the list.  If the frame was the last in the Rx
 	 *	channel (EOC), the function restarts the receive channel
 	 *	by sending an Rx Go command to the adapter.  Then it
-	 *	activates/continues the the activity LED.
+	 *	activates/continues the activity LED.
 	 *
 	 **************************************************************/
 
@@ -1509,7 +1509,7 @@
 	 *		io_base		Base IO port of the device of
 	 *				which to print DIO registers.
 	 *
-	 *	This function prints out all the the internal (DIO)
+	 *	This function prints out all the internal (DIO)
 	 *	registers of a TLAN chip.
 	 *
 	 **************************************************************/
@@ -2061,7 +2061,7 @@
 		TLan_MiiSync( io );
 		TLan_MiiWriteReg( io, phy, MII_GEN_CTL, MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE );
 		TLan_MiiWriteReg( io, phy, MII_GEN_CTL, MII_GC_LOOPBK );
-		udelay(50000);
+		mdelay(50);
 		TLan_MiiWriteReg( io, phy, MII_GEN_CTL, MII_GC_RESET | MII_GC_LOOPBK );
 		TLan_MiiSync( io );
 	}
@@ -2074,7 +2074,7 @@
 	/* TLan_MiiWriteReg( io, phy, MII_GEN_CTL, MII_GC_DUPLEX ); */
 	TLan_MiiWriteReg( io, phy, MII_GEN_CTL, 0 );
 
-	udelay(500000);
+	mdelay(500);
 
 	TLan_MiiReadReg( io, phy, TLAN_TLPHY_CTL, &value );
 	if ( aui ) 
@@ -2197,7 +2197,7 @@
 		TLan_MiiSync( io );
 		TLan_MiiWriteReg( io, phy, MII_GEN_CTL, MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE );
 		TLan_MiiWriteReg( io, phy, MII_GEN_CTL, MII_GC_LOOPBK );
-		udelay(500000);
+		mdelay(500);
 		TLan_MiiWriteReg( io, phy, MII_GEN_CTL, MII_GC_RESET | MII_GC_LOOPBK );
 		TLan_MiiSync( io );
 	}
@@ -2215,7 +2215,7 @@
        	TLan_MiiWriteReg( io, phy, MII_GEN_CTL, 0x1000 );
 	TLan_MiiWriteReg( io, phy, MII_GEN_CTL, 0x1200 );
 
-	udelay(50000);
+	mdelay(50);
 #if 0
 	/* Read Possible Latched Link Status */
 	TLan_MiiReadReg( io, phy, MII_GEN_STS, &value ); 
diff -u --recursive --new-file v2.1.103/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v2.1.103/linux/drivers/net/tulip.c	Wed May 20 19:10:39 1998
+++ linux/drivers/net/tulip.c	Thu May 21 13:45:02 1998
@@ -42,9 +42,9 @@
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
 #ifdef __alpha__
-static const rx_copybreak = 1518;
+static const int rx_copybreak = 1518;
 #else
-static const rx_copybreak = 100;
+static const int rx_copybreak = 100;
 #endif
 
 /* The following example shows how to always use the 10base2 port. */
@@ -578,7 +578,7 @@
 	/* Stop the chip's Tx and Rx processes. */
 	outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6);
 	/* Clear the missed-packet counter. */
-	(volatile)inl(ioaddr + CSR8);
+	(volatile int)inl(ioaddr + CSR8);
 
 	if (chip_id == DC21041) {
 		if (inl(ioaddr + CSR9) & 0x8000) {
@@ -804,7 +804,7 @@
 	/* The last media info list parsed, for multiport boards.  */
 	static struct mediatable *last_mediatable = NULL;
 	static unsigned char *last_ee_data = NULL;
-	static controller_index = 0;
+	static int controller_index = 0;
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 	int ioaddr = dev->base_addr;
 	unsigned char *ee_data = tp->eeprom;
diff -u --recursive --new-file v2.1.103/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v2.1.103/linux/drivers/net/wavelan.c	Thu Feb 12 20:56:09 1998
+++ linux/drivers/net/wavelan.c	Thu May 21 14:24:07 1998
@@ -139,7 +139,7 @@
 {
   hacr_write(ioaddr, hacr);
   /* delay might only be needed sometimes */
-  udelay(1000L);
+  mdelay(1);
 } /* hacr_write_slow */
 
 /*------------------------------------------------------------------*/
@@ -284,7 +284,7 @@
       count = 0;
       while((count++ < 100) &&
 	    (hasr_read(ioaddr) & HASR_PSA_BUSY))
-	udelay(1000);
+	mdelay(1);
     }
 
   wv_16_on(ioaddr, hacr);
@@ -528,7 +528,7 @@
       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE);
 
       /* Wavelan doc says : wait at least 10 ms for EEBUSY = 0 */
-      udelay(10000);
+      mdelay(10);
       fee_wait(ioaddr, 10, 100);
     }
 
@@ -2629,16 +2629,16 @@
  * the transmit.
  *
  * The principle :
- * Each block contain a transmit command, a nop command,
+ * Each block contains a transmit command, a nop command,
  * a transmit block descriptor and a buffer.
- * The CU read the transmit block which point to the tbd,
- * read the tbd and the the content of the buffer.
- * When it has finish with it, it goes to the next command
- * which in our case is the nop. The nop point on itself,
- * so the CU stop here.
+ * The CU reads the transmit block which points to the tbd,
+ * reads the tbd and the content of the buffer.
+ * When it has finished with it, it goes to the next command
+ * which in our case is the nop. The nop points on itself,
+ * so the CU stops here.
  * When we add the next block, we modify the previous nop
  * to make it point on the new tx command.
- * Simple, isn't it ?
+ * Simple, isn't it?
  *
  * (called in wavelan_packet_xmit())
  */
@@ -2772,7 +2772,7 @@
 /*------------------------------------------------------------------*/
 /*
  * This routine is called when we want to send a packet (NET3 callback)
- * In this routine, we check if the the harware is ready to accept
+ * In this routine, we check if the hardware is ready to accept
  * the packet. We also prevent reentrance. Then, we call the function
  * to send the packet...
  */
diff -u --recursive --new-file v2.1.103/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
--- v2.1.103/linux/drivers/net/yellowfin.c	Fri May  8 23:14:48 1998
+++ linux/drivers/net/yellowfin.c	Thu May 21 13:45:02 1998
@@ -37,7 +37,7 @@
 
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1518 effectively disables this feature. */
-static const rx_copybreak = 100;
+static const int rx_copybreak = 100;
 
 /* Keep the ring sizes a power of two for efficiency.
    Making the Tx ring too large decreases the effectiveness of channel
@@ -948,7 +948,7 @@
 	return;
 }
 
-/* This routine is logically part of the interrupt handler, but seperated
+/* This routine is logically part of the interrupt handler, but separated
    for clarity and better register allocation. */
 static int
 yellowfin_rx(struct device *dev)
diff -u --recursive --new-file v2.1.103/linux/drivers/sbus/audio/cs4231.c linux/drivers/sbus/audio/cs4231.c
--- v2.1.103/linux/drivers/sbus/audio/cs4231.c	Thu May 14 19:47:39 1998
+++ linux/drivers/sbus/audio/cs4231.c	Thu May 21 14:24:07 1998
@@ -73,7 +73,7 @@
 static int cs4231_length_to_samplecount(struct audio_prinfo *thisdir, unsigned int length);
 static void cs4231_getsamplecount(struct sparcaudio_driver *drv, unsigned int length, unsigned int value);
 
-#define CHIP_READY udelay(100); cs4231_ready(drv); udelay(1000);
+#define CHIP_READY udelay(100); cs4231_ready(drv); mdelay(1);
 
 /* Enable cs4231 interrupts atomically. */
 static __inline__ void cs4231_enable_interrupts(struct sparcaudio_driver *drv)
diff -u --recursive --new-file v2.1.103/linux/drivers/sbus/char/cgsix.c linux/drivers/sbus/char/cgsix.c
--- v2.1.103/linux/drivers/sbus/char/cgsix.c	Thu Apr 23 20:21:34 1998
+++ linux/drivers/sbus/char/cgsix.c	Wed May 20 18:55:05 1998
@@ -26,7 +26,7 @@
 /*
  * Brooktree is the video dac and is funny to program on the cg6.
  * (it's even funnier on the cg3)
- * The FBC could be the the frame buffer control
+ * The FBC could be the frame buffer control
  * The FHC could is the frame buffer hardware control.
  */
 #define CG6_ROM_OFFSET       0x0
diff -u --recursive --new-file v2.1.103/linux/drivers/sbus/char/envctrl.c linux/drivers/sbus/char/envctrl.c
--- v2.1.103/linux/drivers/sbus/char/envctrl.c	Thu Apr 23 20:21:34 1998
+++ linux/drivers/sbus/char/envctrl.c	Thu May 21 14:24:07 1998
@@ -225,7 +225,7 @@
 	i2c->csr = CONTROL_PIN | CONTROL_ES1;
 	i2c->data = CLK_4_43 | BUS_CLK_90;
 	i2c->csr = CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK;
-	udelay(10000);
+	mdelay(10);
 
 	return scan_bus();
 #else
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c
--- v2.1.103/linux/drivers/scsi/53c7xx.c	Thu May 14 19:47:40 1998
+++ linux/drivers/scsi/53c7xx.c	Wed May 20 18:55:06 1998
@@ -284,7 +284,7 @@
 #ifdef NO_IO_SPACE
 /*
  * The following make the definitions in 53c7xx.h (write8, etc) smaller,
- * we don't have seperate i/o space anyway.
+ * we don't have separate i/o space anyway.
  */
 #undef inb
 #undef outb
@@ -2518,7 +2518,7 @@
 	 * RGH:  I don't really like it - You get an interrupt which
 	 * calls NCR53c7x0_intr(), which calls this function (via
 	 * intr_dma()), which calls NCR53c7x0_intr().....
-	 * Anyway lets see how it goes for now.
+	 * Anyway let's see how it goes for now.
 	 */
 	hostdata->emulated_intfly = 1;
 	NCR53c7x0_intr(host->irq, NULL, NULL);
@@ -5681,7 +5681,7 @@
 	    
 	/*
 	 * For the 53c710, the following will report value 0 for SCNTL3
-	 * and STEST0 - we dont have these registers.
+	 * and STEST0 - we don't have these registers.
 	 */
     	printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)\n"
 		"         DSA=0x%lx (virt 0x%p)\n"
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/53c7xx.h linux/drivers/scsi/53c7xx.h
--- v2.1.103/linux/drivers/scsi/53c7xx.h	Mon Apr  6 17:41:00 1998
+++ linux/drivers/scsi/53c7xx.h	Wed May 20 18:55:06 1998
@@ -1580,7 +1580,7 @@
 
 #ifdef BIG_ENDIAN
 /* If we are big-endian, then we are not Intel, so probably don't have
- * an i/o map as well as a memory map.  So, lets assume memory mapped.
+ * an i/o map as well as a memory map.  So, let's assume memory mapped.
  * Also, I am having terrible problems trying to persuade the compiler
  * not to lay down code which does a read after write for these macros.
  * If you remove 'volatile' from writeb() and friends it is ok....
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c
--- v2.1.103/linux/drivers/scsi/AM53C974.c	Thu May 14 19:47:40 1998
+++ linux/drivers/scsi/AM53C974.c	Thu May 21 14:24:07 1998
@@ -778,7 +778,7 @@
 	AM53C974_write_8(CMDREG, CMDREG_RBUS);	/* reset SCSI bus */
 	udelay(10);
 	AM53C974_config_after_reset(instance);
-	udelay(500000);
+	mdelay(500);
 	return (1);
 }
 
@@ -823,7 +823,7 @@
 {
 	static char info[100];
 
-	sprintf(info, "AM53/79C974 PCscsi driver rev. %d.%d; host I/O address: 0x%x; irq: %d\n",
+	sprintf(info, "AM53/79C974 PCscsi driver rev. %d.%d; host I/O address: 0x%lx; irq: %d\n",
 	  AM53C974_DRIVER_REVISION_MAJOR, AM53C974_DRIVER_REVISION_MINOR,
 		instance->io_port, instance->irq);
 	return (info);
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/ChangeLog.ncr53c8xx linux/drivers/scsi/ChangeLog.ncr53c8xx
--- v2.1.103/linux/drivers/scsi/ChangeLog.ncr53c8xx	Mon Jan 12 15:05:27 1998
+++ linux/drivers/scsi/ChangeLog.ncr53c8xx	Wed May 20 18:55:06 1998
@@ -838,7 +838,7 @@
 	working conditions (3 commands per lun, FAST SCSI, no command queueing).
 	I get the stack overflow problem with the 2 drivers at the same 
 	frequency.
-	With only 2 commands per lun, I dont have the problem with any driver.
+	With only 2 commands per lun, I don't have the problem with any driver.
 	It seems that the madness of recursion and the recent introduction of
 	the silly generic read function have broken performance and reliability 
 	of scsi drivers.
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c
--- v2.1.103/linux/drivers/scsi/NCR53C9x.c	Thu Mar 26 15:57:03 1998
+++ linux/drivers/scsi/NCR53C9x.c	Wed May 20 18:55:06 1998
@@ -1093,7 +1093,7 @@
 		}
 #endif
 		/* We've talked to this guy before,
-		 * but never negotiated.. lets try,
+		 * but never negotiated.  Let's try,
 		 * need to attempt WIDE first, before
 		 * sync nego, as per SCSI 2 standard.
 		 */
@@ -3002,7 +3002,7 @@
 			       esp->esp_id, size);
 			message_out = MESSAGE_REJECT;
 		} else {
-			/* Things look good, lets see what we got. */
+			/* Things look good; let's see what we got. */
 			if(size == 16) {
 				/* Set config 3 register for this target. */
 				printk("esp%d: 16 byte WIDE transfers enabled for target %d.\n",
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/README.aic7xxx linux/drivers/scsi/README.aic7xxx
--- v2.1.103/linux/drivers/scsi/README.aic7xxx	Tue Apr 14 14:29:21 1998
+++ linux/drivers/scsi/README.aic7xxx	Wed Jun  3 09:48:19 1998
@@ -100,8 +100,6 @@
     
   Boot Command line options
   ------------------------------
-    "aic7xxx=no_reset" -  Eliminate the SCSI reset delay during startup.
-        Some SCSI devices need some extra time to reset.
     "aic7xxx=reverse_scan" - Have the driver register the SCSI cards in the
         reverse of the normal order.  This may help those people who have more
         than one PCI Adaptec controller force the correct controller to be
@@ -134,6 +132,17 @@
         both channels to use the IRQ assigned to Channel A, 1 to force both
         channels to use the IRQ assigned to Channel B, and -1 will disable
         this horrible abomination of a hack.  The default is disabled (-1).
+    "aic7xxx=pci_parity:x" - This option controls whether or not the driver
+        enables PCI parity error checking on the PCI bus.  By default, this
+        checking is disabled.  To enable the checks, simply specify pci_parity
+        with no value afterwords.  To reverse the parity from even to odd,
+        supply any number other than 0 or 255.  In short:
+          pci_parity     - Even parity checking (even is the normal PCI parity)
+          pci_parity:x   - Where x > 0, Odd parity checking
+          pci_parity:0   - No check (default)
+        NOTE: In order to get Even PCI parity checking, you must use the
+        version of the option that does not include the : and a number at
+        the end (unless you want to enter exactly 2^32 - 1 as the number).
     "aic7xxx=tag_info:{{8,8..},{8,8..},..}" - This option is used to enable
         tagged queueing on specific devices.  As of driver version 5.0.6, we
         now globally enable tagged queueing by default, but we also disable
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- v2.1.103/linux/drivers/scsi/advansys.c	Thu May 14 19:47:40 1998
+++ linux/drivers/scsi/advansys.c	Thu May 21 14:24:08 1998
@@ -9211,12 +9211,8 @@
 STATIC void
 DvcSleepMilliSecond(ulong n)
 {
-    ulong i;
-
     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
-    for (i = 0; i < n; i++) {
-        udelay(1000);
-    }
+    mdelay(n);
 }
 
 STATIC int
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.1.103/linux/drivers/scsi/aha152x.c	Wed May 20 19:10:39 1998
+++ linux/drivers/scsi/aha152x.c	Thu May 21 13:45:02 1998
@@ -992,7 +992,7 @@
 
     aha152x_reset_ports(shpnt);
       
-    printk("aha152x%d: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d,"
+    printk("aha152x%d: vital data: PORTBASE=0x%03lx, IRQ=%d, SCSI ID=%d,"
            " reconnect=%s, parity=%s, synchronous=%s, delay=%d, extended translation=%s\n",
            i,
            shpnt->io_port,
@@ -3176,7 +3176,7 @@
   save_flags(flags);
   cli();
   
-  SPRINTF("ioports 0x%04x to 0x%04x\n",
+  SPRINTF("ioports 0x%04lx to 0x%04lx\n",
           shpnt->io_port, shpnt->io_port+shpnt->n_io_port-1);
   SPRINTF("interrupt 0x%02x\n", shpnt->irq);
   SPRINTF("disconnection/reconnection %s\n", 
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v2.1.103/linux/drivers/scsi/aha1542.c	Tue Apr 14 14:29:21 1998
+++ linux/drivers/scsi/aha1542.c	Fri May 22 23:10:45 1998
@@ -155,7 +155,7 @@
      WAITbits = inb(port) & (mask);					\
      if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
        break;                                                         	\
-     udelay(1000);							\
+     mdelay(1);							\
      if (--WAITtimeout == 0) goto fail;					\
    }									\
  }
@@ -223,7 +223,7 @@
 
 /* Similar to aha1542_in, except that we wait a very short period of time.
    We use this if we know the board is alive and awake, but we are not sure
-   if the board will respond the the command we are about to send or not */
+   if the board will respond to the command we are about to send or not */
 static int aha1542_in1(unsigned int base, unchar *cmdp, int len)
 {
     unsigned long flags;
@@ -319,8 +319,7 @@
 
     outb(SRST|IRST/*|SCRST*/, CONTROL(bse));
 
-    i = jiffies + 2;
-    while (i>jiffies); /* Wait a little bit for things to settle down. */
+    mdelay(20);	/* Wait a little bit for things to settle down. */
     
     debug = 1;
     /* Expect INIT and IDLE, any of the others are bad */
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- v2.1.103/linux/drivers/scsi/aha1740.c	Fri Apr 10 13:03:49 1998
+++ linux/drivers/scsi/aha1740.c	Thu May 21 13:45:02 1998
@@ -93,7 +93,7 @@
     }
     host = HOSTDATA(shpnt);
 
-    len = sprintf(buffer, "aha174x at IO:%x, IRQ %d, SLOT %d.\n"
+    len = sprintf(buffer, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n"
 		  "Extended translation %sabled.\n",
 		  shpnt->io_port, shpnt->irq, host->slot,
 		  host->translation ? "en" : "dis");
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v2.1.103/linux/drivers/scsi/aic7xxx.c	Fri May  8 23:14:49 1998
+++ linux/drivers/scsi/aic7xxx.c	Wed Jun  3 09:48:19 1998
@@ -209,7 +209,7 @@
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.0.13"
+#define AIC7XXX_C_VERSION  "5.0.18"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
@@ -237,12 +237,12 @@
 
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
 #  if defined(__sparc_v9__) || defined(__powerpc__)
-#    error "PPC and Sparc platforms are only support under 2.1.x and above"
+#    error "PPC and Sparc platforms are only support under 2.1.92 and above"
 #  endif
 #  include <linux/bios32.h>
 #endif
 
-#if !defined(__alpha__) && !defined(__sparc__)
+#if defined(__powerpc__) || defined(__i386__)
 #  define MMAPIO
 #endif
 
@@ -728,6 +728,7 @@
         AHC_BIOS_ENABLED          = 0x00800000,
         AHC_ABORT_PENDING         = 0x02000000,
         AHC_RESET_PENDING         = 0x04000000,
+#define AHC_IN_ISR_BIT              28
         AHC_IN_ISR                = 0x10000000,
         AHC_IN_ABORT              = 0x20000000,
         AHC_IN_RESET              = 0x40000000
@@ -866,12 +867,19 @@
 #define  DEVICE_PRINT_WDTR              0x10
 #define  DEVICE_SUCCESS                 0x20
 #define  DEVICE_TAGGED_SUCCESS          0x40
+#define  DEVICE_SCANNED                 0x80
   volatile unsigned char   dev_flags[MAX_TARGETS];
   volatile unsigned char   dev_active_cmds[MAX_TARGETS];
   unsigned char            dev_temp_queue_depth[MAX_TARGETS];
   unsigned char            dev_commands_sent[MAX_TARGETS];
 
   /*
+   * The next 128 (or 256 on 64 bit machines)....
+   */
+  Scsi_Cmnd               *dev_wdtr_cmnd[MAX_TARGETS];
+  Scsi_Cmnd               *dev_sdtr_cmnd[MAX_TARGETS];
+
+  /*
    * The next 64.... 
    */
 
@@ -936,6 +944,7 @@
   volatile unsigned char   untagged_scbs[256];
   volatile unsigned char   qoutfifo[256];
   volatile unsigned char   qinfifo[256];
+  unsigned int             irq;              /* IRQ for this adapter */
   unsigned short           needsdtr;
   unsigned short           sdtr_pending;
   unsigned short           needwdtr;
@@ -950,8 +959,10 @@
   unsigned short           needwdtr_copy;    /* default config */
   unsigned short           ultraenb;         /* Ultra mode target list */
   unsigned short           bios_control;     /* bios control - SEEPROM */
-  unsigned int             irq;              /* IRQ for this adapter */
   unsigned short           adapter_control;  /* adapter control - SEEPROM */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+  struct pci_dev          *pdev;
+#endif
   unsigned char            pci_bus;
   unsigned char            pci_device_fn;
 
@@ -1040,7 +1051,6 @@
                                               *   1 == Use the Channel B IRQ
                                               */
 static unsigned int aic7xxx_extended = 0;    /* extended translation on? */
-static unsigned int aic7xxx_no_reset = 0;    /* no resetting of SCSI bus */
 static int aic7xxx_irq_trigger = -1;         /*
                                               * -1 use board setting
                                               *  0 use edge triggered
@@ -1070,7 +1080,13 @@
                                               * or reset call into the
                                               * driver.
                                               */
-
+static int aic7xxx_pci_parity = 0;           /*
+                                              * Set this to:
+                                              *   0 - Shut off PCI parity check
+                                              *  -1 - Normal parity check
+                                              *  anything else - reverse pci
+                                              *    pci parity checking
+                                              */
 /*
  * So that insmod can find the variable and make it point to something
  */
@@ -1206,13 +1222,13 @@
     unsigned int *flag;
   } options[] = {
     { "extended",    &aic7xxx_extended },
-    { "no_reset",    &aic7xxx_no_reset },
     { "irq_trigger", &aic7xxx_irq_trigger },
     { "verbose",     &aic7xxx_verbose },
     { "reverse_scan",&aic7xxx_reverse_scan },
     { "7895_irq_hack", &aic7xxx_7895_irq_hack },
     { "override_term", &aic7xxx_override_term },
     { "panic_on_abort", &aic7xxx_panic_on_abort },
+    { "pci_parity", &aic7xxx_pci_parity },
     { "tag_info",    NULL }
   };
 
@@ -1390,8 +1406,8 @@
  * Description:
  *   Find the next patch to download.
  *-F*************************************************************************/
-static struct patch *
-aic7xxx_next_patch(struct patch *cur_patch, int options, int instrptr)
+static struct sequencer_patch *
+aic7xxx_next_patch(struct sequencer_patch *cur_patch, int options, int instrptr)
 {
   while (cur_patch != NULL)
   {
@@ -1450,15 +1466,15 @@
     {
       int address_offset;
       unsigned int address;
-      struct patch *patch;
+      struct sequencer_patch *patch;
       int i;
 
       address_offset = 0;
       address = instr.address;
       address |= (instr.opcode_addr & ADDR_HIGH_BIT) << 8;
-      for (i = 0; i < NUMBER(patches); i++)
+      for (i = 0; i < NUMBER(sequencer_patches); i++)
       {
-        patch = &patches[i];
+        patch = &sequencer_patches[i];
         if ((((patch->options & options) == 0) && (patch->negative == FALSE)) ||
             (((patch->options & options) != 0) && (patch->negative == TRUE)))
         {
@@ -1506,7 +1522,7 @@
 aic7xxx_loadseq(struct aic7xxx_host *p)
 {
   int options;
-  struct patch *cur_patch;
+  struct sequencer_patch *cur_patch;
   int i;
   int downloaded;
 
@@ -1560,7 +1576,7 @@
   }
 
 
-  cur_patch = patches;
+  cur_patch = sequencer_patches;
   aic_outb(p, PERRORDIS | LOADRAM, SEQCTL);
   aic_outb(p, 0, SEQADDR0);
   aic_outb(p, 0, SEQADDR1);
@@ -1602,16 +1618,7 @@
 static void
 aic7xxx_delay(int seconds)
 {
-  unsigned int i;
-
-  /*                        
-   * Call udelay() for 1 millisecond inside a loop for  
-   * the requested amount of seconds.
-   */
-  for (i=0; i < seconds*1000; i++)
-  {
-    udelay(1000);  /* Delay for 1 millisecond. */
-  }
+  mdelay(seconds*1000);
 }
 
 /*+F*************************************************************************
@@ -1799,10 +1806,16 @@
 static inline void
 scbq_insert_head(volatile scb_queue_type *queue, struct aic7xxx_scb *scb)
 {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
+  unsigned long cpu_flags;
+#endif
+
+  DRIVER_LOCK
   scb->q_next = queue->head;
   queue->head = scb;
   if (queue->tail == NULL)       /* If list was empty, update tail. */
     queue->tail = queue->head;
+  DRIVER_UNLOCK
 }
 
 /*+F*************************************************************************
@@ -1817,11 +1830,17 @@
 scbq_remove_head(volatile scb_queue_type *queue)
 {
   struct aic7xxx_scb * scbp;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
+  unsigned long cpu_flags;
+#endif
+
+  DRIVER_LOCK
   scbp = queue->head;
   if (queue->head != NULL)
     queue->head = queue->head->q_next;
   if (queue->head == NULL)       /* If list is now empty, update tail. */
     queue->tail = NULL;
+  DRIVER_UNLOCK
   return(scbp);
 }
 
@@ -1836,6 +1855,11 @@
 static inline void
 scbq_remove(volatile scb_queue_type *queue, struct aic7xxx_scb *scb)
 {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
+  unsigned long cpu_flags;
+#endif
+
+  DRIVER_LOCK
   if (queue->head == scb)
   {
     /* At beginning of queue, remove from head. */
@@ -1864,6 +1888,7 @@
       }
     }
   }
+  DRIVER_UNLOCK
 }
 
 /*+F*************************************************************************
@@ -1877,12 +1902,18 @@
 static inline void
 scbq_insert_tail(volatile scb_queue_type *queue, struct aic7xxx_scb *scb)
 {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
+  unsigned long cpu_flags;
+#endif
+
+  DRIVER_LOCK
   scb->q_next = NULL;
   if (queue->tail != NULL)       /* Add the scb at the end of the list. */
     queue->tail->q_next = scb;
   queue->tail = scb;             /* Update the tail. */
   if (queue->head == NULL)       /* If list was empty, update head. */
     queue->head = queue->tail;
+  DRIVER_UNLOCK
 }
 
 /*+F*************************************************************************
@@ -2167,7 +2198,6 @@
   Scsi_Cmnd *cmd;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
   unsigned int cpu_flags = 0;
-#endif
   
   DRIVER_LOCK
   while (p->completeq.head != NULL)
@@ -2175,11 +2205,20 @@
     cmd = p->completeq.head;
     p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
     cmd->host_scribble = NULL;
-    DRIVER_UNLOCK
+    sti();
     cmd->scsi_done(cmd);
-    DRIVER_LOCK
+    cli();
   }
   DRIVER_UNLOCK
+#else
+  while (p->completeq.head != NULL)
+  {
+    cmd = p->completeq.head;
+    p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
+    cmd->host_scribble = NULL;
+    cmd->scsi_done(cmd);
+  }
+#endif
 }
 
 /*+F*************************************************************************
@@ -2234,6 +2273,52 @@
       cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24) | 
         (cmd->result & 0xffff);
   }
+  if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
+  {
+    if(cmd->cmnd[0] == INQUIRY)
+    {
+      char *buffer;
+      
+      if(cmd->use_sg)
+      {
+        struct scatterlist *sg;
+
+        sg = (struct scatterlist *)cmd->request_buffer;
+        buffer = (char *)sg[0].address;
+      }
+      else
+      {
+        buffer = (char *)cmd->request_buffer;
+      }
+#define WIDE_INQUIRY_BITS 0x60
+#define SYNC_INQUIRY_BITS 0x10
+      if (buffer[7] & WIDE_INQUIRY_BITS)
+      {
+        p->needwdtr |= (1<<tindex);
+        p->needwdtr_copy |= (1<<tindex);
+        p->syncinfo[tindex].offset = MAX_OFFSET_16BIT;
+      }
+      else
+      {
+        p->needwdtr &= ~(1<<tindex);
+        p->needwdtr_copy &= ~(1<<tindex);
+        p->syncinfo[tindex].offset = MAX_OFFSET_8BIT;
+      }
+      if (buffer[7] & SYNC_INQUIRY_BITS)
+      {
+        p->needsdtr |= (1<<tindex);
+        p->needsdtr_copy |= (1<<tindex);
+      }
+      else
+      {
+        p->needsdtr &= ~(1<<tindex);
+        p->needsdtr_copy &= ~(1<<tindex);
+      }
+      p->dev_flags[tindex] |= DEVICE_SCANNED;
+#undef WIDE_INQUIRY_BITS
+#undef SYNC_INQUIRY_BITS
+    }
+  }
   if ((scb->flags & (SCB_MSGOUT_WDTR | SCB_MSGOUT_SDTR)) != 0)
   {
     unsigned short mask;
@@ -2298,23 +2383,32 @@
   {
     scbp = scbq_remove_head(&p->delayed_scbs[tindex]);
     if (scbp)
-      scbq_insert_tail(&p->waiting_scbs, scbp);
-    if ( (queue_depth > p->dev_active_cmds[tindex]) && scbp)
+    {
+      if (queue_depth == 1)
+      {
+        /*
+         * Give extra preference to untagged devices, such as CD-R devices
+         * This makes it more likely that a drive *won't* stuff up while
+         * waiting on data at a critical time, such as CD-R writing and
+         * audio CD ripping operations.  Should also benefit tape drives.
+         */
+        scbq_insert_head(&p->waiting_scbs, scbp);
+      }
+      else
+      {
+        scbq_insert_tail(&p->waiting_scbs, scbp);
+      }
+    }
+    if ( (queue_depth > p->dev_active_cmds[tindex]) && scbp )
     {
       scbp = scbq_remove_head(&p->delayed_scbs[tindex]);
       if (scbp)
         scbq_insert_tail(&p->waiting_scbs, scbp);
     }
   }
-  if ( (p->dev_timer[tindex].expires) &&
-      ((p->dev_active_cmds[tindex] == 1) ||
-       (p->dev_max_queue_depth[tindex] ==
-        p->dev_temp_queue_depth[tindex])) )
-  {
-    del_timer(&p->dev_timer[tindex]);
-    p->dev_timer[tindex].expires = 0;
-    p->dev_temp_queue_depth[tindex] = 
-          p->dev_max_queue_depth[tindex];
+  if ( !(scb->tag_action) && (p->tagenable & (1<<tindex)) )
+  {
+    p->dev_temp_queue_depth[tindex] = p->dev_max_queue_depth[tindex];
   }
   p->dev_active_cmds[tindex]--;
   p->activescbs--;
@@ -2513,13 +2607,18 @@
         */
        if (requeue && (queue != NULL))
        {
-         if ( !(scbp->flags & SCB_WAITINGQ) )
+         if (scbp->flags & SCB_WAITINGQ)
          {
-           scbq_insert_tail(queue, scbp);
-           p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]--;
-           p->activescbs--;
-           scbp->flags |= SCB_WAITINGQ;
+           scbq_remove(queue, scbp);
+           scbq_remove(&p->waiting_scbs, scbp);
+           scbq_remove(&p->delayed_scbs[TARGET_INDEX(scbp->cmd)], scbp);
+           p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
+           p->activescbs++;
          }
+         scbq_insert_tail(queue, scbp);
+         p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]--;
+         p->activescbs--;
+         scbp->flags |= SCB_WAITINGQ;
          if ( !(scbp->tag_action & TAG_ENB) )
          {
            aic7xxx_index_busy_target(p, scbp->hscb->target_channel_lun,
@@ -2689,12 +2788,11 @@
    * here so that we can delay all re-sent commands for this device for the
    * 4 seconds and then have our timer routine pick them back up.
    */
-        if( (p->dev_timer[i].prev != NULL) ||
-            (p->dev_timer[i].next != NULL) )
+        if(p->dev_timer[i].expires)
         {
           del_timer(&p->dev_timer[i]);
         }
-        p->dev_timer[i].expires = jiffies + (3 * HZ);
+        p->dev_timer[i].expires = jiffies + (4 * HZ);
         add_timer(&p->dev_timer[i]);
       }
       for(j=0; j<MAX_LUNS; j++)
@@ -2726,7 +2824,7 @@
         if (aic7xxx_match_scb(p, prev_scbp, target, channel, lun, tag))
         {
           scbq_remove(&p->delayed_scbs[i], prev_scbp);
-          if ( !(prev_scbp->flags & SCB_QUEUED_ABORT) )
+          if (prev_scbp->flags & SCB_WAITINGQ)
           {
             p->dev_active_cmds[i]++;
             p->activescbs++;
@@ -2785,7 +2883,7 @@
       if (aic7xxx_match_scb(p, prev_scbp, target, channel, lun, tag))
       {
         scbq_remove(&p->waiting_scbs, prev_scbp);
-        if ( !(prev_scbp->flags & SCB_QUEUED_ABORT) )
+        if (prev_scbp->flags & SCB_WAITINGQ)
         {
           p->dev_active_cmds[TARGET_INDEX(prev_scbp->cmd)]++;
           p->activescbs++;
@@ -2838,6 +2936,11 @@
         if (aic7xxx_match_scb(p, scbp, target, channel, lun, tag))
         {
           next = aic7xxx_abort_waiting_scb(p, scbp, next, prev);
+          if (scbp->flags & SCB_WAITINGQ)
+          {
+            p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
+            p->activescbs++;
+          }
           scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
           scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
           if (prev == SCB_LIST_NULL)
@@ -2849,6 +2952,7 @@
              * it isn't already off.
              */
             aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ);
+            aic_outb(p, CLRSELTIMEO, CLRSINT1);
           }
         }
         else
@@ -2870,6 +2974,9 @@
    * Go through disconnected list and remove any entries we have queued
    * for completion, zeroing their control byte too.
    */
+  if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
+    printk(INFO_LEAD "Cleaning disconnected scbs "
+      "list.\n", p->host_no, channel, target, lun);
   {
     unsigned char next, prev, scb_index;
 
@@ -2882,7 +2989,7 @@
       scb_index = aic_inb(p, SCB_TAG);
       if (scb_index > p->scb_data->numscbs)
       {
-        printk(WARN_LEAD "Waiting List inconsistency; SCB index=%d, "
+        printk(WARN_LEAD "Disconnected List inconsistency; SCB index=%d, "
           "numscbs=%d\n", p->host_no, channel, target, lun, scb_index,
           p->scb_data->numscbs);
         next = aic7xxx_rem_scb_from_disc_list(p, next);
@@ -2893,6 +3000,11 @@
         if (aic7xxx_match_scb(p, scbp, target, channel, lun, tag))
         {
           next = aic7xxx_rem_scb_from_disc_list(p, next);
+          if (scbp->flags & SCB_WAITINGQ)
+          {
+            p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
+            p->activescbs++;
+          }
           scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
           scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
           scbp->hscb->control = 0;
@@ -3002,6 +3114,13 @@
         aic7xxx_match_scb(p, scbp, target, channel, lun, tag) &&
         !aic7xxx_scb_on_qoutfifo(p, scbp))
     {
+      if (scbp->flags & SCB_WAITINGQ)
+      {
+        scbq_remove(&p->waiting_scbs, scbp);
+        scbq_remove(&p->delayed_scbs[TARGET_INDEX(scbp->cmd)], scbp);
+        p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
+        p->activescbs++;
+      }
       scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
       scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
     }
@@ -3047,7 +3166,7 @@
   scsiseq = aic_inb(p, SCSISEQ);
   aic_outb(p, scsiseq | SCSIRSTO, SCSISEQ);
 
-  udelay(1000);
+  mdelay(1);
 
   /* Turn off the bus reset. */
   aic_outb(p, scsiseq & ~SCSIRSTO, SCSISEQ);
@@ -3057,7 +3176,7 @@
   /* Re-enable reset interrupts. */
   aic_outb(p, aic_inb(p, SIMODE1) | ENSCSIRST, SIMODE1);
 
-  udelay(1000);
+  mdelay(1);
 }
 
 /*+F*************************************************************************
@@ -3178,12 +3297,6 @@
     restart_sequencer(p);
   }
 
-  /*
-   * Now loop through all the SCBs that have been marked for abortion,
-   * and call the scsi_done routines.
-   */
-  if(!(p->flags & AHC_IN_ISR))
-    aic7xxx_run_done_queue(p, /*complete*/ TRUE);
   return;
 }
 
@@ -3218,20 +3331,27 @@
   while ((scb = scbq_remove_head(&p->waiting_scbs)) != NULL)
   {
     tindex = TARGET_INDEX(scb->cmd);
+    if ( !scb->tag_action && (p->tagenable & (1<<tindex)) )
+    {
+      p->dev_temp_queue_depth[tindex] = 1;
+    }
     if ( (p->dev_active_cmds[tindex] >=
           p->dev_temp_queue_depth[tindex]) ||
-         (p->dev_last_reset[tindex] >= (jiffies + (3 * HZ))) )
+         (p->dev_last_reset[tindex] >= (jiffies - (4 * HZ))) )
     {
         scbq_insert_tail(&p->delayed_scbs[tindex], scb);
+        if ( !(p->dev_timer[tindex].expires) &&
+             !(p->dev_active_cmds[tindex]) )
+        {
+          p->dev_timer[tindex].expires = p->dev_last_reset[tindex] + (4 * HZ);
+          add_timer(&p->dev_timer[tindex]);
+        }
     }
     else
     {
         scb->flags &= ~SCB_WAITINGQ;
-        if ( !(scb->flags & SCB_QUEUED_ABORT) )
-        {
-          p->dev_active_cmds[tindex]++;
-          p->activescbs++;
-        }
+        p->dev_active_cmds[tindex]++;
+        p->activescbs++;
         if ( !(scb->tag_action) )
         {
           aic7xxx_busy_target(p, scb);
@@ -3242,14 +3362,9 @@
   }
   if (sent)
   {
-    if(p->type & AHC_AIC78x0)
-      aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
-    else
-    {
-      pause_sequencer(p);
-      aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
-      unpause_sequencer(p, FALSE);
-    }
+    pause_sequencer(p);
+    aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
+    unpause_sequencer(p, FALSE);
     if (p->activescbs > p->max_activescbs)
       p->max_activescbs = p->activescbs;
   }
@@ -3268,7 +3383,7 @@
 static void
 aic7xxx_timer(struct aic7xxx_host *p)
 {
-  int i;
+  int i, j;
   unsigned long cpu_flags = 0;
   struct aic7xxx_scb *scb;
 
@@ -3289,10 +3404,23 @@
         del_timer(&p->dev_timer[i]);
       }
       p->dev_temp_queue_depth[i] =  p->dev_max_queue_depth[i];
-      while ( (scb = scbq_remove_head(&p->delayed_scbs[i])) != NULL )
+      j = 0;
+      while ( ((scb = scbq_remove_head(&p->delayed_scbs[i])) != NULL) &&
+              (j++ < p->scb_data->numscbs) )
       {
         scbq_insert_tail(&p->waiting_scbs, scb);
       }
+      if (j == p->scb_data->numscbs)
+      {
+        printk(INFO_LEAD "timer: Yikes, loop in delayed_scbs list.\n",
+          p->host_no, 0, i, -1);
+        scbq_init(&p->delayed_scbs[i]);
+        scbq_init(&p->waiting_scbs);
+        /*
+         * Well, things are screwed now, wait for a reset to clean the junk
+         * out.
+         */
+      }
     }
   }
   aic7xxx_run_waiting_queues(p);
@@ -3433,7 +3561,7 @@
   if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
     printk(INFO_LEAD "Bus Device Reset delivered.\n", p->host_no, channel,
       target, -1);
-  aic7xxx_run_done_queue(p, /*complete*/ TRUE);
+  aic7xxx_run_done_queue(p, /*complete*/ FALSE);
 }
 
 /*+F*************************************************************************
@@ -3495,6 +3623,7 @@
             lun, aic_inb(p, LASTPHASE), aic_inb(p, SAVED_TCL));
 
         aic7xxx_reset_channel(p, channel, /*initiate reset*/ TRUE);
+        aic7xxx_run_done_queue(p, FALSE);
 
       }
       break;
@@ -3559,8 +3688,8 @@
         last_msg = aic_inb(p, LAST_MSG);
 
         if ( (last_msg == MSG_IDENTIFYFLAG) &&
-             (scb->tag_action != 0 ) &&
-             !(p->flags & AHC_HANDLING_REQINITS) )
+             (scb->tag_action) &&
+            !(scb->flags & SCB_MSGOUT_BITS) )
         {
           if ((scb->tag_action == MSG_ORDERED_Q_TAG) &&
               (p->dev_flags[scratch_offset] & DEVICE_TAGGED_SUCCESS))
@@ -3581,8 +3710,11 @@
              * ATNO and hope this will take us into the identify phase again
              * so we can resend the tag type and info to the device.
              */
+            aic_outb(p, MSG_IDENTIFYFLAG, MSG_OUT);
+            aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
           }
-          else
+          else if ( (scb->tag_action == MSG_SIMPLE_Q_TAG) &&
+                   !(p->dev_flags[scratch_offset] & DEVICE_TAGGED_SUCCESS) )
           {
             unsigned char i, reset = 0;
             struct aic7xxx_scb *scbp;
@@ -3612,7 +3744,6 @@
              */
             scb->tag_action = 0;
             scb->hscb->control &= ~(TAG_ENB | SCB_TAG_TYPE);
-            scb->hscb->control |= MK_MESSAGE;
             aic_outb(p,  scb->hscb->control, SCB_CONTROL);
 
             old_verbose = aic7xxx_verbose;
@@ -3627,6 +3758,7 @@
                   aic7xxx_reset_device(p, target, channel, lun, i);
                   reset++;
                 }
+                aic7xxx_run_done_queue(p, FALSE);
               }
             }
             aic7xxx_verbose = old_verbose;
@@ -3638,12 +3770,11 @@
             aic7xxx_busy_target(p, scb);
             printk(INFO_LEAD "Device is refusing tagged commands, using "
               "untagged I/O.\n", p->host_no, channel, target, lun);
+            aic_outb(p, MSG_IDENTIFYFLAG, MSG_OUT);
+            aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
           }
-          aic_outb(p, MSG_IDENTIFYFLAG, MSG_OUT);
-          aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
         }
-        else if ( (last_msg == MSG_IDENTIFYFLAG) && 
-                  (scb->flags & SCB_MSGOUT_WDTR) )
+        else if (scb->flags & SCB_MSGOUT_WDTR)
         {
           /*
            * note 8bit xfers and clear flag
@@ -3661,13 +3792,8 @@
           }
           scb->flags &= ~SCB_MSGOUT_WDTR_16BIT;
           p->syncinfo[scratch_offset].offset = MAX_OFFSET_8BIT;
-          if (p->needsdtr & target_mask)
-          {
-            p->sdtr_pending |= target_mask;
-            scb->flags |= SCB_MSGOUT_SDTR;
-            aic_outb(p, HOST_MSG, MSG_OUT);
-            aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
-          }
+          if (p->needsdtr_copy & target_mask)
+            p->needsdtr |= target_mask;
         }
         else if (scb->flags & SCB_MSGOUT_SDTR)
         {
@@ -3766,7 +3892,7 @@
                    * Send a sense command to the requesting target.
                  * XXX - revisit this and get rid of the memcopys.
                    */
-                memcpy((void *) scb->sense_cmd, (void *) generic_sense,
+                memcpy(&scb->sense_cmd[0], &generic_sense[0],
                        sizeof(generic_sense));
 
                 scb->sense_cmd[1] = (cmd->lun << 5);
@@ -3806,10 +3932,16 @@
                  * so if needed, we'll re-negotiate while doing the sense cmd.
                  * However, if this SCB already was attempting to negotiate,
                  * then we assume this isn't the problem and skip this part.
+                 *
+                 * 1998/04/23 - We also don't want to set the flag if the
+                 *   original command was a TEST_UNIT_READY since that
+                 *   implies a SEND_SENSE anyway.
                  */
-                if ( !(scb->flags & SCB_MSGOUT_BITS) )
+                if (scb->cmd->cmnd[0] != TEST_UNIT_READY)
                 {
-                  if ( p->needwdtr_copy & target_mask )
+                  if ( (p->needwdtr_copy & target_mask) &&
+                      !(p->wdtr_pending & target_mask) &&
+                      !(p->sdtr_pending & target_mask) )
                   {
                     p->needwdtr |= target_mask;
                     p->wdtr_pending |= target_mask;
@@ -3819,7 +3951,8 @@
                   if ( p->needsdtr_copy & target_mask )
                   {
                     p->needsdtr |= target_mask;
-                    if ((hscb->control & MK_MESSAGE) == 0)
+                    if ( !(p->wdtr_pending & target_mask) &&
+                         !(p->sdtr_pending & target_mask) )
                     {
                       p->sdtr_pending |= target_mask;
                       hscb->control |= MK_MESSAGE;
@@ -3879,41 +4012,60 @@
               {
                 aic_outb(p, next_hscb, SCBPTR);
                 scb_index = aic_inb(p, SCB_TAG);
-                next_scbp = p->scb_data->scb_array[scb_index];
-                if (aic7xxx_match_scb(p, next_scbp, target, channel, lun,
-                    SCB_LIST_NULL) )
+                if (scb_index < p->scb_data->numscbs)
                 {
-                  scbq_insert_head(&p->delayed_scbs[scratch_offset],
-                    next_scbp);
-                  next_scbp->flags |= SCB_WAITINGQ;
-                  p->dev_active_cmds[scratch_offset]--;
-                  p->activescbs--;
-                  next_hscb = aic_inb(p, SCB_NEXT);
-                  aic_outb(p, 0, SCB_CONTROL);
-                  aic_outb(p, SCB_LIST_NULL, SCB_TAG);
-                  aic7xxx_add_curscb_to_free_list(p);
-                  if (prev_hscb == SCB_LIST_NULL)
+                  next_scbp = p->scb_data->scb_array[scb_index];
+                  if (aic7xxx_match_scb(p, next_scbp, target, channel, lun,
+                      SCB_LIST_NULL) )
                   {
-                    aic_outb(p, 0, SCSISEQ);    /* We were first on the list,
-                                                 * so we kill the selection
-                                                 * hardware.  Let the sequencer
-                                                 * re-init the hardware itself
-                                                 */
-                    aic_outb(p, next_hscb, WAITING_SCBH);
+                    if (next_scbp->flags & SCB_WAITINGQ)
+                    {
+                      p->dev_active_cmds[scratch_offset]++;
+                      p->activescbs--;
+                      scbq_remove(&p->delayed_scbs[scratch_offset], next_scbp);
+                      scbq_remove(&p->waiting_scbs, next_scbp);
+                    }
+                    scbq_insert_head(&p->delayed_scbs[scratch_offset],
+                      next_scbp);
+                    next_scbp->flags |= SCB_WAITINGQ;
+                    p->dev_active_cmds[scratch_offset]--;
+                    p->activescbs--;
+                    next_hscb = aic_inb(p, SCB_NEXT);
+                    aic_outb(p, 0, SCB_CONTROL);
+                    aic_outb(p, SCB_LIST_NULL, SCB_TAG);
+                    aic7xxx_add_curscb_to_free_list(p);
+                    if (prev_hscb == SCB_LIST_NULL)
+                    {
+                      /* We were first on the list,
+                       * so we kill the selection
+                       * hardware.  Let the sequencer
+                       * re-init the hardware itself
+                       */
+                      aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ);
+                      aic_outb(p, CLRSELTIMEO, CLRSINT1);
+                      aic_outb(p, next_hscb, WAITING_SCBH);
+                    }
+                    else
+                    {
+                      aic_outb(p, prev_hscb, SCBPTR);
+                      aic_outb(p, next_hscb, SCB_NEXT);
+                    }
                   }
                   else
                   {
-                    aic_outb(p, prev_hscb, SCBPTR);
-                    aic_outb(p, next_hscb, SCB_NEXT);
+                    prev_hscb = next_hscb;
+                    next_hscb = aic_inb(p, SCB_NEXT);
                   }
-                }
-                else
-                {
-                  prev_hscb = next_hscb;
-                  next_hscb = aic_inb(p, SCB_NEXT);
-                }
+                } /* scb_index >= p->scb_data->numscbs */
               }
               aic_outb(p, active_hscb, SCBPTR);
+              if (scb->flags & SCB_WAITINGQ)
+              {
+                scbq_remove(&p->delayed_scbs[scratch_offset], scb);
+                scbq_remove(&p->waiting_scbs, scb);
+                p->dev_active_cmds[scratch_offset]++;
+                p->activescbs++;
+              }
               scbq_insert_head(&p->delayed_scbs[scratch_offset], scb);
               p->dev_active_cmds[scratch_offset]--;
               p->activescbs--;
@@ -3989,9 +4141,10 @@
 
     case AWAITING_MSG:
       {
-        unsigned char scb_index;
+        unsigned char scb_index, msg_out;
 
         scb_index = aic_inb(p, SCB_TAG);
+        msg_out = aic_inb(p, MSG_OUT);
         scb = p->scb_data->scb_array[scb_index];
         p->msg_index = p->msg_len = 0;
         /*
@@ -4010,14 +4163,14 @@
         }
         else if (scb->flags & SCB_ABORT)
         {
-          if (scb->hscb->control & TAG_ENB)
+          if (scb->tag_action)
           {
-            if (aic_inb(p, MSG_OUT) == MSG_IDENTIFYFLAG)
+            if (msg_out == MSG_IDENTIFYFLAG)
             {
               p->msg_buf[p->msg_index++] = scb->tag_action;
               p->msg_buf[p->msg_index++] = scb->hscb->tag;
-              p->msg_len += 2;
-            }
+	      p->msg_len += 2;
+	    }
             p->msg_buf[p->msg_index++] = MSG_ABORT_TAG;
           }
           else
@@ -4051,6 +4204,7 @@
         }
         else 
         {
+          sti();
           panic("aic7xxx: AWAITING_MSG for an SCB that does "
                 "not have a waiting message.\n");
         }
@@ -4324,6 +4478,18 @@
           }
           scb->flags &= ~SCB_MSGOUT_WDTR_16BIT;
           p->wdtr_pending &= ~target_mask;
+          /*
+           * By virtue of the SCSI spec, a WDTR message negates any existing
+           * SDTR negotiations.  So, even if needsdtr isn't marked for this
+           * device, we still have to do a new SDTR message if the device
+           * supports SDTR at all.  Therefore, we check needsdtr_copy instead
+           * of needstr.
+           */
+          if ( (p->needsdtr_copy & target_mask) &&
+              !(p->sdtr_pending & target_mask))
+          {
+            p->needsdtr |= target_mask;
+          }
         }
         else
         {
@@ -4373,21 +4539,6 @@
         p->syncinfo[scratch_offset].offset =
           (bus_width == MSG_EXT_WDTR_BUS_8_BIT) ? 
           MAX_OFFSET_8BIT : MAX_OFFSET_16BIT;
-        if ( !(p->wdtr_pending & target_mask) && !reject)
-        {
-          /*
-           * We've successfully completed the wide negotiation, so let's start
-           * up the sync negotiation now.
-           */
-          scb->flags &= ~SCB_MSGOUT_WDTR_16BIT;
-          if ((p->needsdtr & target_mask) && !(p->sdtr_pending & target_mask))
-          {
-            p->sdtr_pending |= target_mask;
-            scb->flags |= SCB_MSGOUT_SDTR;
-            aic_outb(p, HOST_MSG, MSG_OUT);
-            aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
-          }
-        }
         done = TRUE;
         break;
       }
@@ -4569,6 +4720,7 @@
      * reset the channel again.
      */
     aic7xxx_reset_channel(p, channel, /* Initiate Reset */ FALSE);
+    aic7xxx_run_done_queue(p, FALSE);
     scb = NULL;
   }
   else if ( ((status & BUSFREE) != 0) && ((status & SELTO) == 0) )
@@ -4724,9 +4876,9 @@
       }
     }
     /*
-     * Stop the selection.
+     * Restarting the sequencer will stop the selection and make sure devices
+     * are allowed to reselect in.
      */
-    aic_outb(p, 0, SCSISEQ);
     aic_outb(p, aic_inb(p, SIMODE1) & ~ENREQINIT, SIMODE1);
     p->flags &= ~AHC_HANDLING_REQINITS;
     aic_outb(p, CLRSELTIMEO | CLRBUSFREE | CLRREQINIT, CLRSINT1);
@@ -4856,43 +5008,39 @@
 aic7xxx_pci_intr(struct aic7xxx_host *p)
 {
   unsigned char status1;
-  int error;
 
-  error = 0;
-  error = pcibios_read_config_byte(p->pci_bus, p->pci_device_fn,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+  pci_read_config_byte(p->pdev, PCI_STATUS, &status1);
+#else
+  pcibios_read_config_byte(p->pci_bus, p->pci_device_fn,
                                             PCI_STATUS, &status1);
+#endif
 
-  if (error == 0)
-  {
-    if (status1 & DPE)
-      printk(WARN_LEAD "Data Parity Error during PCI address or PCI write"
-        "phase.\n", p->host_no, -1, -1, -1);
-    if (status1 & SSE)
-      printk(WARN_LEAD "Signal System Error Detected\n", p->host_no,
-        -1, -1, -1);
-    if (status1 & RMA)
-      printk(WARN_LEAD "Received a PCI Master Abort\n", p->host_no,
-        -1, -1, -1);
-    if (status1 & RTA)
-      printk(WARN_LEAD "Received a PCI Target Abort\n", p->host_no,
-        -1, -1, -1);
-    if (status1 & STA)
-      printk(WARN_LEAD "Signaled a PCI Target Abort\n", p->host_no,
-        -1, -1, -1);
-    if (status1 & DPR)
-      printk(WARN_LEAD "Data Parity Error has been reported via PCI pin "
-        "PERR#\n", p->host_no, -1, -1, -1);
-  }
-  else
-  {
-    printk(WARN_LEAD "Error reading PCI config register during PCI ERROR"
-      "interrupt.\n", p->host_no, -1, -1, -1);
-    aic_outb(p,  CLRPARERR, CLRINT);
-    return;
-  }
+  if ( (status1 & DPE) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+    printk(WARN_LEAD "Data Parity Error during PCI address or PCI write"
+      "phase.\n", p->host_no, -1, -1, -1);
+  if ( (status1 & SSE) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+    printk(WARN_LEAD "Signal System Error Detected\n", p->host_no,
+      -1, -1, -1);
+  if ( (status1 & RMA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+    printk(WARN_LEAD "Received a PCI Master Abort\n", p->host_no,
+      -1, -1, -1);
+  if ( (status1 & RTA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+    printk(WARN_LEAD "Received a PCI Target Abort\n", p->host_no,
+      -1, -1, -1);
+  if ( (status1 & STA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+    printk(WARN_LEAD "Signaled a PCI Target Abort\n", p->host_no,
+      -1, -1, -1);
+  if ( (status1 & DPR) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+    printk(WARN_LEAD "Data Parity Error has been reported via PCI pin "
+      "PERR#\n", p->host_no, -1, -1, -1);
   
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+  pci_write_config_byte(p->pdev, PCI_STATUS, status1);
+#else
   pcibios_write_config_byte(p->pci_bus, p->pci_device_fn,
                                             PCI_STATUS, status1);
+#endif
   if (status1 & (DPR|RMA|RTA))
     aic_outb(p,  CLRPARERR, CLRINT);
 
@@ -4915,17 +5063,11 @@
   p = (struct aic7xxx_host *)dev_id;
 
   /*
-   * Just a few sanity checks.  Make sure p != NULL, that we have an
-   * interrupt pending, and that we aren't already in our int handler.
+   * Just a few sanity checks.  Make sure that we have an int pending.
    * Also, if PCI, then we are going to check for a PCI bus error status
    * should we get too many spurious interrupts.
    */
-  if (p == NULL)
-  {
-    printk(KERN_WARNING "aic7xxx: ISR routine called with NULL dev_id\n");
-    return;
-  }
-  else if (!(aic_inb(p, INTSTAT) & INT_PEND))
+  if (!((intstat = aic_inb(p, INTSTAT)) & INT_PEND))
   {
 #ifdef CONFIG_PCI
     if ((p->type & AHC_AIC78x0) && (p->spurious_int > 500))
@@ -4943,26 +5085,17 @@
 #endif
     return;
   }
-  else if (p->flags & AHC_IN_ISR)
-  {
-    return;
-  }
 
-  /*
-   * Handle all the interrupt sources - especially for SCSI
-   * interrupts, we won't get a second chance at them.
-   */
-  intstat = aic_inb(p, INTSTAT);
   p->spurious_int = 0;
 
   /*
    * Keep track of interrupts for /proc/scsi
    */
   p->isr_count++;
-  p->flags |= AHC_IN_ISR;
 
   /*
-   * Indicate that we're in the interrupt handler.
+   * Handle all the interrupt sources - especially for SCSI
+   * interrupts, we won't get a second chance at them.
    */
   if (intstat & CMDCMPLT)
   {
@@ -5008,6 +5141,21 @@
           (unsigned long) scb->cmd);
         continue;
       }
+      else if (scb->flags & SCB_QUEUED_ABORT)
+      {
+        pause_sequencer(p);
+        if ( ((aic_inb(p, LASTPHASE) & PHASE_MASK) != P_BUSFREE) &&
+             (aic_inb(p, SCB_TAG) == scb->hscb->tag) )
+        {
+          unpause_sequencer(p, FALSE);
+          continue;
+        }
+        aic7xxx_reset_device(p, scb->cmd->target, scb->cmd->channel,
+          scb->cmd->lun, scb->hscb->tag);
+        scb->flags &= ~(SCB_QUEUED_FOR_DONE | SCB_RESET | SCB_ABORT |
+          SCB_QUEUED_ABORT);
+        unpause_sequencer(p, FALSE);
+      }
       switch (status_byte(scb->hscb->target_status))
       {
         case QUEUE_FULL:
@@ -5056,6 +5204,7 @@
       aic7xxx_reset_channel(p, 1, TRUE);
       restart_sequencer(p);
     }
+    aic7xxx_run_done_queue(p, FALSE);
     aic_outb(p, CLRBRKADRINT, CLRINT);
   }
 
@@ -5068,12 +5217,6 @@
   {
     aic7xxx_handle_scsiint(p, intstat);
   }
-  if(!(p->flags & (AHC_IN_ABORT | AHC_IN_RESET)))
-  {
-    aic7xxx_done_cmds_complete(p);
-    aic7xxx_run_waiting_queues(p);
-  }
-  p->flags &= ~AHC_IN_ISR;
 }
 
 /*+F*************************************************************************
@@ -5089,15 +5232,54 @@
 do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
 {
   unsigned long cpu_flags;
+  struct aic7xxx_host *p;
+  static unsigned int re_entry_counter = 0;
+  
+  p = (struct aic7xxx_host *)dev_id;
+  if(!p)
+    return;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
-
+  if(test_and_set_bit(AHC_IN_ISR_BIT, &p->flags))
+  {
+    if(re_entry_counter++ > 100000UL)
+    {
+      /*
+       * Hmmm...we seem to be looping here.  This usually means that our
+       * interrupt routine got killed by a NULL pointer deref.  Panic.
+       */
+      sti();
+      panic("aic7xxx: The interrupt routine appears to have seg faulted.\n");
+    }
+    return;
+  }
+  re_entry_counter = 0;
   spin_lock_irqsave(&io_request_lock, cpu_flags);
   aic7xxx_isr(irq, dev_id, regs);
+  aic7xxx_done_cmds_complete(p);
+  aic7xxx_run_waiting_queues(p);
   spin_unlock_irqrestore(&io_request_lock, cpu_flags);
+  clear_bit(AHC_IN_ISR_BIT, &p->flags);
 #else
+  if(set_bit(AHC_IN_ISR_BIT, (int *)&p->flags))
+  {
+    if(re_entry_counter++ > 100000UL)
+    {
+      /*
+       * Hmmm...we seem to be looping here.  This usually means that our
+       * interrupt routine got killed by a NULL pointer deref.  Panic.
+       */
+      sti();
+      panic("aic7xxx: The interrupt routine appears to have seg faulted.\n");
+    }
+    return;
+  }
+  re_entry_counter = 0;
   DRIVER_LOCK
   aic7xxx_isr(irq, dev_id, regs);
   DRIVER_UNLOCK
+  aic7xxx_done_cmds_complete(p);
+  aic7xxx_run_waiting_queues(p);
+  clear_bit(AHC_IN_ISR_BIT, (int *)&p->flags);
 #endif
 }
 
@@ -5245,7 +5427,6 @@
   }
 }
 
-#if defined(__i386__) || defined(__alpha__)
 /*+F*************************************************************************
  * Function:
  *   aic7xxx_probe
@@ -5267,7 +5448,13 @@
  *
  *   The fourth byte's lowest bit seems to be an enabled/disabled
  *   flag (rest of the bits are reserved?).
+ *
+ * NOTE:  This function is only needed on Intel and Alpha platforms,
+ *   the other platforms we support don't have EISA/VLB busses.  So,
+ *   we #ifdef this entire function to avoid compiler warnings about
+ *   an unused function.
  *-F*************************************************************************/
+#if defined(__i386__) || defined(__alpha__)
 static ahc_type
 aic7xxx_probe(int slot, int base, ahc_flag_type *flags)
 {
@@ -5323,7 +5510,8 @@
 
   return (AHC_NONE);
 }
-#endif /* __i386__ || __alpha__ */
+#endif /* (__i386__) || (__alpha__) */
+
 
 /*+F*************************************************************************
  * Function:
@@ -5494,7 +5682,7 @@
   while ((wait > 0) && ((aic_inb(p, SEECTL) & SEERDY) == 0))
   {
     wait--;
-    udelay(1000);  /* 1 msec */
+    mdelay(1);  /* 1 msec */
   }
   if ((aic_inb(p, SEECTL) & SEERDY) == 0)
   {
@@ -6219,7 +6407,7 @@
       scsi_conf |= p->scsi_id_b;
       aic_outb(p, scsi_conf | (term) ? TERM_ENB : 0, SCSICONF + 1);
     }
-    if ((scsi_conf & RESET_SCSI) && (aic7xxx_no_reset == 0))
+    if (scsi_conf & RESET_SCSI)
     {
       /* Reset SCSI bus B. */
       if (aic7xxx_verbose & VERBOSE_PROBE)
@@ -6255,7 +6443,7 @@
   }
 
 
-  if ((scsi_conf & RESET_SCSI) && (aic7xxx_no_reset == 0))
+  if (scsi_conf & RESET_SCSI)
   {
     /* Reset SCSI bus A. */
     if (aic7xxx_verbose & VERBOSE_PROBE)
@@ -6513,7 +6701,7 @@
   wait = 1000;  /* 1 second (1000 * 1000 usec) */
   while ((wait > 0) && ((aic_inb(p, HCNTRL) & CHIPRSTACK) == 0))
   {
-    udelay(1000);  /* 1 msec = 1000 usec */
+    mdelay(1);  /* 1 msec = 1000 usec */
     wait = wait - 1;
   }
 
@@ -6647,24 +6835,23 @@
   {
     kfree(p->scb_data->scb_array[i]);
   }
-  /*
-   * Free the SCB data area.
-   */
-  kfree(p->scb_data);
 
   /*
-   * Free the instance of the device structure.
+   * Free any alloced Scsi_Cmnd structures that might be around for
+   * negotiation purposes....
    */
+  for (i = 0; i < MAX_TARGETS; i++)
+  {
+    if(p->dev_wdtr_cmnd[i])
+      kfree(p->dev_wdtr_cmnd[i]);
+    if(p->dev_sdtr_cmnd[i])
+      kfree(p->dev_sdtr_cmnd[i]);
+  }
 
   /*
-   * XXXXXXXX  FIXXXXXMEEEEEE.  How do we unmap the I/O range we have mapped
-   * if we are doing MMAPed I/O ??????????  Our biggest concern is the issue
-   * of possibly calling unmap on an area that *might* be used on another
-   * controller as well (aka, the 4096 byte MMAPed area is back to back
-   * with another controller, and the PAGE_SIZE is greater then 4096, allowing
-   * us to remap in a shared page).
+   * Free the SCB data area.
    */
-  scsi_unregister(p->host);
+  kfree(p->scb_data);
 }
 
 /*+F*************************************************************************
@@ -6945,7 +7132,13 @@
    */
   if(aic7xxx)
     aic7xxx_setup(aic7xxx, NULL);
-
+  if(dummy_buffer[0] != 'P')
+    printk(KERN_WARNING "aic7xxx: Please read the file /usr/src/linux/drivers"
+      "/scsi/README.aic7xxx\n"
+      "aic7xxx: to see the proper way to specify options to the aic7xxx "
+      "module\n"
+      "aic7xxx: Specifically, don't use any commas when passing arguments to\n"
+      "aic7xxx: insmod or else it might trash certain memory areas.\n");
 #endif
 
   template->proc_dir = &proc_scsi_aic7xxx;
@@ -7221,7 +7414,11 @@
   /*
    * PCI-bus probe.
    */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+  if (pci_present())
+#else
   if (pcibios_present())
+#endif
   {
     struct
     {
@@ -7266,7 +7463,7 @@
     };
 
     unsigned short command;
-    unsigned int  devconfig, i;
+    unsigned int  devconfig, i, oldverbose;
 #ifdef MMAPIO
     unsigned long page_offset, base;
 #endif
@@ -7276,7 +7473,7 @@
 #else
     int index;
     unsigned int piobase, mmapbase;
-    unsigned char pci_bus, pci_devfn;
+    unsigned char pci_bus, pci_devfn, pci_irq;
 #endif
 
     for (i = 0; i < NUMBER(aic7xxx_pci_devices); i++)
@@ -7315,19 +7512,49 @@
            */
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
           temp_p->irq = pdev->irq;
+          temp_p->pdev = pdev;
           temp_p->pci_bus = pdev->bus->number;
           temp_p->pci_device_fn = pdev->devfn;
           temp_p->base = pdev->base_address[0];
           temp_p->mbase = pdev->base_address[1];
           pci_read_config_word(pdev, PCI_COMMAND, &command);
-          pci_write_config_word(pdev, PCI_COMMAND,
-             command | PCI_COMMAND_MASTER |
-             PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+          if (aic7xxx_verbose & VERBOSE_PROBE2)
+          {
+            printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
+              (int)command);
+          }
+          command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
+            PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
+            PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+          if (aic7xxx_pci_parity == 0)
+            command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+          pci_write_config_word(pdev, PCI_COMMAND, command);
+          pci_read_config_dword(pdev, PCI_COMMAND, &devconfig);
+          if (aic7xxx_verbose & VERBOSE_PROBE2)
+          {
+            printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
+          }
+          devconfig |= 0x80000000;
+          if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
+          {
+            devconfig &= ~(0x00000008);
+          }
+          else
+          {
+            devconfig |= 0x00000008;
+          }
+          pci_write_config_dword(pdev, PCI_COMMAND, devconfig);
+          if (aic7xxx_verbose & VERBOSE_PROBE2)
+            printk("aic7xxx: <%s> at PCI %d/%d\n", 
+              board_names[aic7xxx_pci_devices[i].board_name_index],
+              PCI_SLOT(temp_p->pdev->devfn),
+              PCI_FUNC(temp_p->pdev->devfn));
 #else
           temp_p->pci_bus = pci_bus;
           temp_p->pci_device_fn = pci_devfn;
           pcibios_read_config_byte(pci_bus, pci_devfn, PCI_INTERRUPT_LINE,
-            &temp_p->irq);
+            &pci_irq);
+          temp_p->irq = pci_irq;
           pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0,
             &piobase);
           temp_p->base = piobase;
@@ -7335,16 +7562,38 @@
             &mmapbase);
           temp_p->mbase = mmapbase;
           pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command);
-          pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND,
-            command | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
-            PCI_COMMAND_IO);
-#endif
-
+          if (aic7xxx_verbose & VERBOSE_PROBE2)
+          {
+            printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
+              (int)command);
+          }
+          command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
+            PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
+            PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+          if (aic7xxx_pci_parity == 0)
+            command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+          pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, command);
+          pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, &devconfig);
+          if (aic7xxx_verbose & VERBOSE_PROBE2)
+          {
+            printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
+          }
+          devconfig |= 0x80000000;
+          if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
+          {
+            devconfig &= ~(0x00000008);
+          }
+          else
+          {
+            devconfig |= 0x00000008;
+          }
+          pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, devconfig);
           if (aic7xxx_verbose & VERBOSE_PROBE2)
             printk("aic7xxx: <%s> at PCI %d/%d\n", 
               board_names[aic7xxx_pci_devices[i].board_name_index],
               PCI_SLOT(temp_p->pci_device_fn),
               PCI_FUNC(temp_p->pci_device_fn));
+#endif
 
           /*
            * The first bit (LSB) of PCI_BASE_ADDRESS_0 is always set, so
@@ -7356,26 +7605,56 @@
           temp_p->pause = temp_p->unpause | PAUSE;
 
 #ifdef MMAPIO
-          base = temp_p->mbase & PAGE_MASK;
-          page_offset = temp_p->mbase - base;
-          /*
-           * replace the next line with this one if you are using 2.1.x:
-           * temp_p->maddr = ioremap(base, page_offset + 256);
-           */
+          if((temp_p->type & AHC_AIC7850) != AHC_AIC7850)
+          {
+            base = temp_p->mbase & PAGE_MASK;
+            page_offset = temp_p->mbase - base;
+            /*
+             * replace the next line with this one if you are using 2.1.x:
+             * temp_p->maddr = ioremap(base, page_offset + 256);
+             */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-          temp_p->maddr = ioremap(base, page_offset + 256);
+            temp_p->maddr = ioremap(base, page_offset + 256);
 #else
-          temp_p->maddr = vremap(base, page_offset + 256);
+            temp_p->maddr = vremap(base, page_offset + 256);
 #endif
-          if(temp_p->maddr)
+            if(temp_p->maddr)
+            {
+              temp_p->maddr += page_offset;
+            }
+          }
+          else
           {
-            temp_p->maddr += page_offset;
+#ifdef __i386__
+            /*
+             * Resort to PIO mode on these controllers and Intel hardware.
+             * For other hardware we need to either disable these controllers
+             * or do without MMAPed IO.  However, for PPC, we can't do
+             * MMAPed IO (according to what I've heard) so we may be forced
+             * to just fail detection on those cards.
+             */
+            temp_p->maddr = NULL;
+#else
+            kfree(temp_p);
+            temp_p = NULL;
+            continue;
+#endif /* __i386__ */
           }
 #endif
 
           aic_outb(temp_p, temp_p->pause, HCNTRL);
           while( (aic_inb(temp_p, HCNTRL) & PAUSE) == 0 ) ;
 
+          /*
+           * Clear out any pending PCI error status messages.  Also set
+           * verbose to 0 so that we don't emit strange PCI error messages
+           * while cleaning out the current status bits.
+           */
+          oldverbose = aic7xxx_verbose;
+          aic7xxx_verbose = 0;
+          aic7xxx_pci_intr(temp_p);
+          aic7xxx_verbose = oldverbose;
+
           temp_p->bios_address = 0;
 
           /*
@@ -7427,15 +7706,21 @@
 
             case AHC_AIC7895:
               temp_p->flags |= AHC_MULTI_CHANNEL;
-              if (PCI_FUNC(temp_p->pci_device_fn) != 0)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+              if (PCI_FUNC(temp_p->pdev->devfn) != 0)
               {
                 temp_p->flags |= AHC_CHNLB;
               }
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
               pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
+              devconfig = le32_to_cpu(devconfig);
               devconfig |= SCBSIZE32;
+              devconfig = cpu_to_le32(devconfig);
               pci_write_config_dword(pdev, DEVCONFIG, devconfig);
 #else
+              if (PCI_FUNC(temp_p->pci_device_fn) != 0)
+              {
+                temp_p->flags |= AHC_CHNLB;
+              }
               pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
                 &devconfig);
               devconfig |= SCBSIZE32;
@@ -7483,7 +7768,6 @@
             temp_p->flags |= AHC_USEDEFAULTS;
             if (sxfrctl1 & STPWEN)
               temp_p->flags |= AHC_TERM_ENB_A | AHC_TERM_ENB_B;
-            temp_p->scsi_id = temp_p->scsi_id_b = 7;
           }
 
           /*
@@ -7806,6 +8090,7 @@
         {
           found--;
           aic7xxx_free(p);
+          scsi_unregister(p->host);
         }
       }
       current_p = temp_p;
@@ -7824,6 +8109,7 @@
         {
           found--;
           aic7xxx_free(p);
+          scsi_unregister(p->host);
         }
       }
       current_p = temp_p;
@@ -7842,6 +8128,7 @@
         {
           found--;
           aic7xxx_free(p);
+          scsi_unregister(p->host);
         }
       }
       current_p = temp_p;
@@ -7854,6 +8141,89 @@
 
 /*+F*************************************************************************
  * Function:
+ *   aic7xxx_negotiation_complete
+ *
+ * Description:
+ *   Handle completion events for our Negotiation commands.  Clear out the
+ *   struct and get it ready for its next use.
+ *-F*************************************************************************/
+static void
+aic7xxx_negotiation_complete(Scsi_Cmnd *cmd)
+{
+  memset(&cmd->sense_buffer[0], 0, sizeof(cmd->sense_buffer));
+}
+
+/*+F*************************************************************************
+ * Function:
+ *   aic7xxx_build_negotiation_command
+ *
+ * Description:
+ *   Build a Scsi_Cmnd structure to perform negotiation with or else send
+ *   a pre-built command specifically for this purpose.
+ *-F*************************************************************************/
+static void
+aic7xxx_build_negotiation_cmnd(struct aic7xxx_host *p, Scsi_Cmnd *old_cmd,
+  int tindex)
+{
+
+  if ( (p->needwdtr & (1<<tindex)) && !(p->wdtr_pending & (1<<tindex)) )
+  {
+    if(p->dev_wdtr_cmnd[tindex] == NULL)
+    {
+      Scsi_Cmnd *cmd;
+
+      if (!(p->dev_wdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
+      {
+        return;
+      }
+      cmd = p->dev_wdtr_cmnd[tindex];
+      memset(cmd, 0, sizeof(Scsi_Cmnd));
+      memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
+      memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
+      memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
+      cmd->lun = 0;
+      cmd->request_bufflen = 0;
+      cmd->request_buffer = NULL;
+      cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
+      cmd->bufflen = 0;
+      cmd->buffer = NULL;
+      cmd->underflow = 0;
+      cmd->cmd_len = 6;
+    }
+    aic7xxx_queue(p->dev_wdtr_cmnd[tindex], 
+                  aic7xxx_negotiation_complete);
+  }
+  else if ( (p->needsdtr & (1<<tindex)) && !(p->sdtr_pending & (1<<tindex)) )
+  {
+    if(p->dev_sdtr_cmnd[tindex] == NULL)
+    {
+      Scsi_Cmnd *cmd;
+
+      if (!(p->dev_sdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
+      {
+        return;
+      }
+      cmd = p->dev_sdtr_cmnd[tindex];
+      memset(cmd, 0, sizeof(Scsi_Cmnd));
+      memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
+      memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
+      memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
+      cmd->lun = 0;
+      cmd->request_bufflen = 0;
+      cmd->request_buffer = NULL;
+      cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
+      cmd->bufflen = 0;
+      cmd->buffer = NULL;
+      cmd->underflow = 0;
+      cmd->cmd_len = 6;
+    }
+    aic7xxx_queue(p->dev_sdtr_cmnd[tindex], 
+                  aic7xxx_negotiation_complete);
+  }
+}
+
+/*+F*************************************************************************
+ * Function:
  *   aic7xxx_buildscb
  *
  * Description:
@@ -7903,27 +8273,37 @@
       }
     }
   }
-  if ( (p->needwdtr & mask) &&
-      !(p->wdtr_pending & mask) &&
-      !(scb->tag_action))
-  {
-    p->wdtr_pending |= mask;
-    hscb->control |= MK_MESSAGE;
-    if (p->needwdtr_copy & mask)
-      scb->flags |= SCB_MSGOUT_WDTR_16BIT;
-    else
-      scb->flags |= SCB_MSGOUT_WDTR_8BIT;
-  }
-  else
+  if (p->dev_flags[TARGET_INDEX(cmd)] & DEVICE_SCANNED)
   {
-    if ( (p->needsdtr & mask) &&
-        !(p->sdtr_pending & mask) &&
-        !(p->wdtr_pending & mask) &&
-        !(scb->tag_action) )
-    {
-      p->sdtr_pending |= mask;
-      hscb->control |= MK_MESSAGE;
-      scb->flags |= SCB_MSGOUT_SDTR;
+    if ( (p->needwdtr & mask) && !(p->wdtr_pending & mask) )
+    {
+      if (cmd == p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
+      {
+        p->wdtr_pending |= mask;
+        scb->flags |= SCB_MSGOUT_WDTR_16BIT;
+        hscb->control &= DISCENB;
+        hscb->control |= MK_MESSAGE;
+        scb->tag_action = 0;
+      }
+      else
+      {
+        aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));
+      }
+    }
+    if ( (p->needsdtr & mask) && !(p->sdtr_pending & mask) )
+    {
+      if (cmd == p->dev_sdtr_cmnd[TARGET_INDEX(cmd)])
+      {
+        p->sdtr_pending |= mask;
+        scb->flags |= SCB_MSGOUT_SDTR;
+        hscb->control &= DISCENB;
+        hscb->control |= MK_MESSAGE;
+        scb->tag_action = 0;
+      }
+      else if (cmd != p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
+      {
+        aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));
+      }
     }
   }
   hscb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
@@ -8033,7 +8413,7 @@
     }
   }
 
-  if (p->dev_active_cmds[tindex] > cmd->device->queue_depth)
+  if (p->dev_active_cmds[tindex] > (cmd->device->queue_depth + 1))
   {
     printk(WARN_LEAD "Commands queued exceeds queue "
            "depth, active=%d\n",
@@ -8070,7 +8450,7 @@
     aic7xxx_status(cmd) = 0;
     cmd->result = 0;
     cmd->host_scribble = NULL;
-    memset(&cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+    memset(&cmd->sense_buffer[0], 0, sizeof(cmd->sense_buffer));
 
     scb->flags |= SCB_ACTIVE | SCB_WAITINGQ;
 
@@ -8186,9 +8566,6 @@
     { 
       if ( (lastphase != P_MESGOUT) && (lastphase != P_MESGIN) )
       {
-        /* Send the abort message to the active SCB. */
-        aic_outb(p, MSG_BUS_DEV_RESET, MSG_OUT);
-        aic_outb(p, lastphase | ATNO, SCSISIGO);
         if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
           printk(INFO_LEAD "Device reset message in "
                 "message buffer\n", p->host_no, CTL_OF_SCB(scb));
@@ -8198,6 +8575,9 @@
                 ~DEVICE_SUCCESS;
         p->dev_flags[TARGET_INDEX(scb->cmd)] |= 
                 BUS_DEVICE_RESET_PENDING;
+        /* Send the abort message to the active SCB. */
+        aic_outb(p, HOST_MSG, MSG_OUT);
+        aic_outb(p, lastphase | ATNO, SCSISIGO);
         return(SCSI_RESET_PENDING);
       }
       else
@@ -8365,6 +8745,7 @@
   {
     aic7xxx_isr(p->irq, p, (void *)NULL);
     pause_sequencer(p);
+    aic7xxx_done_cmds_complete(p);
   }
 
   if ((scb == NULL) || (cmd->serial_number != cmd->serial_number_at_timeout))
@@ -8556,9 +8937,12 @@
         if ( prev_hscbptr == SCB_LIST_NULL )
         {
             aic_outb(p, aic_inb(p, SCB_NEXT), WAITING_SCBH);
-            aic_outb(p, 0, SCSISEQ);    /* stop the selection since we just
-                                         * grabbed the scb out from under the
-                                         * card */
+            /* stop the selection since we just
+             * grabbed the scb out from under the
+             * card
+             */
+            aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ);
+            aic_outb(p, CLRSELTIMEO, CLRSINT1);
         }
         else
         {
@@ -8693,6 +9077,7 @@
   {
     aic7xxx_isr(p->irq, p, (void *)NULL );
     pause_sequencer(p);
+    aic7xxx_done_cmds_complete(p);
   }
 
   if (scb == NULL)
@@ -8894,6 +9279,7 @@
         p->msg_index = 0;
         p->msg_len = 0;
       }
+      aic7xxx_run_done_queue(p, TRUE);
       p->flags &= ~AHC_IN_RESET;
       /*  We can't rely on run_waiting_queues to unpause the sequencer for
        *  PCI based controllers since we use AAP */
@@ -8941,6 +9327,52 @@
   geom[2] = cylinders;
 
   return (0);
+}
+
+/*+F*************************************************************************
+ * Function:
+ *   aic7xxx_release
+ *
+ * Description:
+ *   Free the passed in Scsi_Host memory structures prior to unloading the
+ *   module.
+ *-F*************************************************************************/
+int
+aic7xxx_release(struct Scsi_Host *host)
+{
+  struct aic7xxx_host *p = (struct aic7xxx_host *) host->hostdata;
+  struct aic7xxx_host *next, *prev;
+
+  if(p->irq)
+    free_irq(p->irq, p);
+  release_region(p->base, MAXREG - MINREG);
+  if(p->maddr)
+  {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+    vfree((void *) (((unsigned long) p->maddr) & PAGE_MASK));
+#else
+    iounmap((void *) (((unsigned long) p->maddr) & PAGE_MASK));
+#endif
+  }
+  prev = NULL;
+  next = first_aic7xxx;
+  while(next != NULL)
+  {
+    if(next == p)
+    {
+      if(prev == NULL)
+        first_aic7xxx = next->next;
+      else
+        prev->next = next->next;
+    }
+    else
+    {
+      prev = next;
+    }
+    next = next->next;
+  }
+  aic7xxx_free(p);
+  return(0);
 }
 
 #include "aic7xxx_proc.c"
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/aic7xxx.h linux/drivers/scsi/aic7xxx.h
--- v2.1.103/linux/drivers/scsi/aic7xxx.h	Tue Apr 14 14:29:21 1998
+++ linux/drivers/scsi/aic7xxx.h	Thu Jun  4 23:31:53 1998
@@ -51,7 +51,7 @@
 	proc_info: aic7xxx_proc_info,				\
 	name: NULL,						\
 	detect: aic7xxx_detect,					\
-	release: NULL,						\
+	release: aic7xxx_release,				\
 	info: aic7xxx_info,					\
 	command: NULL,						\
 	queuecommand: aic7xxx_queue,				\
@@ -81,7 +81,7 @@
 	proc_info: aic7xxx_proc_info,				\
 	name: NULL,						\
 	detect: aic7xxx_detect,					\
-	release: NULL,						\
+	release: aic7xxx_release,				\
 	info: aic7xxx_info,					\
 	command: NULL,						\
 	queuecommand: aic7xxx_queue,				\
@@ -105,6 +105,7 @@
 extern int aic7xxx_command(Scsi_Cmnd *);
 extern int aic7xxx_reset(Scsi_Cmnd *, unsigned int);
 extern int aic7xxx_abort(Scsi_Cmnd *);
+extern int aic7xxx_release(struct Scsi_Host *);
 
 extern const char *aic7xxx_info(struct Scsi_Host *);
 
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/aic7xxx_proc.c linux/drivers/scsi/aic7xxx_proc.c
--- v2.1.103/linux/drivers/scsi/aic7xxx_proc.c	Tue Apr 14 14:29:21 1998
+++ linux/drivers/scsi/aic7xxx_proc.c	Wed Jun  3 09:48:19 1998
@@ -243,8 +243,6 @@
             p->adapter_control);
   size += sprintf(BLS, "   Extended Translation: %sabled\n",
       (p->flags & AHC_EXTEND_TRANS_A) ? "En" : "Dis");
-  size += sprintf(BLS, "         SCSI Bus Reset: %sabled\n",
-      aic7xxx_no_reset ? "Dis" : "En");
   size += sprintf(BLS, "Disconnect Enable Flags: 0x%04x\n", p->discenable);
   if (p->type & AHC_ULTRA)
   {
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/aic7xxx_seq.h linux/drivers/scsi/aic7xxx_seq.h
--- v2.1.103/linux/drivers/scsi/aic7xxx_seq.h	Tue Apr 14 14:29:21 1998
+++ linux/drivers/scsi/aic7xxx_seq.h	Thu May 21 11:07:29 1998
@@ -496,12 +496,12 @@
 #define	SCB_PAGING      	0x8
 #define	TWIN_CHANNEL    	0x4
 #define	TARGET_MODE     	0x2
-struct patch {
+struct sequencer_patch {
 	int	options;
 	int	negative;
 	int	begin;
 	int	end;
-} patches[] = {
+} sequencer_patches[] = {
 	{ 0x00000002, 0, 0x001, 0x002 },
 	{ 0x00000002, 1, 0x002, 0x003 },
 	{ 0x00000004, 0, 0x009, 0x00d },
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c
--- v2.1.103/linux/drivers/scsi/atari_scsi.c	Thu Mar 26 15:57:03 1998
+++ linux/drivers/scsi/atari_scsi.c	Wed May 20 18:55:06 1998
@@ -340,7 +340,7 @@
 		}
 	}
 
-	/* If the DMA is active but not finished, we have the the case
+	/* If the DMA is active but not finished, we have the case
 	 * that some other 5380 interrupt occurred within the DMA transfer.
 	 * This means we have residual bytes, if the desired end address
 	 * is not yet reached. Maybe we have to fetch some bytes from the
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v2.1.103/linux/drivers/scsi/eata.c	Wed May 20 19:10:39 1998
+++ linux/drivers/scsi/eata.c	Thu Jun  4 11:00:37 1998
@@ -1,6 +1,10 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104
+ *          Increased busy timeout from 10 msec. to 200 msec. while
+ *          processing interrupts.
+ *
  *      16 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102
  *          Improved abort handling during the eh recovery process.
  *
@@ -9,7 +13,7 @@
  *          abort and reset routines.
  *          Added command line options (eh:[y|n]) to choose between
  *          new_eh_code and the old scsi code.
- *          If linux verion >= 2.1.101 the default is eh:y, while the eh
+ *          If linux version >= 2.1.101 the default is eh:y, while the eh
  *          option is ignored for previous releases and the old scsi code
  *          is used.
  *
@@ -2020,7 +2024,7 @@
                         HD(j)->iocount);
 
    /* Check if this board is still busy */
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
+   if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) {
       reg = inb(sh[j]->io_port + REG_STATUS);
       printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
              BN(j), irq, reg, HD(j)->iocount);
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h
--- v2.1.103/linux/drivers/scsi/eata.h	Wed May 20 19:10:39 1998
+++ linux/drivers/scsi/eata.h	Thu Jun  4 23:31:53 1998
@@ -15,7 +15,7 @@
 int eata2x_reset(Scsi_Cmnd *);
 int eata2x_old_reset(Scsi_Cmnd *, unsigned int);
 
-#define EATA_VERSION "4.31.00"
+#define EATA_VERSION "4.32.00"
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/esp.c linux/drivers/scsi/esp.c
--- v2.1.103/linux/drivers/scsi/esp.c	Fri May  8 23:14:49 1998
+++ linux/drivers/scsi/esp.c	Wed May 20 18:55:06 1998
@@ -1446,7 +1446,7 @@
 		}
 
 		/* We've talked to this guy before,
-		 * but never negotiated.. lets try,
+		 * but never negotiated.  Let's try,
 		 * need to attempt WIDE first, before
 		 * sync nego, as per SCSI 2 standard.
 		 */
@@ -3100,7 +3100,7 @@
 			       esp->esp_id, SCptr->target, SCptr->lun);
 			SDptr->sync_max_offset = 0;
 			SDptr->sync_min_period = 0;
-			SDptr->sync = 1; /* so we dont negotiate again */
+			SDptr->sync = 1; /* so we don't negotiate again */
 
 			/* Run the command again, this time though we
 			 * won't try to negotiate for synchronous transfers.
@@ -3215,7 +3215,7 @@
 	switch(esp->cur_msgin[0]) {
 	default:
 		/* We don't want to hear about it. */
-		ESPLOG(("esp%d: msg %02x which we dont know about\n", esp->esp_id,
+		ESPLOG(("esp%d: msg %02x which we don't know about\n", esp->esp_id,
 			esp->cur_msgin[0]));
 		return MESSAGE_REJECT;
 
@@ -3451,7 +3451,7 @@
 			       esp->esp_id, size);
 			message_out = MESSAGE_REJECT;
 		} else {
-			/* Things look good, lets see what we got. */
+			/* Things look good; let's see what we got. */
 			if(size == 16) {
 				/* Set config 3 register for this target. */
 				printk("esp%d: 16 byte WIDE transfers enabled for target %d.\n",
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v2.1.103/linux/drivers/scsi/fdomain.c	Wed May 20 19:10:39 1998
+++ linux/drivers/scsi/fdomain.c	Thu Jun  4 15:52:21 1998
@@ -1,6 +1,6 @@
 /* fdomain.c -- Future Domain TMC-16x0 SCSI driver
  * Created: Sun May  3 18:53:19 1992 by faith@cs.unc.edu
- * Revised: Wed Oct  2 11:10:55 1996 by r.faith@ieee.org
+ * Revised: Wed Oct  2 11:10:55 1996 by faith@acm.org
  * Author: Rickard E. Faith, faith@cs.unc.edu
  * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith
  *
@@ -956,14 +956,14 @@
 	 if (retcode == -EINVAL) {
 	    printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
 	    printk( "         This shouldn't happen!\n" );
-	    printk( "         Send mail to faith@cs.unc.edu\n" );
+	    printk( "         Send mail to faith@acm.org\n" );
 	 } else if (retcode == -EBUSY) {
 	    printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
 	    printk( "         Please use another IRQ!\n" );
 	 } else {
 	    printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
 	    printk( "         This shouldn't happen!\n" );
-	    printk( "         Send mail to faith@cs.unc.edu\n" );
+	    printk( "         Send mail to faith@acm.org\n" );
 	 }
 	 panic( "fdomain: Driver requires interruptions\n" );
       }
@@ -1107,7 +1107,7 @@
       status = inb( TMC_Status_port );        /* Read adapter status */
       if (status & 0x02)		      /* Arbitration complete */
 	    return 0;
-      udelay(1000);			/* Wait one millisecond */
+      mdelay(1);			/* Wait one millisecond */
    } while (--timeout);
 
    /* Make bus idle */
@@ -1145,7 +1145,7 @@
 	 outb( 0x80, SCSI_Cntl_port );
 	 return 0;
       }
-      udelay(1000);			/* wait one msec */
+      mdelay(1);			/* wait one msec */
    } while (--timeout);
    /* Make bus idle */
    fdomain_make_bus_idle();
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/fdomain.h linux/drivers/scsi/fdomain.h
--- v2.1.103/linux/drivers/scsi/fdomain.h	Sun Dec 21 17:04:49 1997
+++ linux/drivers/scsi/fdomain.h	Thu Jun  4 15:52:21 1998
@@ -1,6 +1,6 @@
 /* fdomain.h -- Header for Future Domain TMC-16x0 driver
  * Created: Sun May  3 18:47:33 1992 by faith@cs.unc.edu
- * Revised: Thu Oct 12 13:21:35 1995 by r.faith@ieee.org
+ * Revised: Thu Oct 12 13:21:35 1995 by faith@acm.org
  * Author: Rickard E. Faith, faith@cs.unc.edu
  * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith
  *
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- v2.1.103/linux/drivers/scsi/g_NCR5380.c	Thu May 14 19:47:41 1998
+++ linux/drivers/scsi/g_NCR5380.c	Thu May 21 13:45:02 1998
@@ -645,7 +645,7 @@
 #else
     PRINTP("NO NCR53C400 driver extensions\n");
 #endif
-    PRINTP("Using %s mapping at %s 0x%x, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
+    PRINTP("Using %s mapping at %s 0x%lx, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
     if (scsi_ptr->irq == IRQ_NONE)
 	PRINTP("no interrupt\n");
     else
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- v2.1.103/linux/drivers/scsi/gdth.c	Thu May 14 19:47:41 1998
+++ linux/drivers/scsi/gdth.c	Thu May 21 14:24:08 1998
@@ -170,7 +170,7 @@
 static unchar   DebugState = DEBUG_GDTH;
 extern int sys_syslog(int,char*,int);
 #define LOGEN           sys_syslog(7,NULL,0);
-#define WAITSEC(a)      {ulong idx; for(idx=0;idx<a*1000L;++idx) udelay(1000);}
+#define WAITSEC(a)      mdelay((a)*1000)
 
 #ifdef SLOWMOTION_GDTH
 #define SLOWM   WAITSEC(2)  
@@ -542,7 +542,7 @@
             printk("GDT-EISA: Initialization error (DEINIT failed)\n");
             return 0;
         }
-        udelay(1000);
+        mdelay(1);
         TRACE2(("wait for DEINIT: retries=%ld\n",retries));
     }
     prot_ver = inb(eisa_adr+MAILBOXREG);
@@ -572,7 +572,7 @@
                 printk("GDT-EISA: Initialization error (get IRQ failed)\n");
                 return 0;
             }
-            udelay(1000);
+            mdelay(1);
         }
         ha->irq = inb(eisa_adr+MAILBOXREG);
         outb(0xff,eisa_adr+EDOORREG);
@@ -663,7 +663,7 @@
 	    gdth_munmap(ha->brd);
             return 0;
         }
-        udelay(1000);
+        mdelay(1);
     }
     prot_ver = (unchar)readl(&dp2_ptr->u.ic.S_Info[0]);
     writeb(0, &dp2_ptr->u.ic.Status);
@@ -694,7 +694,7 @@
 	    gdth_munmap(ha->brd);
             return 0;
         }
-        udelay(1000);
+        mdelay(1);
     }
     writeb(0, &dp2_ptr->u.ic.Status);
     writeb(0xff, &dp2_ptr->io.irqdel);
@@ -749,7 +749,7 @@
 		gdth_munmap(ha->brd);
                 return 0;
             }
-            udelay(1000);
+            mdelay(1);
         }
         prot_ver = (unchar)readl(&dp6_ptr->u.ic.S_Info[0]);
         writeb(0, &dp6_ptr->u.ic.S_Status);
@@ -778,7 +778,7 @@
 		gdth_munmap(ha->brd);
                 return 0;
             }
-            udelay(1000);
+            mdelay(1);
         }
         writeb(0, &dp6_ptr->u.ic.S_Status);
         writeb(0xff, &dp6_ptr->io.irqdel);
@@ -822,7 +822,7 @@
 		gdth_munmap(ha->brd);
                 return 0;
             }
-            udelay(1000);
+            mdelay(1);
         }
         prot_ver = (unchar)readl(&dp6c_ptr->u.ic.S_Info[0]);
         writeb(0, &dp6c_ptr->u.ic.Status);
@@ -852,7 +852,7 @@
 		gdth_munmap(ha->brd);
                 return 0;
             }
-            udelay(1000);
+            mdelay(1);
         }
         writeb(0, &dp6c_ptr->u.ic.S_Status);
 
@@ -891,7 +891,7 @@
 		gdth_munmap(ha->brd);
                 return 0;
             }
-            udelay(1000);
+            mdelay(1);
         }
         prot_ver = (unchar)readl(&dp6m_ptr->u.ic.S_Info[0]);
         writeb(0, &dp6m_ptr->u.ic.S_Status);
@@ -919,7 +919,7 @@
 		gdth_munmap(ha->brd);
                 return 0;
             }
-            udelay(1000);
+            mdelay(1);
         }
         writeb(0, &dp6m_ptr->u.ic.S_Status);
     }
@@ -1186,7 +1186,7 @@
             answer_found = TRUE;
             break;
         }
-        udelay(1000);
+        mdelay(1);
     } while (--time);
     gdth_from_wait = FALSE;
     
@@ -1249,7 +1249,7 @@
         }
         if (ha->status != S_BSY || --retries == 0)
             break;
-        udelay(1000);   
+        mdelay(1);   
     }   
     
     return (ha->status != S_OK ? 0:1);
@@ -1541,7 +1541,7 @@
                         return;
                     }
                     while (gdth_test_busy(hanum))
-                        udelay(1000);
+                        mdelay(1);
                 }
                 firsttime = FALSE;
             }
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v2.1.103/linux/drivers/scsi/hosts.c	Wed May 20 19:10:39 1998
+++ linux/drivers/scsi/hosts.c	Wed May 20 18:55:07 1998
@@ -546,7 +546,7 @@
 }
 
 /*
- * Why is this a seperate function?  Because the kernel_thread code
+ * Why is this a separate function?  Because the kernel_thread code
  * effectively does a fork, and there is a builtin exit() call when
  * the child returns.   The difficulty is that scsi_init() is
  * marked __initfunc(), which means the memory is unmapped after bootup
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/ibmmca.c linux/drivers/scsi/ibmmca.c
--- v2.1.103/linux/drivers/scsi/ibmmca.c	Thu May 14 19:47:41 1998
+++ linux/drivers/scsi/ibmmca.c	Thu May 21 14:24:08 1998
@@ -1042,7 +1042,7 @@
   int len = 0;
 
   len += sprintf (buf + len, "Subsystem PUN: %d\n", subsystem_pun);
-  len += sprintf (buf + len, "I/O base address: 0x%x\n", IM_CMD_REG);
+  len += sprintf (buf + len, "I/O base address: 0x%lx\n", IM_CMD_REG);
   return len;
 }
 
@@ -1269,7 +1269,7 @@
 		    issue_cmd (shpnt, IM_RESET_IMM_CMD, IM_IMM_CMD | ldn);
 		    while (reset_status == IM_RESET_IN_PROGRESS && --ticks) 
 		      {
-			udelay(1000000/HZ);
+			mdelay(1+999/HZ);
 			barrier();
 		      }
 		    /* if reset did not complete, just claim */
@@ -2072,7 +2072,7 @@
   reset_status = IM_RESET_IN_PROGRESS;
   issue_cmd (shpnt, IM_RESET_IMM_CMD, IM_IMM_CMD | 0xf);
   while (reset_status == IM_RESET_IN_PROGRESS && --ticks) {
-    udelay(1000000/HZ);
+    mdelay(1+999/HZ);
     barrier();
   }
   /* if reset did not complete, just return an error*/
@@ -2205,7 +2205,7 @@
 #endif
    len += sprintf(buffer+len, "               This Hostnumber..........: %d\n",
 		  hostno);
-   len += sprintf(buffer+len, "               Base I/O-Port............: 0x%x\n",
+   len += sprintf(buffer+len, "               Base I/O-Port............: 0x%lx\n",
 		  IM_CMD_REG);
    len += sprintf(buffer+len, "               (Shared) IRQ.............: %d\n",
 		  IM_IRQ);
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- v2.1.103/linux/drivers/scsi/ncr53c8xx.c	Fri May  8 23:14:50 1998
+++ linux/drivers/scsi/ncr53c8xx.c	Thu May 21 14:24:08 1998
@@ -369,8 +369,8 @@
 
 static void DELAY(long us)
 {
-	for (;us>1000;us-=1000) udelay(1000);
-	if (us) udelay(us);
+	if (us/1000) mdelay(us/1000);
+	if (us%1000) udelay(us%1000);
 }
 
 /*
@@ -1874,7 +1874,7 @@
 **	we reach them (for forward jumps).
 **	Therefore we declare a struct here.
 **	If you make changes inside the script,
-**	DONT FORGET TO CHANGE THE LENGTHS HERE!
+**	DON'T FORGET TO CHANGE THE LENGTHS HERE!
 **
 **----------------------------------------------------------
 */
@@ -3782,7 +3782,7 @@
 		case 0x8:
 			/*
 			**	JUMP / CALL
-			**	dont't relocate if relative :-)
+			**	don't relocate if relative :-)
 			*/
 			if (opcode & 0x00800000)
 				relocs = 0;
@@ -6249,7 +6249,7 @@
 	/*
 	**	Why not to try the immediate lower divisor and to choose 
 	**	the one that allows the fastest output speed ?
-	**	We dont want input speed too much greater than output speed.
+	**	We don't want input speed too much greater than output speed.
 	*/
 	if (div >= 1 && fak < 8) {
 		u_long fak2, per2;
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
--- v2.1.103/linux/drivers/scsi/ppa.c	Wed May 20 19:10:39 1998
+++ linux/drivers/scsi/ppa.c	Thu May 21 14:24:08 1998
@@ -798,10 +798,10 @@
 	w_ctr(ppb, 0x08);
 	udelay(30);
 	w_ctr(ppb, 0x0c);
-	udelay(1000);		/* Allow devices to settle down */
+	mdelay(1);		/* Allow devices to settle down */
     }
     ppa_disconnect(host_no);
-    udelay(1000);		/* Another delay to allow devices to settle */
+    mdelay(1);		/* Another delay to allow devices to settle */
 
     if (!retv)
 	retv = device_check(host_no);
@@ -1139,7 +1139,7 @@
 }
 
 /*
- * Apparently the the disk->capacity attribute is off by 1 sector 
+ * Apparently the disk->capacity attribute is off by 1 sector 
  * for all disk drives.  We add the one here, but it should really
  * be done in sd.c.  Even if it gets fixed there, this will still
  * work.
@@ -1200,9 +1200,9 @@
     w_ctr(ppb, 0x8);
     udelay(30);
     w_ctr(ppb, 0xc);
-    udelay(1000);		/* delay for devices to settle down */
+    mdelay(1);		/* delay for devices to settle down */
     ppa_disconnect(host_no);
-    udelay(1000);		/* Additional delay to allow devices to settle down */
+    mdelay(1);		/* Additional delay to allow devices to settle down */
 
     /*
      * PHASE2:
@@ -1264,9 +1264,9 @@
 	    w_ctr(ppb, 0x08);
 	    udelay(30);
 	    w_ctr(ppb, 0x0c);
-	    udelay(1000);
+	    mdelay(1);
 	    ppa_disconnect(host_no);
-	    udelay(1000);
+	    mdelay(1);
 	    if (ppa_hosts[host_no].mode == PPA_EPP_32) {
 		ppa_hosts[host_no].mode = old_mode;
 		goto second_pass;
@@ -1291,9 +1291,9 @@
 	    w_ctr(ppb, 0x08);
 	    udelay(30);
 	    w_ctr(ppb, 0x0c);
-	    udelay(1000);
+	    mdelay(1);
 	    ppa_disconnect(host_no);
-	    udelay(1000);
+	    mdelay(1);
 	    if (ppa_hosts[host_no].mode == PPA_EPP_32) {
 		ppa_hosts[host_no].mode = old_mode;
 		goto second_pass;
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c
--- v2.1.103/linux/drivers/scsi/qlogicpti.c	Fri May  8 23:14:50 1998
+++ linux/drivers/scsi/qlogicpti.c	Thu May 21 14:24:08 1998
@@ -382,7 +382,7 @@
 	}
 
 	qregs->hcctrl = HCCTRL_RESET;
-	udelay(1000);
+	mdelay(1);
 
 	qregs->sbus_ctrl = (SBUS_CTRL_GENAB | SBUS_CTRL_ERIRQ);
 	set_sbus_cfg1(qregs, qpti->bursts);
@@ -456,7 +456,7 @@
 
 	/* Reset the ISP again. */
 	qregs->hcctrl = HCCTRL_RESET;
-	udelay(1000);
+	mdelay(1);
 
 	qlogicpti_enable_irqs(qregs);
 	qregs->sbus_semaphore = 0;
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.1.103/linux/drivers/scsi/scsi.c	Wed May 20 19:10:40 1998
+++ linux/drivers/scsi/scsi.c	Thu May 21 14:24:08 1998
@@ -1313,7 +1313,7 @@
 	 * host).
 	 */
 	spin_unlock_irq(&io_request_lock);
-	while (--ticks_remaining >= 0) udelay(1000000/HZ);
+	while (--ticks_remaining >= 0) mdelay(1+999/HZ);
 	host->last_reset = jiffies - MIN_RESET_DELAY;
 	spin_lock_irq(&io_request_lock);
     }
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- v2.1.103/linux/drivers/scsi/scsi_ioctl.c	Thu May  7 22:51:51 1998
+++ linux/drivers/scsi/scsi_ioctl.c	Thu Jun  4 11:00:37 1998
@@ -6,6 +6,7 @@
 #include <asm/system.h>
 #include <asm/page.h>
 
+#include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -107,15 +108,17 @@
     Scsi_Cmnd * SCpnt;
     Scsi_Device * SDpnt;
 
+    spin_lock_irqsave(&io_request_lock, flags);
+
     SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0]));
     SCpnt = scsi_allocate_device(NULL, dev, 1);
     {
 	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,  timeout, retries);
 	spin_unlock_irqrestore(&io_request_lock, flags);
 	down(&sem);
+        spin_lock_irqsave(&io_request_lock, flags);
         SCpnt->request.sem = NULL;
     }
     
@@ -163,6 +166,7 @@
 	(*SDpnt->scsi_request_fn)();
 
     wake_up(&SDpnt->device_wait);
+    spin_unlock_irqrestore(&io_request_lock, flags);
     return result;
 }
 
@@ -276,13 +280,14 @@
       }
 
 #ifndef DEBUG_NO_CMD
+
+    spin_lock_irqsave(&io_request_lock, flags);
     
     SCpnt = scsi_allocate_device(NULL, dev, 1);
 
     {
 	struct semaphore sem = MUTEX_LOCKED;
 	SCpnt->request.sem = &sem;
-	spin_lock_irqsave(&io_request_lock, flags);
 	scsi_do_cmd(SCpnt,  cmd,  buf, needed,  scsi_ioctl_done,
 		    timeout, retries);
 	spin_unlock_irqrestore(&io_request_lock, flags);
@@ -308,6 +313,8 @@
     }
     result = SCpnt->result;
 
+    spin_lock_irqsave(&io_request_lock, flags);
+
     wake_up(&SCpnt->device->device_wait);
     SDpnt = SCpnt->device;
     scsi_release_command(SCpnt);
@@ -318,6 +325,7 @@
     if(SDpnt->scsi_request_fn)
 	(*SDpnt->scsi_request_fn)();
     
+    spin_unlock_irqrestore(&io_request_lock, flags);
     return result;
 #else
     {
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/scsi_queue.c linux/drivers/scsi/scsi_queue.c
--- v2.1.103/linux/drivers/scsi/scsi_queue.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/scsi/scsi_queue.c	Wed May 20 18:55:07 1998
@@ -58,7 +58,7 @@
 
 /*
  * Lock used to prevent more than one process from frobbing the list at the
- * same time.  FIXME(eric) - there should be seperate spinlocks for each host.
+ * same time.  FIXME(eric) - there should be separate spinlocks for each host.
  * This will reduce contention.
  */
 spinlock_t	scsi_mlqueue_lock        = SPIN_LOCK_UNLOCKED;
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/scsiiom.c linux/drivers/scsi/scsiiom.c
--- v2.1.103/linux/drivers/scsi/scsiiom.c	Thu May 14 19:47:41 1998
+++ linux/drivers/scsi/scsiiom.c	Thu May 21 14:24:09 1998
@@ -1428,7 +1428,7 @@
 #endif
 
     /* delay a second */
-    { unsigned int msec = 1*1000; while (--msec) udelay(1000); }
+    mdelay(1000);
 
     save_flags(flags);
     cli();
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/tmscsim.c linux/drivers/scsi/tmscsim.c
--- v2.1.103/linux/drivers/scsi/tmscsim.c	Tue Apr 14 14:29:24 1998
+++ linux/drivers/scsi/tmscsim.c	Thu May 21 14:24:09 1998
@@ -921,7 +921,7 @@
     outb(bval,ioport+CtrlReg1);  /* disable interrupt */
     DC390_ResetSCSIBus( pACB );
     for( i=0; i<500; i++ )
-	udelay(1000);
+	mdelay(1);
     bval = inb(ioport+CtrlReg1);
     bval &= ~DIS_INT_ON_SCSI_RST;
     outb(bval,ioport+CtrlReg1); /* re-enable interrupt */
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v2.1.103/linux/drivers/scsi/u14-34f.c	Wed May 20 19:10:40 1998
+++ linux/drivers/scsi/u14-34f.c	Thu Jun  4 11:00:37 1998
@@ -1,6 +1,10 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104
+ *          Increased busy timeout from 10 msec. to 200 msec. while
+ *          processing interrupts.
+ *
  *      18 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102
  *          Improved abort handling during the eh recovery process.
  *
@@ -9,7 +13,7 @@
  *          abort and reset routines.
  *          Added command line options (eh:[y|n]) to choose between
  *          new_eh_code and the old scsi code.
- *          If linux verion >= 2.1.101 the default is eh:y, while the eh
+ *          If linux version >= 2.1.101 the default is eh:y, while the eh
  *          option is ignored for previous releases and the old scsi code
  *          is used.
  *
@@ -1733,7 +1737,7 @@
                         HD(j)->iocount);
 
    /* Check if this board is still busy */
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
+   if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) {
       outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
       printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
              BN(j), irq, reg, HD(j)->iocount);
diff -u --recursive --new-file v2.1.103/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h
--- v2.1.103/linux/drivers/scsi/u14-34f.h	Wed May 20 19:10:40 1998
+++ linux/drivers/scsi/u14-34f.h	Thu Jun  4 23:31:53 1998
@@ -15,7 +15,7 @@
 int u14_34f_old_reset(Scsi_Cmnd *, unsigned int);
 int u14_34f_biosparam(Disk *, kdev_t, int *);
 
-#define U14_34F_VERSION "4.31.00"
+#define U14_34F_VERSION "4.32.00"
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.1.103/linux/drivers/sound/Config.in	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/Config.in	Thu May 21 13:45:02 1998
@@ -180,7 +180,7 @@
 
 mainmenu_option next_comment
 comment 'Additional low level sound drivers'
-dep_tristate 'Additional low level sound drivers' CONFIG_LOWLEVEL_SOUND $CONFIG_SOUND
+bool 'Additional low level sound drivers' CONFIG_LOWLEVEL_SOUND $CONFIG_SOUND
 if [ "$CONFIG_LOWLEVEL_SOUND" != "n" ]; then
     source drivers/sound/lowlevel/Config.in
 fi
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/Readme.cards linux/drivers/sound/Readme.cards
--- v2.1.103/linux/drivers/sound/Readme.cards	Tue Feb 17 13:12:47 1998
+++ linux/drivers/sound/Readme.cards	Wed May 20 18:55:07 1998
@@ -860,7 +860,7 @@
 DMA numbers. Using the same values than with DOS/Win is a good idea. Don't
 attempt to use the same IRQ or DMA channels twice.
 
-The SB mode of ATP is implemented so the the ATP driver just enables SB
+The SB mode of ATP is implemented so the ATP driver just enables SB
 in the proper address. The SB driver handles the rest. You have to configure
 both the SB driver and the SB mode of ATP to use the same IRQ, DMA and I/O
 settings.
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/Readme.linux linux/drivers/sound/Readme.linux
--- v2.1.103/linux/drivers/sound/Readme.linux	Tue Dec  9 09:49:59 1997
+++ linux/drivers/sound/Readme.linux	Wed May 20 18:55:07 1998
@@ -28,7 +28,7 @@
   sound support during "make config"). Please refer to kernel documentation
   for instructions about configuring and compiling kernel. File Readme.cards
   contains card specific instructions for configuring this driver for
-  use with various soundcards.
+  use with various sound cards.
 
 Boot time configuration (using lilo and insmod) 
 -----------------------------------------------
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/Readme.modules linux/drivers/sound/Readme.modules
--- v2.1.103/linux/drivers/sound/Readme.modules	Tue Feb 17 13:12:47 1998
+++ linux/drivers/sound/Readme.modules	Wed May 20 18:55:07 1998
@@ -31,7 +31,7 @@
 alias char-major-14 sb
 post-install sb modprobe  "-k" "adlib_card"
 options sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330
-options adlib_card io=0x388     # FM synthetiser
+options adlib_card io=0x388     # FM synthesizer
 
   The effect of this is that the sound driver and all necessary bits and
 pieces autoload on demand, assuming you use kerneld (a sound choice) and
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.1.103/linux/drivers/sound/ad1848.c	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/ad1848.c	Wed May 20 18:55:07 1998
@@ -1492,7 +1492,7 @@
 	}
 
 	/*
-	 * The indirect register I12 has some read only bits. Lets
+	 * The indirect register I12 has some read only bits. Let's
 	 * try to change them.
 	 */
 
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v2.1.103/linux/drivers/sound/dev_table.h	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/dev_table.h	Wed May 20 18:55:07 1998
@@ -229,7 +229,7 @@
 
 	/* fields formerly in audio.c */
 	int audio_mode;
-	/* why dont we use file->f_flags & O_NONBLOCK for the following? - ts */
+	/* why don't we use file->f_flags & O_NONBLOCK for the following? - ts */
 	int dev_nblock;	/* 1 if in nonblocking mode */
 
 #define		AM_NONE		0
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
--- v2.1.103/linux/drivers/sound/gus_wave.c	Wed May 20 19:10:40 1998
+++ linux/drivers/sound/gus_wave.c	Thu May 21 13:45:02 1998
@@ -384,7 +384,7 @@
 	gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
 	gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
 		    + (frac << 5));
-	/* Could writing twice fix problems with GUS_VOICE_POS() ? Lets try... */
+	/* Could writing twice fix problems with GUS_VOICE_POS()? Let's try. */
 	gus_delay();
 	gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
 	gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
@@ -500,12 +500,13 @@
 	int sample_no;
 
 	if ((sample_no = sample_map[voice]) != -1) {
-		if (position < samples[sample_no].len)
+		if (position < samples[sample_no].len) {
 			if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
 				voices[voice].offset_pending = position;
 			else
 				gus_write_addr(0x0a, sample_ptrs[sample_no] + position, 0,
 				 samples[sample_no].mode & WAVE_16_BITS);
+		}
 	}
 }
 
diff -u --recursive --new-file v2.1.103/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- v2.1.103/linux/drivers/sound/sb_common.c	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/sb_common.c	Thu May 21 14:24:09 1998
@@ -940,7 +940,7 @@
 			free_irq(devc->irq, devc);
 			sound_unload_mixerdev(devc->my_mixerdev);
 			/* We don't have to do this bit any more the UART401 is its own
-				master  -- Krzystof Halasa */
+				master  -- Krzysztof Halasa */
 			/* sound_unload_mididev(devc->my_mididev); */
 			sound_unload_audiodev(devc->my_dev);
 		}
@@ -1039,7 +1039,7 @@
 	outb((control | 3), mpu_base + 7);	/* Set last two bits to 1 (?) */
 	outb(((control & 0xfe) | 2), mpu_base + 7);	/* xxxxxxx0 resets the mc */
 
-	udelay(3000);	/* Wait at least 1ms */
+	mdelay(3);	/* Wait at least 1ms */
 
 	outb((control & 0xfc), mpu_base + 7);	/* xxxxxx00 enables RAM */
 
diff -u --recursive --new-file v2.1.103/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.1.103/linux/drivers/video/atyfb.c	Thu Mar 26 15:57:04 1998
+++ linux/drivers/video/atyfb.c	Wed May 20 18:55:08 1998
@@ -206,11 +206,11 @@
 typedef struct aty_regvals {
     int offset[3];		/* first pixel address */
 
-    int crtc_h_sync_strt_wid[3];	/* depth dependant */
+    int crtc_h_sync_strt_wid[3];	/* depth dependent */
     int crtc_gen_cntl[3];
     int mem_cntl[3];
 
-    int crtc_h_tot_disp;	/* mode dependant */
+    int crtc_h_tot_disp;	/* mode dependent */
     int crtc_v_tot_disp;
     int crtc_v_sync_strt_wid;
     int crtc_off_pitch;
diff -u --recursive --new-file v2.1.103/linux/drivers/video/fbcon-iplan2p2.c linux/drivers/video/fbcon-iplan2p2.c
--- v2.1.103/linux/drivers/video/fbcon-iplan2p2.c	Thu Mar 26 15:57:04 1998
+++ linux/drivers/video/fbcon-iplan2p2.c	Wed May 20 18:55:08 1998
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/video/iplan2p2.c -- Low level frame buffer operations for
- *				      interleaved bitplanes à la Atari (2
- *				      planes, 2 bytes interleave)
+ *  linux/drivers/video/fbcon-iplan2p2.c -- Low level frame buffer operations
+ *				  for interleaved bitplanes à la Atari (2
+ *				  planes, 2 bytes interleave)
  *
  *	Created 5 Apr 1997 by Geert Uytterhoeven
  *
@@ -52,7 +52,7 @@
 }
 
 /* Sets the bytes in the visible column at d, height h, to the value
- * val for a 2 plane screen. The the bis of the color in 'color' are
+ * val for a 2 plane screen. The bits of the color in 'color' are
  * moved (8 times) to the respective bytes. This means:
  *
  * for(h times; d += bpr)
diff -u --recursive --new-file v2.1.103/linux/drivers/video/fbcon-iplan2p4.c linux/drivers/video/fbcon-iplan2p4.c
--- v2.1.103/linux/drivers/video/fbcon-iplan2p4.c	Thu Mar 26 15:57:04 1998
+++ linux/drivers/video/fbcon-iplan2p4.c	Wed May 20 18:55:08 1998
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/video/iplan2p4.c -- Low level frame buffer operations for
- *				      interleaved bitplanes à la Atari (4
- *				      planes, 2 bytes interleave)
+ *  linux/drivers/video/fbcon-iplan2p4.c -- Low level frame buffer operations
+ *				   for interleaved bitplanes à la Atari (4
+ *				   planes, 2 bytes interleave)
  *
  *	Created 5 Apr 1997 by Geert Uytterhoeven
  *
@@ -46,7 +46,7 @@
 }
 
 /* Sets the bytes in the visible column at d, height h, to the value
- * val for a 4 plane screen. The the bis of the color in 'color' are
+ * val for a 4 plane screen. The bits of the color in 'color' are
  * moved (8 times) to the respective bytes. This means:
  *
  * for(h times; d += bpr)
diff -u --recursive --new-file v2.1.103/linux/drivers/video/macfb.c linux/drivers/video/macfb.c
--- v2.1.103/linux/drivers/video/macfb.c	Thu Mar 26 15:57:04 1998
+++ linux/drivers/video/macfb.c	Wed May 20 18:55:08 1998
@@ -372,7 +372,7 @@
 {
 	if(nt->category==NUBUS_CAT_DISPLAY)
 		return 0;
-	/* Claim all video cards. We dont yet do driver specifics tho. */
+	/* Claim all video cards. We don't yet do driver specifics though. */
 	return -ENODEV;
 }
 
diff -u --recursive --new-file v2.1.103/linux/drivers/video/skeletonfb.c linux/drivers/video/skeletonfb.c
--- v2.1.103/linux/drivers/video/skeletonfb.c	Wed Apr  8 19:36:28 1998
+++ linux/drivers/video/skeletonfb.c	Wed May 20 18:55:08 1998
@@ -271,7 +271,7 @@
 
 
 
-/* ------------ Hardware Independant Functions ------------ */
+/* ------------ Hardware Independent Functions ------------ */
 
 
     /*
diff -u --recursive --new-file v2.1.103/linux/fs/affs/Changes linux/fs/affs/Changes
--- v2.1.103/linux/fs/affs/Changes	Fri May  8 23:14:50 1998
+++ linux/fs/affs/Changes	Wed May 20 18:55:08 1998
@@ -32,7 +32,7 @@
 -----------
 
 - Moved cleanup from release_file() to put_inode().
-  This makes the the first one obsolete.
+  This makes the first one obsolete.
 
 - truncate() zeroes the unused remainder of a
   partially used last block when a file is truncated.
diff -u --recursive --new-file v2.1.103/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.1.103/linux/fs/binfmt_elf.c	Sat May  2 14:19:53 1998
+++ linux/fs/binfmt_elf.c	Fri May 22 11:04:43 1998
@@ -1054,7 +1054,7 @@
 	struct vm_area_struct *vma;
 	struct elfhdr elf;
 	off_t offset = 0, dataoff;
-	int limit = current->rlim[RLIMIT_CORE].rlim_cur;
+	long limit = current->rlim[RLIMIT_CORE].rlim_cur;
 	int numnote = 4;
 	struct memelfnote notes[4];
 	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
diff -u --recursive --new-file v2.1.103/linux/fs/buffer.c linux/fs/buffer.c
--- v2.1.103/linux/fs/buffer.c	Thu May 14 19:47:43 1998
+++ linux/fs/buffer.c	Thu Jun  4 22:53:50 1998
@@ -10,7 +10,6 @@
  * data, of course), but instead letting the caller do it.
  */
 
-/* Some bdflush() changes for the dynamic ramdisk - Paul Gortmaker, 12/94 */
 /* Start bdflush() with kernel_thread not syscall - Paul Gortmaker, 12/95 */
 
 /* Removed a lot of unnecessary code and simplified things now that
@@ -21,6 +20,10 @@
  * hash table, use SLAB cache for buffer heads. -DaveM
  */
 
+/* Added 32k buffer block sizes - these are required older ARM systems.
+ * - RMK
+ */
+
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
@@ -46,9 +49,13 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 
-#define NR_SIZES 5
-static char buffersize_index[17] =
-{-1,  0,  1, -1,  2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4};
+#define NR_SIZES 7
+static char buffersize_index[65] =
+{-1,  0,  1, -1,  2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
+  4, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1,
+  5, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1,
+  6};
 
 #define BUFSIZE_INDEX(X) ((int) buffersize_index[(X)>>9])
 #define MAX_BUF_PER_PAGE (PAGE_SIZE / 512)
@@ -637,13 +644,9 @@
 	if (!blksize_size[MAJOR(dev)])
 		return;
 
-	if (size > PAGE_SIZE)
-		size = 0;
-
-	switch (size) {
-		default: panic("Invalid blocksize passed to set_blocksize");
-		case 512: case 1024: case 2048: case 4096: case 8192: ;
-	}
+	/* Size must be a power of two, and between 512 and PAGE_SIZE */
+	if (size > PAGE_SIZE || size < 512 || (size & (size-1)))
+		panic("Invalid blocksize passed to set_blocksize");
 
 	if (blksize_size[MAJOR(dev)][MINOR(dev)] == 0 && size == BLOCK_SIZE) {
 		blksize_size[MAJOR(dev)][MINOR(dev)] = size;
diff -u --recursive --new-file v2.1.103/linux/fs/coda/cache.c linux/fs/coda/cache.c
--- v2.1.103/linux/fs/coda/cache.c	Thu May  7 22:51:52 1998
+++ linux/fs/coda/cache.c	Thu Jun  4 15:53:19 1998
@@ -267,8 +267,7 @@
 	while ( alias != &inode->i_dentry ) {
 		alias_de = list_entry(alias, struct dentry, d_alias);
 		if ( !alias_de ) {
-			printk("Corrupt alias list for %*s\n",
-			       alias_de->d_name.len, alias_de->d_name.name);
+			printk("Null alias list for inode %ld\n", inode->i_ino);
 			return;
 		}
 		coda_flag_children(alias_de, flag);
diff -u --recursive --new-file v2.1.103/linux/fs/coda/cnode.c linux/fs/coda/cnode.c
--- v2.1.103/linux/fs/coda/cnode.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/coda/cnode.c	Thu Jun  4 15:53:19 1998
@@ -15,7 +15,7 @@
 
 /* cnode.c */
 
-static void coda_fill_inode (struct inode *inode, struct coda_vattr *attr)
+static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
 {
         CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
 
@@ -54,8 +54,8 @@
         ENTRY;
 
         /* 
-        * We get inode numbers from Venus -- see venus source
-	*/
+	 * We get inode numbers from Venus -- see venus source
+	 */
 
 	error = venus_getattr(sb, fid, &attr);
 	if ( error ) {
@@ -82,16 +82,26 @@
 		INIT_LIST_HEAD(&(cnp->c_cnhead));
 		INIT_LIST_HEAD(&(cnp->c_volrootlist));
 	} else {
-		printk("coda_cnode make on initialized inode %ld, %s!\n",
+	        cnp->c_flags = 0;
+		CDEBUG(D_CNODE, "coda_cnode make on initialized"
+		       "inode %ld, %s!\n",
 		       (*inode)->i_ino, coda_f2s(&cnp->c_fid));
 	}
 
 	/* fill in the inode attributes */
-	if ( coda_fid_is_volroot(fid) ) 
+	if ( coda_f2i(fid) != ino ) {
+	        if ( !coda_fid_is_weird(fid) ) 
+		        printk("Coda: unknown weird fid: ino %ld, fid %s."
+			       "Tell Peter.", ino, coda_f2s(&cnp->c_fid));
 		list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
+		CDEBUG(D_CNODE, "Added %ld ,%s to volroothead\n",
+		       ino, coda_f2s(&cnp->c_fid));
+	}
 
         coda_fill_inode(*inode, &attr);
-	CDEBUG(D_CNODE, "Done linking: ino %ld,  at 0x%x with cnp 0x%x, cnp->c_vnode 0x%x\n", (*inode)->i_ino, (int) (*inode), (int) cnp, (int)cnp->c_vnode);
+	CDEBUG(D_CNODE, "Done linking: ino %ld,  at 0x%x with cnp 0x%x,"
+	       "cnp->c_vnode 0x%x\n", (*inode)->i_ino, (int) (*inode), 
+	       (int) cnp, (int)cnp->c_vnode);
 
         EXIT;
         return 0;
@@ -132,7 +142,7 @@
 	}
 
 
-	if ( coda_fid_is_volroot(fid) ) {
+	if ( coda_fid_is_weird(fid) ) {
 		struct coda_inode_info *cii;
 		struct list_head *lh, *le;
 		struct coda_sb_info *sbi = coda_sbp(sb);
@@ -141,7 +151,7 @@
 		while ( (le = le->next) != lh ) {
 			cii = list_entry(le, struct coda_inode_info, 
 					 c_volrootlist);
-			if ( cii->c_fid.Volume == fid->Volume) {
+			if ( coda_fideq(&cii->c_fid, fid) ) {
 				inode = cii->c_vnode;
 				CDEBUG(D_INODE, "volume root, found %ld\n", cii->c_vnode->i_ino);
 				return cii->c_vnode;
@@ -151,7 +161,7 @@
 		return NULL;
 	}
 
-	/* fid is not volume root, hence ino is computable */
+	/* fid is not weird: ino should be computable */
 	nr = coda_f2i(fid);
 	inode = iget(sb, nr);
 	if ( !inode ) {
@@ -173,9 +183,9 @@
 	   These have the same inode as the root of the volume they
 	   mount, but the fid will be wrong. 
 	*/
-	if ( !coda_fideq(fid, &(cnp->c_fid)) && 
-	     !coda_fid_is_volroot(&(cnp->c_fid))) {
-		printk("coda_fid2inode: bad cnode! Tell Peter.\n");
+	if ( !coda_fideq(fid, &(cnp->c_fid)) ) {
+		printk("coda_fid2inode: bad cnode (ino %ld, fid %s)"
+		       "Tell Peter.\n", nr, coda_f2s(fid));
 		iput(inode);
 		return NULL;
 	}
diff -u --recursive --new-file v2.1.103/linux/fs/coda/coda_linux.c linux/fs/coda/coda_linux.c
--- v2.1.103/linux/fs/coda/coda_linux.c	Thu May  7 22:51:52 1998
+++ linux/fs/coda/coda_linux.c	Thu Jun  4 15:53:19 1998
@@ -65,6 +65,36 @@
 {
 	return ( (fid->Vnode == 1) && (fid->Unique == 1 ) );
 }
+  
+int coda_fid_is_weird(struct ViceFid *fid)
+{
+        /* volume roots */
+        if ( (fid->Vnode == 1) && (fid->Unique == 1 ) )
+	        return 1;
+        /* tmpfid unique (simulate.cc) */
+	if ( fid->Unique == 0xffffffff )
+	        return 1;
+	/* LocalFakeVnode (local.h)  */
+	if ( fid->Vnode == 0xfffffffd )
+	        return 1;
+	/* LocalFileVnode (venus.private.h) */
+	if ( fid->Vnode == 0xfffffffe )
+	        return 1;
+	/* local fake vid (local.h) */
+	if ( fid->Volume == 0xffffffff )
+	        return 1;
+	/* local DirVnode (venus.private.h) */
+	if ( fid->Vnode == 0xffffffff )
+	        return 1;
+	/* FakeVnode (venus.private.h) */
+	if ( fid->Vnode == 0xfffffffc )
+	        return 1;
+
+	return 0;
+
+}
+
+
 
 /* put the current process credentials in the cred */
 void coda_load_creds(struct coda_cred *cred)
@@ -94,14 +124,23 @@
 {
 	unsigned short coda_flags = 0;
 
-	if ( flags & (O_RDONLY | O_RDWR) )
+	if ( (flags & 0xf) == O_RDONLY )
+		coda_flags |= C_O_READ;
+
+	if ( flags &  O_RDWR )
 		coda_flags |= C_O_READ;
 
 	if ( flags & (O_WRONLY | O_RDWR) )
 		coda_flags |= C_O_WRITE;
 
-	if ( flags & O_TRUNC ) 
+	if ( flags & O_TRUNC )  { 
+		CDEBUG(D_FILE, "--> C_O_TRUNC added\n");
 		coda_flags |= C_O_TRUNC;
+	}
+	if ( flags & O_EXCL ) {
+		coda_flags |= C_O_EXCL;
+		CDEBUG(D_FILE, "--> C_O_EXCL added\n");
+	}
 
 	return coda_flags;
 }
diff -u --recursive --new-file v2.1.103/linux/fs/coda/dir.c linux/fs/coda/dir.c
--- v2.1.103/linux/fs/coda/dir.c	Thu May  7 22:51:52 1998
+++ linux/fs/coda/dir.c	Thu Jun  4 15:53:19 1998
@@ -167,8 +167,10 @@
 	entry->d_time = 0;
 	entry->d_op = &coda_dentry_operations;
 	d_add(entry, res_inode);
-	if ( dropme ) 
+	if ( dropme ) {
 		d_drop(entry);
+		ITOC(res_inode)->c_flags |= C_VATTR;
+	}
         EXIT;
         return 0;
 }
@@ -264,7 +266,7 @@
 	}
 
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags &= ~C_VATTR;
+	dircnp->c_flags |= C_VATTR;
 	d_instantiate(de, result);
         return 0;
 }			     
@@ -320,7 +322,7 @@
 	}
 	
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags &= ~C_VATTR;
+	dircnp->c_flags |= C_VATTR;
 	dir->i_nlink++;
 	d_instantiate(de, inode);
         return 0;
@@ -359,7 +361,7 @@
 			   (const char *)name, len);
 
 	if (  ! error ) { 
-		dir_cnp->c_flags &= ~C_VATTR;
+		dir_cnp->c_flags |= C_VATTR;
 		inode->i_nlink++;
 		d_instantiate(de, inode);
 	} else {
@@ -442,7 +444,7 @@
         }
 
         /* cache management */
-	dircnp->c_flags &= ~C_VATTR;
+	dircnp->c_flags |= C_VATTR;
 	
 	de->d_inode->i_nlink--;
 	d_delete(de);
@@ -814,7 +816,7 @@
 		if (is_bad_inode(inode))
 			return 0;
 		cii = ITOC(de->d_inode);
-		if (cii->c_flags & C_PURGE) 
+		if (cii->c_flags & (C_PURGE | C_VATTR)) 
 			valid = 0;
 	}
 	return valid ||  coda_isroot(de->d_inode);
@@ -838,7 +840,7 @@
 	}
 
 	/* this baby may be lost if:
-	   - it's type changed
+            - it's type changed
             - it's ino changed 
 	*/
 	old_mode = inode->i_mode;
@@ -852,7 +854,7 @@
 		return -EIO;
 	}
 	
-	cii->c_flags &= ~C_VATTR;
+	cii->c_flags &= ~(C_VATTR | C_PURGE);
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.103/linux/fs/coda/file.c linux/fs/coda/file.c
--- v2.1.103/linux/fs/coda/file.c	Thu May  7 22:51:52 1998
+++ linux/fs/coda/file.c	Thu Jun  4 15:53:19 1998
@@ -192,13 +192,14 @@
                 return -1;
         }
 
-        cnp->c_flags &= ~C_VATTR;
-
 	down(&cont_inode->i_sem);
         result = cont_file.f_op->write(&cont_file , buff, count, 
 				       &(cont_file.f_pos));
 	up(&cont_inode->i_sem);
         coda_restore_codafile(coda_inode, coda_file, cont_inode, &cont_file);
+	
+	if (result)
+		cnp->c_flags |= C_VATTR;
 
         return result;
 }
diff -u --recursive --new-file v2.1.103/linux/fs/coda/inode.c linux/fs/coda/inode.c
--- v2.1.103/linux/fs/coda/inode.c	Mon Apr  6 17:41:00 1998
+++ linux/fs/coda/inode.c	Thu Jun  4 15:53:19 1998
@@ -161,6 +161,8 @@
 
         ENTRY;
 
+
+        sb->s_dev = 0;
 	coda_cache_clear_all(sb);
 	sb_info = coda_sbp(sb);
 	sb_info->sbi_vcomm->vc_inuse = 0;
diff -u --recursive --new-file v2.1.103/linux/fs/coda/psdev.c linux/fs/coda/psdev.c
--- v2.1.103/linux/fs/coda/psdev.c	Thu May  7 22:51:52 1998
+++ linux/fs/coda/psdev.c	Thu Jun  4 15:53:19 1998
@@ -410,8 +410,9 @@
         NULL, NULL                              /* parent, subdir */
 };
 
-struct proc_dir_entry proc_fs_coda = {
-        PROC_FS_CODA, 4, "coda",
+
+struct proc_dir_entry proc_sys_coda = {
+        0, 4, "coda",
         S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
         0, &proc_dir_inode_operations,
 	NULL, NULL,
@@ -419,8 +420,8 @@
 	NULL, NULL
 };
 
-struct proc_dir_entry proc_sys_coda = {
-        0, 4, "coda",
+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,
@@ -428,8 +429,17 @@
 	NULL, NULL
 };
 
-struct proc_dir_entry proc_fs = {
-        PROC_FS, 2, "fs",
+/*
+ * target directory structure:
+   /proc/fs/
+   /proc/fs/coda
+   /proc/fs/coda/{vfs_stats,
+
+*/
+
+
+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,
@@ -437,15 +447,6 @@
 	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,
@@ -528,9 +529,7 @@
 	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);
@@ -585,12 +584,9 @@
         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_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);
diff -u --recursive --new-file v2.1.103/linux/fs/coda/stats.c linux/fs/coda/stats.c
--- v2.1.103/linux/fs/coda/stats.c	Thu May  7 22:51:53 1998
+++ linux/fs/coda/stats.c	Thu Jun  4 15:53:19 1998
@@ -7,6 +7,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
diff -u --recursive --new-file v2.1.103/linux/fs/coda/upcall.c linux/fs/coda/upcall.c
--- v2.1.103/linux/fs/coda/upcall.c	Thu May  7 22:51:53 1998
+++ linux/fs/coda/upcall.c	Thu Jun  4 15:53:19 1998
@@ -777,8 +777,6 @@
  *                  force a new lookup for all the children
                     of this dir.
 
- * CFS_ZAPVNODE  -- intended to be a zapfile for just one cred. 
-                    Not used?
  *
  * The next is a result of Venus detecting an inconsistent file.
  * CFS_PURGEFID  -- flush the attribute for the file
@@ -792,81 +790,85 @@
 int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
 {
 
-    /* Handle invalidate requests. */
-    switch (opcode) {
-    case CFS_FLUSH : {
-	    clstats(CFS_FLUSH);
-	    CDEBUG(D_DOWNCALL, "CFS_FLUSH\n");
-	    coda_cache_clear_all(sb);
-	    shrink_dcache_sb(sb);
-	    return(0);
-    }
-    case CFS_PURGEUSER : {
-	    struct coda_cred *cred = &out->cfs_purgeuser.cred;
-	    CDEBUG(D_DOWNCALL, "CFS_PURGEUSER\n");
-	    if ( !cred ) {
-		    printk("PURGEUSER: null cred!\n");
-		    return 0;
-	    }
-	    clstats(CFS_PURGEUSER);
-	    coda_cache_clear_cred(sb, cred);
-	    return(0);
-    }
-    case CFS_ZAPDIR : {
-	    struct inode *inode;
-	    ViceFid *fid = &out->cfs_zapdir.CodaFid;
-	    if ( !fid ) {
-		    printk("ZAPDIR: Null fid\n");
-		    return 0;
-	    }
-	    CDEBUG(D_DOWNCALL, "zapdir: fid = %s\n", coda_f2s(fid));
-	    clstats(CFS_ZAPDIR);
-	    inode = coda_fid_to_inode(fid, sb);
-	    coda_flag_inode(inode, C_VATTR);
-	    coda_cache_clear_inode(inode);
-	    coda_flag_alias_children(inode, C_PURGE);
-	    return(0);
-    }
-
-    case CFS_ZAPVNODE : 
-    case CFS_ZAPFILE : {
-	    struct inode *inode;
-	    struct ViceFid *fid = &out->cfs_zapfile.CodaFid;
-	    clstats(CFS_ZAPFILE);
-	    if ( !fid ) {
-		    printk("ZAPFILE: Null fid\n");
-		    return 0;
-	    }
-	    CDEBUG(D_DOWNCALL, "zapfile: fid = %s\n", coda_f2s(fid));
-	    inode = coda_fid_to_inode(fid, sb);
-	    coda_flag_inode(inode, C_VATTR);
-	    coda_cache_clear_inode(inode);
-	    return 0;
-    }
-    case CFS_PURGEFID : {
-	    struct inode *inode;
-	    ViceFid *fid = &out->cfs_purgefid.CodaFid;
-	    if ( !fid ) {
-		    printk("PURGEFID: Null fid\n");
-		    return 0;
-	    }
-	    CDEBUG(D_DOWNCALL, "purgefid: fid = %s\n", coda_f2s(fid));
-	    clstats(CFS_PURGEFID);
-	    inode = coda_fid_to_inode(fid, sb);
-	    coda_flag_inode(inode, C_PURGE);
-	    coda_cache_clear_inode(inode);
-	    return 0;
-    }
-    case CFS_REPLACE : {
-	    printk("CFS_REPLACCE\n");
-	    clstats(CFS_REPLACE);
-	    CDEBUG(D_DOWNCALL, "CFS_REPLACE\n");
-	    coda_cache_clear_all(sb);
-	    shrink_dcache_sb(sb);
-	    return (0);
-    }			   
-    }
-      return 0;
+    /* Handle invalidation requests. */
+          if ( !sb ) { 
+	          printk("coda_downcall: opcode %d, no sb!\n", opcode);
+		  return 0; 
+	  }
+
+	  switch (opcode) {
+
+	  case CFS_FLUSH : {
+	           clstats(CFS_FLUSH);
+		   CDEBUG(D_DOWNCALL, "CFS_FLUSH\n");
+		   coda_cache_clear_all(sb);
+		   shrink_dcache_sb(sb);
+		   return(0);
+	  }
+
+	  case CFS_PURGEUSER : {
+	           struct coda_cred *cred = &out->cfs_purgeuser.cred;
+		   CDEBUG(D_DOWNCALL, "CFS_PURGEUSER\n");
+		   if ( !cred ) {
+		           printk("PURGEUSER: null cred!\n");
+			   return 0;
+		   }
+		   clstats(CFS_PURGEUSER);
+		   coda_cache_clear_cred(sb, cred);
+		   return(0);
+	  }
+
+	  case CFS_ZAPDIR : {
+	          struct inode *inode;
+		  ViceFid *fid = &out->cfs_zapdir.CodaFid;
+		  CDEBUG(D_DOWNCALL, "zapdir: fid = %s\n", coda_f2s(fid));
+		  clstats(CFS_ZAPDIR);
+
+		  inode = coda_fid_to_inode(fid, sb);
+		  if ( inode ) {
+	                  coda_flag_inode(inode, C_VATTR);
+			  coda_cache_clear_inode(inode);
+			  coda_flag_alias_children(inode, C_PURGE);
+		  }
+		  return(0);
+	  }
+
+	  case CFS_ZAPFILE : {
+	          struct inode *inode;
+		  struct ViceFid *fid = &out->cfs_zapfile.CodaFid;
+		  clstats(CFS_ZAPFILE);
+		  CDEBUG(D_DOWNCALL, "zapfile: fid = %s\n", coda_f2s(fid));
+		  inode = coda_fid_to_inode(fid, sb);
+		  if ( inode ) {
+	                  coda_flag_inode(inode, C_VATTR);
+			  coda_cache_clear_inode(inode);
+		  }
+		  return 0;
+	  }
+
+	  case CFS_PURGEFID : {
+	          struct inode *inode;
+		  ViceFid *fid = &out->cfs_purgefid.CodaFid;
+		  CDEBUG(D_DOWNCALL, "purgefid: fid = %s\n", coda_f2s(fid));
+		  clstats(CFS_PURGEFID);
+		  inode = coda_fid_to_inode(fid, sb);
+		  if ( inode ) { 
+                          coda_flag_inode(inode, C_PURGE);
+			  coda_cache_clear_inode(inode);
+		  }
+		  return 0;
+	  }
+
+	  case CFS_REPLACE : {
+	          printk("CFS_REPLACCE\n");
+		  clstats(CFS_REPLACE);
+		  CDEBUG(D_DOWNCALL, "CFS_REPLACE\n");
+		  coda_cache_clear_all(sb);
+		  shrink_dcache_sb(sb);
+		  return (0);
+	  }			   
+	  }
+	  return 0;
 }
 
 
diff -u --recursive --new-file v2.1.103/linux/fs/dquot.c linux/fs/dquot.c
--- v2.1.103/linux/fs/dquot.c	Wed May 20 19:10:40 1998
+++ linux/fs/dquot.c	Thu May 21 10:48:07 1998
@@ -1169,7 +1169,7 @@
 	}
 
 	if (inode->i_size == 0 || (inode->i_size % sizeof(struct dqblk)) != 0) {
-		iput(inode);
+		dput(dentry);
 		return(-EINVAL);
 	}
 
diff -u --recursive --new-file v2.1.103/linux/fs/exec.c linux/fs/exec.c
--- v2.1.103/linux/fs/exec.c	Thu May  7 22:51:53 1998
+++ linux/fs/exec.c	Thu May 21 14:21:31 1998
@@ -428,6 +428,8 @@
 	 * Failure ... restore the prior mm_struct.
 	 */
 fail_restore:
+	/* The pgd belongs to the parent ... don't free it! */
+	mm->pgd = NULL;
 	current->mm = old_mm;
 	mmput(mm);
 
diff -u --recursive --new-file v2.1.103/linux/fs/fcntl.c linux/fs/fcntl.c
--- v2.1.103/linux/fs/fcntl.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/fcntl.c	Wed May 20 18:55:08 1998
@@ -152,7 +152,7 @@
 			/*
 			 * XXX If f_owner is a process group, the
 			 * negative return value will get converted
-			 * into an error.  Oops.  If we keep the the
+			 * into an error.  Oops.  If we keep the
 			 * current syscall conventions, the only way
 			 * to fix this will be in libc.
 			 */
diff -u --recursive --new-file v2.1.103/linux/fs/hfs/ChangeLog linux/fs/hfs/ChangeLog
--- v2.1.103/linux/fs/hfs/ChangeLog	Tue Mar 17 22:18:15 1998
+++ linux/fs/hfs/ChangeLog	Wed May 20 18:55:09 1998
@@ -344,7 +344,7 @@
 	Note that these routines are now tested on Intel, PPC and Alpha.
 
 	* Makefile:
-	Add -fno-builtin the the CFLAGS.
+	Add -fno-builtin to the CFLAGS.
 
 Fri Feb 14 10:50:14 1997  Paul H. Hargrove  <hargrove@sccm.stanford.edu>
 
diff -u --recursive --new-file v2.1.103/linux/fs/hfs/super.c linux/fs/hfs/super.c
--- v2.1.103/linux/fs/hfs/super.c	Mon Apr  6 17:41:01 1998
+++ linux/fs/hfs/super.c	Wed May 20 18:55:09 1998
@@ -4,7 +4,7 @@
  * Copyright (C) 1995-1997  Paul H. Hargrove
  * This file may be distributed under the terms of the GNU Public License.
  *
- * This file contains hfs_read_super() some of the the super_ops and
+ * This file contains hfs_read_super(), some of the super_ops and
  * init_module() and cleanup_module().	The remaining super_ops are in
  * inode.c since they deal with inodes.
  *
diff -u --recursive --new-file v2.1.103/linux/fs/nfsd/export.c linux/fs/nfsd/export.c
--- v2.1.103/linux/fs/nfsd/export.c	Thu Feb 12 20:56:12 1998
+++ linux/fs/nfsd/export.c	Thu May 21 13:57:47 1998
@@ -32,8 +32,8 @@
 typedef struct svc_client	svc_client;
 typedef struct svc_export	svc_export;
 
-static svc_export *	exp_find(svc_client *clp, dev_t dev);
-static svc_export *	exp_parent(svc_client *clp, dev_t dev);
+static svc_export *	exp_find(svc_client *clp, kdev_t dev);
+static svc_export *	exp_parent(svc_client *clp, kdev_t dev);
 static void		exp_unexport_all(svc_client *clp);
 static void		exp_do_unexport(svc_export *unexp);
 static svc_client *	exp_getclientbyname(char *name);
@@ -46,6 +46,7 @@
 #define CLIENT_HASHMASK		(CLIENT_HASHMAX - 1)
 #define CLIENT_HASH(a) \
 		((((a)>>24) ^ ((a)>>16) ^ ((a)>>8) ^(a)) & CLIENT_HASHMASK)
+/* XXX: is this adequate for 32bit kdev_t ? */
 #define EXPORT_HASH(dev)	((dev) & (NFSCLNT_EXPMAX - 1))
 
 struct svc_clnthash {
@@ -69,7 +70,7 @@
  * Find a client's export for a device.
  */
 static inline svc_export *
-exp_find(svc_client *clp, dev_t dev)
+exp_find(svc_client *clp, kdev_t dev)
 {
 	svc_export *	exp;
 
@@ -83,7 +84,7 @@
  * Find the client's export entry matching xdev/xino.
  */
 svc_export *
-exp_get(svc_client *clp, dev_t dev, ino_t ino)
+exp_get(svc_client *clp, kdev_t dev, ino_t ino)
 {
 	svc_export *	exp;
 
@@ -97,7 +98,7 @@
  * Check whether there are any exports for a device.
  */
 static int
-exp_device_in_use(dev_t dev)
+exp_device_in_use(kdev_t dev)
 {
 	struct svc_client *clp;
 
@@ -112,7 +113,7 @@
  * Look up the device of the parent fs.
  */
 static inline int
-nfsd_parentdev(dev_t *devp)
+nfsd_parentdev(kdev_t *devp)
 {
 	struct super_block	*sb;
 
@@ -129,10 +130,10 @@
  * only by the export syscall to keep the export tree consistent.
  */
 static svc_export *
-exp_parent(svc_client *clp, dev_t dev)
+exp_parent(svc_client *clp, kdev_t dev)
 {
 	svc_export	*exp;
-	dev_t		xdev = dev;
+	kdev_t		xdev = dev;
 
 	do {
 		exp = exp_find(clp, xdev);
@@ -155,7 +156,7 @@
 	struct dentry	*dentry = NULL;
 	struct inode	*inode = NULL;
 	int		i, err;
-	dev_t		dev;
+	kdev_t		dev;
 	ino_t		ino;
 
 	/* Consistency check */
@@ -166,7 +167,7 @@
 	dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n",
 			nxp->ex_client, nxp->ex_path,
 			nxp->ex_dev, nxp->ex_ino, nxp->ex_flags);
-	dev = nxp->ex_dev;
+	dev = to_kdev_t(nxp->ex_dev);
 	ino = nxp->ex_ino;
 
 	/* Try to lock the export table for update */
@@ -205,7 +206,10 @@
 	if(!inode)
 		goto finish;
 	err = -EINVAL;
-	if(inode->i_dev != nxp->ex_dev || inode->i_ino != nxp->ex_ino) {
+	if(inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
+
+		printk(KERN_DEBUG "exp_export: i_dev = %x, dev = %x\n",
+			inode->i_dev, dev); 
 		/* I'm just being paranoid... */
 		goto finish;
 	}
@@ -386,7 +390,7 @@
  * since its harder to fool a kernel module than a user space program.
  */
 int
-exp_rootfh(struct svc_client *clp, dev_t dev, ino_t ino, struct knfs_fh *f)
+exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, struct knfs_fh *f)
 {
 	struct svc_export	*exp = NULL;
 	struct svc_fh		fh;
diff -u --recursive --new-file v2.1.103/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- v2.1.103/linux/fs/nfsd/nfsctl.c	Thu May  7 22:51:53 1998
+++ linux/fs/nfsd/nfsctl.c	Thu May 21 13:57:47 1998
@@ -124,7 +124,7 @@
 	if (!(clp = exp_getclient(sin)))
 		err = -EPERM;
 	else
-		err = exp_rootfh(clp, data->gf_dev, data->gf_ino, res);
+		err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, res);
 	exp_unlock();
 
 	return err;
diff -u --recursive --new-file v2.1.103/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.1.103/linux/fs/nfsd/nfsfh.c	Fri Jan 23 18:10:32 1998
+++ linux/fs/nfsd/nfsfh.c	Thu May 21 13:57:47 1998
@@ -29,7 +29,7 @@
 	struct dentry * dentry;
 	unsigned long reftime;
 	ino_t	ino;
-	dev_t	dev;
+	kdev_t	dev;
 };
 
 #define NFSD_MAXFH PAGE_SIZE/sizeof(struct fh_entry)
@@ -42,7 +42,7 @@
 
 static int add_to_fhcache(struct dentry *, int);
 static int nfsd_d_validate(struct dentry *);
-struct dentry * lookup_inode(dev_t, ino_t, ino_t);
+struct dentry * lookup_inode(kdev_t, ino_t, ino_t);
 
 static LIST_HEAD(fixup_head);
 static LIST_HEAD(path_inuse);
@@ -55,7 +55,7 @@
 	struct list_head lru;
 	ino_t	dir;
 	ino_t	ino;
-	dev_t	dev;
+	kdev_t	dev;
 	struct dentry *dentry;
 	unsigned long reftime;
 };
@@ -65,11 +65,11 @@
 	unsigned long reftime;
 	int	users;
 	ino_t	ino;
-	dev_t	dev;
+	kdev_t	dev;
 	char	name[1];
 };
 
-static struct nfsd_fixup * find_cached_lookup(dev_t dev, ino_t dir, ino_t ino)
+static struct nfsd_fixup * find_cached_lookup(kdev_t dev, ino_t dir, ino_t ino)
 {
 	struct list_head *tmp = fixup_head.next;
 
@@ -226,14 +226,14 @@
 	 */
 retry:
 	kfree(new);
-	printk("add_to_path_cache: path length changed, retrying\n");
+	printk(KERN_DEBUG "add_to_path_cache: path length changed, retrying\n");
 	goto restart;
 }
 
 /*
  * Search for a path entry for the specified (dev, inode).
  */
-struct nfsd_path *get_path_entry(dev_t dev, ino_t ino)
+struct nfsd_path *get_path_entry(kdev_t dev, ino_t ino)
 {
 	struct nfsd_path *pe;
 	struct list_head *tmp;
@@ -264,7 +264,7 @@
 static void free_path_entry(struct nfsd_path *pe)
 {
 	if (pe->users)
-		printk("free_path_entry: %s in use, users=%d\n",
+		printk(KERN_DEBUG "free_path_entry: %s in use, users=%d\n",
 			pe->name, pe->users);
 	list_del(&pe->lru);
 	kfree(pe);
@@ -381,7 +381,7 @@
  * searching for a dentry given the inode: as we walk up the tree,
  * it's likely that a dentry exists before we reach the root.
  */
-struct dentry * lookup_inode(dev_t dev, ino_t dirino, ino_t ino)
+struct dentry * lookup_inode(kdev_t dev, ino_t dirino, ino_t ino)
 {
 	struct super_block *sb;
 	struct dentry *root, *dentry, *result;
@@ -457,7 +457,8 @@
 		 * Make sure we can't get caught in a loop ...
 		 */
 		if (dirino == dirent.ino && dirino != root_ino) {
-			printk("lookup_inode: looping?? (ino=%ld, path=%s)\n",
+			printk(KERN_DEBUG 
+			       "lookup_inode: looping?? (ino=%ld, path=%s)\n",
 				dirino, name);	
 			goto out_root;
 		}
@@ -649,7 +650,7 @@
 /*
  * Find an entry in the dir cache for the specified inode number.
  */
-static struct fh_entry *find_fhe_by_ino(dev_t dev, ino_t ino)
+static struct fh_entry *find_fhe_by_ino(kdev_t dev, ino_t ino)
 {
 	struct fh_entry * fhe = &dirstable[0];
 	int i;
@@ -667,7 +668,7 @@
  * Find the (directory) dentry with the specified (dev, inode) number.
  * Note: this leaves the dentry in the cache.
  */
-static struct dentry *find_dentry_by_ino(dev_t dev, ino_t ino)
+static struct dentry *find_dentry_by_ino(kdev_t dev, ino_t ino)
 {
 	struct fh_entry *fhe;
 	struct nfsd_path *pe;
@@ -1129,14 +1130,14 @@
 	struct inode *inode;
 
 	if (!fhp->fh_dverified) {
-		printk("fh_update: fh not verified!\n");
+		printk(KERN_DEBUG "fh_update: fh not verified!\n");
 		goto out;
 	}
 
 	dentry = fhp->fh_dentry;
 	inode = dentry->d_inode;
 	if (!inode) {
-		printk("fh_update: %s/%s still negative!\n",
+		printk(KERN_DEBUG "fh_update: %s/%s still negative!\n",
 			dentry->d_parent->d_name.name, dentry->d_name.name);
 		goto out;
 	}
@@ -1157,7 +1158,7 @@
 		fh_unlock(fhp);
 		fhp->fh_dverified = 0;
 		if (!dentry->d_count) {
-			printk("fh_put: %s/%s has d_count 0!\n",
+			printk(KERN_DEBUG "fh_put: %s/%s has d_count 0!\n",
 			dentry->d_parent->d_name.name, dentry->d_name.name);
 			return;
 		}
@@ -1204,10 +1205,10 @@
 	return valid;
 
 bad_addr:
-	printk("nfsd_d_validate: invalid address %lx\n", dent_addr);
+	printk(KERN_DEBUG "nfsd_d_validate: invalid address %lx\n", dent_addr);
 	goto out;
 bad_align:
-	printk("nfsd_d_validate: unaligned address %lx\n", dent_addr);
+	printk(KERN_DEBUG "nfsd_d_validate: unaligned address %lx\n", dent_addr);
 	goto out;
 }
 
@@ -1218,7 +1219,7 @@
  * This is called when revoking the last export for a
  * device, so that it can be unmounted cleanly.
  */
-void nfsd_fh_flush(dev_t dev)
+void nfsd_fh_flush(kdev_t dev)
 {
 	struct fh_entry *fhe;
 	int i, pass = 2;
@@ -1260,7 +1261,7 @@
 		free_fixup_entry(fp);
 		i++;
 	}
-	printk("nfsd_fh_free: %d fixups freed\n", i);
+	printk(KERN_DEBUG "nfsd_fh_free: %d fixups freed\n", i);
 
 	i = 0;
 	while ((tmp = path_inuse.next) != &path_inuse) {
@@ -1269,18 +1270,23 @@
 		free_path_entry(pe);
 		i++;
 	}
-	printk("nfsd_fh_free: %d paths freed\n", i);
+	printk(KERN_DEBUG "nfsd_fh_free: %d paths freed\n", i);
 
-	printk("nfsd_fh_free: verified %d, put %d\n",
+	printk(KERN_DEBUG "nfsd_fh_free: verified %d, put %d\n",
 		nfsd_nr_verified, nfsd_nr_put);
 }
 
 void nfsd_fh_init(void)
 {
+	/* Sanity check */ 
+	extern void __my_nfsfh_is_too_big(void); 
+	if (sizeof(struct nfs_fhbase) > 32) 
+		__my_nfsfh_is_too_big(); 
+
 	memset(filetable, 0, NFSD_MAXFH*sizeof(struct fh_entry));
 	memset(dirstable, 0, NFSD_MAXFH*sizeof(struct fh_entry));
 	INIT_LIST_HEAD(&path_inuse);
 	INIT_LIST_HEAD(&fixup_head);
 
-	printk("nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH);
+	printk(KERN_DEBUG "nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH);
 }
diff -u --recursive --new-file v2.1.103/linux/fs/proc/procfs_syms.c linux/fs/proc/procfs_syms.c
--- v2.1.103/linux/fs/proc/procfs_syms.c	Thu Jun 26 12:33:39 1997
+++ linux/fs/proc/procfs_syms.c	Mon May 25 10:26:36 1998
@@ -22,6 +22,7 @@
 EXPORT_SYMBOL(proc_dir_inode_operations);
 EXPORT_SYMBOL(proc_net_inode_operations);
 EXPORT_SYMBOL(proc_net);
+EXPORT_SYMBOL(proc_bus);
 
 /*
  * This is required so that if we load scsi later, that the
diff -u --recursive --new-file v2.1.103/linux/fs/stat.c linux/fs/stat.c
--- v2.1.103/linux/fs/stat.c	Tue Mar 10 10:03:34 1998
+++ linux/fs/stat.c	Mon May 25 10:37:26 1998
@@ -38,10 +38,15 @@
  */
 static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
 {
+	static int warncount = 5;
 	struct __old_kernel_stat tmp;
 
-	printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
-		current->comm);
+	if (warncount) {
+		warncount--;
+		printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
+			current->comm);
+	}
+
 	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
 	tmp.st_ino = inode->i_ino;
 	tmp.st_mode = inode->i_mode;
diff -u --recursive --new-file v2.1.103/linux/include/asm-alpha/string.h linux/include/asm-alpha/string.h
--- v2.1.103/linux/include/asm-alpha/string.h	Wed Apr  8 19:36:28 1998
+++ linux/include/asm-alpha/string.h	Thu May 21 13:48:06 1998
@@ -4,10 +4,8 @@
 #ifdef __KERNEL__
 
 /*
- * GCC of any recent vintage doesn't do stupid things with bcopy.  Of
- * EGCS-devel vintage, it knows all about expanding memcpy inline.
- * For things other than EGCS-devel but still recent, GCC will expand
- * __builtin_memcpy as a simple call to memcpy.
+ * GCC of any recent vintage doesn't do stupid things with bcopy.
+ * EGCS-devel knows all about expanding memcpy inline, others don't.
  *
  * Similarly for a memset with data = 0.
  */
@@ -16,7 +14,7 @@
 /* For backward compatibility with modules.  Unused otherwise.  */
 extern void * __memcpy(void *, const void *, size_t);
 
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 8
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 #define memcpy __builtin_memcpy
 #endif
 
@@ -24,7 +22,7 @@
 extern void * __constant_c_memset(void *, unsigned long, long);
 extern void * __memset(void *, char, size_t);
 
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 8
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 #define memset(s, c, n)							    \
 (__builtin_constant_p(c)						    \
  ? (__builtin_constant_p(n) && (c) == 0					    \
diff -u --recursive --new-file v2.1.103/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- v2.1.103/linux/include/asm-alpha/unistd.h	Wed Apr  8 19:36:28 1998
+++ linux/include/asm-alpha/unistd.h	Thu May 21 13:48:06 1998
@@ -304,52 +304,187 @@
 #define __NR_getrusage			364
 #define __NR_wait4			365
 #define __NR_adjtimex			366
+#define __NR_getcwd			367
 
 
 #if defined(__LIBRARY__) && defined(__GNUC__)
 
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+#define _syscall_return(type)						\
+	return (_sc_err ? errno = _sc_ret, _sc_ret = -1L : 0), (type) _sc_ret
+
+#define _syscall_clobbers						\
+	"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8",			\
+	"$22", "$23", "$24", "$25", "$27", "$28" 			\
+
 #define _syscall0(type, name)						\
 type name(void)								\
 {									\
-	extern long syscall (int, ...);					\
-	return syscall(__NR_##name));					\
+	long _sc_ret, _sc_err;						\
+	{								\
+		register long _sc_0 __asm__("$0");			\
+		register long _sc_19 __asm__("$19");			\
+									\
+		_sc_0 = __NR_##name;					\
+		__asm__("callsys # %0 %1 %2"				\
+			: "=r"(_sc_0), "=r"(_sc_19)			\
+			: "0"(_sc_0)					\
+			: _syscall_clobbers);				\
+		_sc_ret = _sc_0, _sc_err = _sc_19;			\
+	}								\
+	_syscall_return(type);						\
 }
 
 #define _syscall1(type,name,type1,arg1)					\
 type name(type1 arg1)							\
 {									\
-	extern long syscall (int, ...);					\
-	return syscall(__NR_##name, arg1);				\
+	long _sc_ret, _sc_err;						\
+	{								\
+		register long _sc_0 __asm__("$0");			\
+		register long _sc_16 __asm__("$16");			\
+		register long _sc_19 __asm__("$19");			\
+									\
+		_sc_0 = __NR_##name;					\
+		_sc_16 = (long) (arg1);					\
+		__asm__("callsys # %0 %1 %2 %3"				\
+			: "=r"(_sc_0), "=r"(_sc_19)			\
+			: "0"(_sc_0), "r"(_sc_16)			\
+			: _syscall_clobbers);				\
+		_sc_ret = _sc_0, _sc_err = _sc_19;			\
+	}								\
+	_syscall_return(type);						\
 }
 
 #define _syscall2(type,name,type1,arg1,type2,arg2)			\
 type name(type1 arg1,type2 arg2)					\
 {									\
-	extern long syscall (int, ...);					\
-	return syscall(__NR_##name, arg1, arg2);				\
+	long _sc_ret, _sc_err;						\
+	{								\
+		register long _sc_0 __asm__("$0");			\
+		register long _sc_16 __asm__("$16");			\
+		register long _sc_17 __asm__("$17");			\
+		register long _sc_19 __asm__("$19");			\
+									\
+		_sc_0 = __NR_##name;					\
+		_sc_16 = (long) (arg1);					\
+		_sc_17 = (long) (arg2);					\
+		__asm__("callsys # %0 %1 %2 %3 %4"			\
+			: "=r"(_sc_0), "=r"(_sc_19)			\
+			: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17)		\
+			: _syscall_clobbers);				\
+		_sc_ret = _sc_0, _sc_err = _sc_19;			\
+	}								\
+	_syscall_return(type);						\
 }
 
 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
 type name(type1 arg1,type2 arg2,type3 arg3)				\
 {									\
-	extern long syscall (int, ...);					\
-	return syscall(__NR_##name, arg1, arg2, arg3);			\
+	long _sc_ret, _sc_err;						\
+	{								\
+		register long _sc_0 __asm__("$0");			\
+		register long _sc_16 __asm__("$16");			\
+		register long _sc_17 __asm__("$17");			\
+		register long _sc_18 __asm__("$18");			\
+		register long _sc_19 __asm__("$19");			\
+									\
+		_sc_0 = __NR_##name;					\
+		_sc_16 = (long) (arg1);					\
+		_sc_17 = (long) (arg2);					\
+		_sc_18 = (long) (arg3);					\
+		__asm__("callsys # %0 %1 %2 %3 %4 %5"			\
+			: "=r"(_sc_0), "=r"(_sc_19)			\
+			: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17),		\
+			  "r"(_sc_18)					\
+			: _syscall_clobbers);				\
+		_sc_ret = _sc_0, _sc_err = _sc_19;			\
+	}								\
+	_syscall_return(type);						\
 }
 
 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4)		 \
 {									 \
-	extern long syscall (int, ...);					 \
-	return syscall(__NR_##name, arg1, arg2, arg3, arg4);		 \
+	long _sc_ret, _sc_err;						\
+	{								\
+		register long _sc_0 __asm__("$0");			\
+		register long _sc_16 __asm__("$16");			\
+		register long _sc_17 __asm__("$17");			\
+		register long _sc_18 __asm__("$18");			\
+		register long _sc_19 __asm__("$19");			\
+									\
+		_sc_0 = __NR_##name;					\
+		_sc_16 = (long) (arg1);					\
+		_sc_17 = (long) (arg2);					\
+		_sc_18 = (long) (arg3);					\
+		_sc_19 = (long) (arg4);					\
+		__asm__("callsys # %0 %1 %2 %3 %4 %5 %6"		\
+			: "=r"(_sc_0), "=r"(_sc_19)			\
+			: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17),		\
+			  "r"(_sc_18), "1"(_sc_19)			\
+			: _syscall_clobbers);				\
+		_sc_ret = _sc_0, _sc_err = _sc_19;			\
+	}								\
+	_syscall_return(type);						\
 } 
 
 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
 	  type5,arg5)							 \
-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)	 \
-{									 \
-	extern long syscall (int, ...);					 \
-	return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);	 \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)	\
+{									\
+	long _sc_ret, _sc_err;						\
+	{								\
+		register long _sc_0 __asm__("$0");			\
+		register long _sc_16 __asm__("$16");			\
+		register long _sc_17 __asm__("$17");			\
+		register long _sc_18 __asm__("$18");			\
+		register long _sc_19 __asm__("$19");			\
+		register long _sc_20 __asm__("$20");			\
+									\
+		_sc_0 = __NR_##name;					\
+		_sc_16 = (long) (arg1);					\
+		_sc_17 = (long) (arg2);					\
+		_sc_18 = (long) (arg3);					\
+		_sc_19 = (long) (arg4);					\
+		_sc_20 = (long) (arg5);					\
+		__asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7"		\
+			: "=r"(_sc_0), "=r"(_sc_19)			\
+			: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17),		\
+			  "r"(_sc_18), "1"(_sc_19), "r"(_sc_20)		\
+			: _syscall_clobbers);				\
+		_sc_ret = _sc_0, _sc_err = _sc_19;			\
+	}								\
+	_syscall_return(type);						\
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5,type6,arg6)					 \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\
+{									\
+	long _sc_ret, _sc_err;						\
+	{								\
+		register long _sc_0 __asm__("$0");			\
+		register long _sc_16 __asm__("$16");			\
+		register long _sc_17 __asm__("$17");			\
+		register long _sc_18 __asm__("$18");			\
+		register long _sc_19 __asm__("$19");			\
+		register long _sc_20 __asm__("$20");			\
+		register long _sc_21 __asm__("$21");			\
+									\
+		_sc_0 = __NR_##name;					\
+		_sc_16 = (long) (arg1);					\
+		_sc_17 = (long) (arg2);					\
+		_sc_18 = (long) (arg3);					\
+		_sc_19 = (long) (arg4);					\
+		_sc_20 = (long) (arg5);					\
+		_sc_21 = (long) (arg6);					\
+		__asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7 %8"		\
+			: "=r"(_sc_0), "=r"(_sc_19)			\
+			: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17),		\
+			  "r"(_sc_18), "1"(_sc_19), "r"(_sc_20), "r"(_sc_21) \
+			: _syscall_clobbers);				\
+		_sc_ret = _sc_0, _sc_err = _sc_19;			\
+	}								\
+	_syscall_return(type);						\
 }
 
 #endif /* __LIBRARY__ && __GNUC__ */
diff -u --recursive --new-file v2.1.103/linux/include/asm-i386/irq.h linux/include/asm-i386/irq.h
--- v2.1.103/linux/include/asm-i386/irq.h	Thu Apr 23 20:21:37 1998
+++ linux/include/asm-i386/irq.h	Fri May 22 13:09:39 1998
@@ -10,13 +10,14 @@
  *	<tomsoft@informatik.tu-chemnitz.de>
  */
 
-#ifndef __SMP__
-#define NR_IRQS 16
-#else
-#define NR_IRQS 24
-#endif
-
 #define TIMER_IRQ 0
+
+/*
+ * 16 XT IRQ's, 8 potential APIC interrupt sources.
+ * Right now the APIC is only used for SMP, but this
+ * may change.
+ */
+#define NR_IRQS 24
 
 static __inline__ int irq_cannonicalize(int irq)
 {
diff -u --recursive --new-file v2.1.103/linux/include/asm-i386/posix_types.h linux/include/asm-i386/posix_types.h
--- v2.1.103/linux/include/asm-i386/posix_types.h	Mon Dec  8 23:58:04 1997
+++ linux/include/asm-i386/posix_types.h	Mon May 25 10:32:52 1998
@@ -37,6 +37,8 @@
 #endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
 } __kernel_fsid_t;
 
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
 #undef	__FD_SET
 #define __FD_SET(fd,fdsetp) \
 		__asm__ __volatile__("btsl %1,%0": \
@@ -61,5 +63,7 @@
 			:"=m" (*(__kernel_fd_set *) (fdsetp)) \
 			:"a" (0), "c" (__FDSET_LONGS), \
 			"D" ((__kernel_fd_set *) (fdsetp)) :"cx","di")
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
 
 #endif
diff -u --recursive --new-file v2.1.103/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h
--- v2.1.103/linux/include/asm-i386/spinlock.h	Thu May  7 22:51:54 1998
+++ linux/include/asm-i386/spinlock.h	Thu Jun  4 11:00:37 1998
@@ -61,14 +61,14 @@
 #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(x)		do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_lock(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (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:%d: spin_unlock_wait(%s:%p) deadlock\n", __BASE_FILE__,__LINE__, (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:%d: spin_unlock(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (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:%d: spin_lock_irq(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1;} while (0)
+#define spin_unlock_irq(x)	do {cli(); if (!(x)->lock&&(x)->babble) {printk("%s:%d: spin_lock(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; 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)
+#define spin_lock_irqsave(x,flags)      do {save_flags(flags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_lock_irqsave(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (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:%d: spin_unlock_irqrestore(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; restore_flags(flags);} while (0)
 
 #endif	/* DEBUG_SPINLOCKS */
 
diff -u --recursive --new-file v2.1.103/linux/include/asm-i386/user.h linux/include/asm-i386/user.h
--- v2.1.103/linux/include/asm-i386/user.h	Wed Dec 10 11:39:34 1997
+++ linux/include/asm-i386/user.h	Mon May 25 22:51:13 1998
@@ -79,7 +79,7 @@
 				   esp register.  */
   long int signal;     		/* Signal that caused the core dump. */
   int reserved;			/* No longer used */
-  struct pt_regs * u_ar0;	/* Used by gdb to help find the values for */
+  struct user_pt_regs * u_ar0;	/* Used by gdb to help find the values for */
 				/* the registers. */
   struct user_i387_struct* u_fpstate;	/* Math Co-processor pointer. */
   unsigned long magic;		/* To uniquely identify a core file */
diff -u --recursive --new-file v2.1.103/linux/include/asm-i386/vm86.h linux/include/asm-i386/vm86.h
--- v2.1.103/linux/include/asm-i386/vm86.h	Wed Dec 11 06:41:23 1996
+++ linux/include/asm-i386/vm86.h	Wed May 20 18:55:09 1998
@@ -193,7 +193,7 @@
  * this way. In front of 'return-eip' may be some data, depending on
  * compilation, so we don't rely on this and save the pointer to 'oldregs'
  * in 'regs32' above.
- * However, with GCC-2.7.2 and the the current CFLAGS you see exactly this:
+ * However, with GCC-2.7.2 and the current CFLAGS you see exactly this:
 
 	long return-eip;        from call to vm86()
 	struct pt_regs oldregs;  user space registers as saved by syscall
diff -u --recursive --new-file v2.1.103/linux/include/asm-mips/sgidefs.h linux/include/asm-mips/sgidefs.h
--- v2.1.103/linux/include/asm-mips/sgidefs.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/sgidefs.h	Wed May 20 18:55:15 1998
@@ -45,7 +45,7 @@
 #endif
 
 /*
- * Now lets try our best to supply some reasonable default values for
+ * Now let's try our best to supply some reasonable default values for
  * whatever defines GCC didn't supply.  This cannot be done correct for
  * all possible combinations of options, so be careful with your options
  * to GCC.  Best bet is to keep your fingers off the a.out GCC and use
diff -u --recursive --new-file v2.1.103/linux/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- v2.1.103/linux/include/asm-ppc/pgtable.h	Sat Apr 25 18:13:12 1998
+++ linux/include/asm-ppc/pgtable.h	Wed May 20 18:55:15 1998
@@ -64,7 +64,7 @@
  * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
  * based upon user/super access.  The TLB does not have accessed nor write
  * protect.  We assume that if the TLB get loaded with an entry it is
- * accessed, and overload the the changed bit for write protect.  We use
+ * accessed, and overload the changed bit for write protect.  We use
  * two bits in the software pte that are supposed to be set to zero in
  * the TLB entry (24 and 25) for these indicators.  Although the level 1
  * descriptor contains the guarded and writethrough/copyback bits, we can
diff -u --recursive --new-file v2.1.103/linux/include/asm-sparc64/firehose.h linux/include/asm-sparc64/firehose.h
--- v2.1.103/linux/include/asm-sparc64/firehose.h	Sat Aug 16 09:51:10 1997
+++ linux/include/asm-sparc64/firehose.h	Wed May 20 18:55:15 1998
@@ -29,7 +29,7 @@
 /*0x0100*/	u32	fhc_jtag_cmd;	/* FHC JTAG Command Register		*/
 };
 
-/* Part of same space of regs, but mapped seperately in PROM reg property
+/* Part of same space of regs, but mapped separately in PROM reg property
  * for the FHC, thus we have the following few structs...
  */
 struct fhc_ign_reg {
diff -u --recursive --new-file v2.1.103/linux/include/linux/arcdevice.h linux/include/linux/arcdevice.h
--- v2.1.103/linux/include/linux/arcdevice.h	Wed May 20 19:10:41 1998
+++ linux/include/linux/arcdevice.h	Thu May 21 13:45:02 1998
@@ -113,12 +113,12 @@
 
 /* macros to simplify debug checking */
 #define BUGLVL(x) if ((ARCNET_DEBUG_MAX)&arcnet_debug&(x))
-#define BUGMSG2(x,msg,args...) BUGLVL(x) printk(msg, ## args)
-#define BUGMSG(x,msg,args...) do { \
+#define BUGMSG2(x,msg,args...) do { BUGLVL(x) printk(msg, ## args); } while (0)
+#define BUGMSG(x,msg,args...) \
 	BUGMSG2(x,"%s%6s: " msg, \
             x==D_NORMAL	? KERN_WARNING : \
       x<=D_INIT_REASONS	? KERN_INFO    : KERN_DEBUG , \
-	dev->name , ## args); } while (0)
+	dev->name , ## args)
 
 
 #define SETMASK AINTMASK(lp->intmask)
diff -u --recursive --new-file v2.1.103/linux/include/linux/coda.h linux/include/linux/coda.h
--- v2.1.103/linux/include/linux/coda.h	Tue Mar 17 22:18:15 1998
+++ linux/include/linux/coda.h	Thu Jun  4 15:53:19 1998
@@ -148,8 +148,8 @@
 
 #ifndef _VUID_T_
 #define _VUID_T_
-typedef u_long vuid_t;
-typedef u_long vgid_t;
+typedef unsigned int vuid_t;
+typedef unsigned int vgid_t;
 #endif /*_VUID_T_ */
 
 #ifndef _CODACRED_T_
@@ -223,7 +223,7 @@
 #define CFS_PURGEUSER   ((u_long) 26)
 #define CFS_ZAPFILE     ((u_long) 27)
 #define CFS_ZAPDIR      ((u_long) 28)
-#define CFS_ZAPVNODE    ((u_long) 29)
+/* #define CFS_ZAPVNODE    ((u_long) 29)   obsolete */ 
 #define CFS_PURGEFID    ((u_long) 30)
 #define CFS_OPEN_BY_PATH ((u_long) 31)
 #define CFS_NCALLS 32
diff -u --recursive --new-file v2.1.103/linux/include/linux/coda_linux.h linux/include/linux/coda_linux.h
--- v2.1.103/linux/include/linux/coda_linux.h	Tue Mar 17 22:18:15 1998
+++ linux/include/linux/coda_linux.h	Thu Jun  4 15:53:19 1998
@@ -48,6 +48,7 @@
 char *coda_f2s(ViceFid *f);
 int coda_isroot(struct inode *i);
 int coda_fid_is_volroot(struct ViceFid *);
+int coda_fid_is_weird(struct ViceFid *fid);
 int coda_iscontrol(const char *name, size_t length);
 
 
diff -u --recursive --new-file v2.1.103/linux/include/linux/cyclades.h linux/include/linux/cyclades.h
--- v2.1.103/linux/include/linux/cyclades.h	Tue Apr 14 14:29:25 1998
+++ linux/include/linux/cyclades.h	Wed Jun  3 11:04:16 1998
@@ -1,4 +1,4 @@
-/* $Revision: 2.3 $$Date: 1998/03/16 18:01:12 $
+/* $Revision: 2.4 $$Date: 1998/06/01 12:09:53 $
  * linux/include/linux/cyclades.h
  *
  * This file is maintained by Ivan Passos <ivan@cyclades.com>, 
@@ -7,10 +7,14 @@
  *
  * This file contains the general definitions for the cyclades.c driver
  *$Log: cyclades.h,v $
+ *Revision 2.4  1998/06/01 12:09:53  ivan
+ *removed closing_wait2 from cyclades_port structure;
+ *
  *Revision 2.3  1998/03/16 18:01:12  ivan
  *changes in the cyclades_port structure to get it closer to the 
  *standard serial port structure;
  *added constants for new ioctls;
+ *
  *Revision 2.2  1998/02/17 16:50:00  ivan
  *changes in the cyclades_port structure (addition of shutdown_wait and 
  *chip_rev variables);
@@ -89,8 +93,8 @@
 #define CZ_DEF_POLL	(HZ/25)
 
 #define MAX_BOARD       4       /* Max number of boards */
-#define MAX_PORT        128     /* Max number of ports per board */
 #define MAX_DEV         256     /* Max number of ports total */
+#define	CYZ_MAX_SPEED	921600
 
 #define	CYZ_FIFO_SIZE	16
 
@@ -508,7 +512,6 @@
 	int                     x_char; /* to be pushed out ASAP */
 	int			close_delay;
 	unsigned short		closing_wait;
-	unsigned short		closing_wait2;
 	unsigned long		event;
 	unsigned long		last_active;
 	int			count;	/* # of fd on device */
@@ -544,11 +547,15 @@
 #define Cy_EVENT_OPEN_WAKEUP		4
 #define Cy_EVENT_SHUTDOWN_WAKEUP	5
 
-#define	CLOSING_WAIT_DELAY	30
+#define	CLOSING_WAIT_DELAY	30*HZ
+#define CY_CLOSING_WAIT_NONE	65535
+#define CY_CLOSING_WAIT_INF	0
+
 
 #define CyMAX_CHIPS_PER_CARD	8
 #define CyMAX_CHAR_FIFO		12
 #define CyPORTS_PER_CHIP	4
+#define	CD1400_MAX_SPEED	115200
 
 #define	CyISA_Ywin	0x2000
 
diff -u --recursive --new-file v2.1.103/linux/include/linux/delay.h linux/include/linux/delay.h
--- v2.1.103/linux/include/linux/delay.h	Sat Nov 29 15:08:21 1997
+++ linux/include/linux/delay.h	Thu May 21 14:24:09 1998
@@ -11,4 +11,27 @@
 
 #include <asm/delay.h>
 
+/*
+ * Using udelay() for intervals greater than a few milliseconds can
+ * risk overflow for high loops_per_sec (high bogomips) machines. The
+ * mdelay() provides a wrapper to prevent this.  For delays greater
+ * than MAX_UDELAY_MS milliseconds, the wrapper is used.  Architecture
+ * specific values can be defined in asm-???/delay.h as an override.
+ * The 2nd mdelay() definition ensures GCC will optimize away the 
+ * while loop for the common cases where n <= MAX_UDELAY_MS  --  Paul G.
+ */
+
+#ifndef MAX_UDELAY_MS
+#define MAX_UDELAY_MS	5
+#endif
+
+#ifdef notdef
+#define mdelay(n) (\
+	{unsigned long msec=(n); while (msec--) udelay(1000);})
+#else
+#define mdelay(n) (\
+	(__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
+	({unsigned long msec=(n); while (msec--) udelay(1000);}))
+#endif
+
 #endif /* defined(_LINUX_DELAY_H) */
diff -u --recursive --new-file v2.1.103/linux/include/linux/ip_fw.h linux/include/linux/ip_fw.h
--- v2.1.103/linux/include/linux/ip_fw.h	Thu May 14 19:47:43 1998
+++ linux/include/linux/ip_fw.h	Thu Jun  4 23:33:29 1998
@@ -60,7 +60,7 @@
 #define IP_FW_F_MARKABS	0x0008  /* Set the mark to fw_mark, not add. */
 #define IP_FW_F_WILDIF	0x0010  /* Need only match start of interface name. */
 #define IP_FW_F_NETLINK 0x0020  /* Redirect to netlink: 2.1.x only */
-#define IP_FW_F_MASK	0x002F	/* All possible flag bits mask   */
+#define IP_FW_F_MASK	0x003F	/* All possible flag bits mask   */
 
 /* Values for "fw_invflg" field. */
 #define IP_FW_INV_SRCIP 0x0001  /* Invert the sense of fw_src. */
diff -u --recursive --new-file v2.1.103/linux/include/linux/ipx.h linux/include/linux/ipx.h
--- v2.1.103/linux/include/linux/ipx.h	Mon Feb 23 18:12:12 1998
+++ linux/include/linux/ipx.h	Thu Jun  4 23:31:46 1998
@@ -82,6 +82,7 @@
 
 extern int ipxrtr_route_skb(struct sk_buff *);
 extern int ipx_if_offset(unsigned long ipx_net_number);
+extern void ipx_remove_socket(struct sock *sk);
 #endif /* def __KERNEL__ */
 
 #endif /* def _IPX_H_ */
diff -u --recursive --new-file v2.1.103/linux/include/linux/lp.h linux/include/linux/lp.h
--- v2.1.103/linux/include/linux/lp.h	Thu May  7 22:51:55 1998
+++ linux/include/linux/lp.h	Thu May 21 17:33:43 1998
@@ -129,6 +129,8 @@
 #endif
 	struct wait_queue *wait_q;
 	unsigned int last_error;
+	volatile unsigned int irq_detected:1;
+	volatile unsigned int irq_missed:1;
 };
 
 /*
diff -u --recursive --new-file v2.1.103/linux/include/linux/nfsd/export.h linux/include/linux/nfsd/export.h
--- v2.1.103/linux/include/linux/nfsd/export.h	Fri Feb  6 15:34:24 1998
+++ linux/include/linux/nfsd/export.h	Thu Jun  4 23:32:39 1998
@@ -60,7 +60,7 @@
 	struct svc_client *	ex_client;
 	int			ex_flags;
 	struct dentry *		ex_dentry;
-	dev_t			ex_dev;
+	kdev_t			ex_dev;
 	ino_t			ex_ino;
 	uid_t			ex_anon_uid;
 	gid_t			ex_anon_gid;
@@ -84,8 +84,8 @@
 void			exp_unlock(void);
 struct svc_client *	exp_getclient(struct sockaddr_in *sin);
 void			exp_putclient(struct svc_client *clp);
-struct svc_export *	exp_get(struct svc_client *clp, dev_t dev, ino_t ino);
-int			exp_rootfh(struct svc_client *, dev_t, ino_t,
+struct svc_export *	exp_get(struct svc_client *clp, kdev_t dev, ino_t ino);
+int			exp_rootfh(struct svc_client *, kdev_t, ino_t,
 					struct knfs_fh *);
 int			nfserrno(int errno);
 void			exp_nlmdetach(void);
diff -u --recursive --new-file v2.1.103/linux/include/linux/nfsd/nfsfh.h linux/include/linux/nfsd/nfsfh.h
--- v2.1.103/linux/include/linux/nfsd/nfsfh.h	Fri Feb  6 15:34:24 1998
+++ linux/include/linux/nfsd/nfsfh.h	Thu Jun  4 23:32:39 1998
@@ -30,8 +30,8 @@
 	struct dentry *		fb_dentry;	/* dentry cookie */
 	ino_t			fb_ino;		/* our inode number */
 	ino_t			fb_dirino;	/* dir inode number */
-	dev_t			fb_dev;		/* our device */
-	dev_t			fb_xdev;
+	kdev_t			fb_dev;		/* our device */
+	kdev_t			fb_xdev;
 	ino_t			fb_xino;
 };
 
@@ -80,7 +80,7 @@
 void	fh_compose(struct svc_fh *, struct svc_export *, struct dentry *);
 void	fh_update(struct svc_fh *);
 void	fh_put(struct svc_fh *);
-void	nfsd_fh_flush(dev_t);
+void	nfsd_fh_flush(kdev_t);
 void	nfsd_fh_init(void);
 void	nfsd_fh_free(void);
 
diff -u --recursive --new-file v2.1.103/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.1.103/linux/include/linux/sched.h	Wed May 20 19:10:41 1998
+++ linux/include/linux/sched.h	Thu Jun  4 23:31:03 1998
@@ -565,7 +565,7 @@
 
 extern inline int capable(int cap)
 {
-#if 0 /* not yet */
+#if 1 /* ok now */
 	if (cap_raised(current->cap_effective, cap))
 #else
 	if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
diff -u --recursive --new-file v2.1.103/linux/include/linux/serial_reg.h linux/include/linux/serial_reg.h
--- v2.1.103/linux/include/linux/serial_reg.h	Sun Nov  3 00:16:46 1996
+++ linux/include/linux/serial_reg.h	Mon May 25 10:32:52 1998
@@ -1,5 +1,5 @@
 /*
- * include/linux/serial.h
+ * include/linux/serial_reg.h
  *
  * Copyright (C) 1992, 1994 by Theodore Ts'o.
  * 
diff -u --recursive --new-file v2.1.103/linux/include/linux/socket.h linux/include/linux/socket.h
--- v2.1.103/linux/include/linux/socket.h	Thu May 14 19:47:44 1998
+++ linux/include/linux/socket.h	Thu Jun  4 23:31:02 1998
@@ -1,6 +1,8 @@
 #ifndef _LINUX_SOCKET_H
 #define _LINUX_SOCKET_H
 
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
 #include <asm/socket.h>			/* arch-dependent defines	*/
 #include <linux/sockios.h>		/* the SIOCxxx I/O controls	*/
 #include <linux/uio.h>			/* iovec support		*/
@@ -256,4 +258,5 @@
 extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr);
 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
 #endif
+#endif /* not kernel and not glibc */
 #endif /* _LINUX_SOCKET_H */
diff -u --recursive --new-file v2.1.103/linux/include/linux/soundcard.h linux/include/linux/soundcard.h
--- v2.1.103/linux/include/linux/soundcard.h	Tue Dec  9 09:49:59 1997
+++ linux/include/linux/soundcard.h	Wed May 20 18:55:15 1998
@@ -606,7 +606,7 @@
  * 
  *	APF_NORMAL (the default) and APF_NETWORK make the driver to cleanup the
  *	playback buffer whenever an underrun occurs. This consumes some time
- *	preven's looping the existing buffer.
+ *	prevents looping the existing buffer.
  *	APF_CPUINTENS is intended to be set by CPU intensive applications which
  *	are likely to run out of time occasionally. In this mode the buffer cleanup is
  *	disabled which saves CPU time but also let's the previous buffer content to
diff -u --recursive --new-file v2.1.103/linux/include/linux/stat.h linux/include/linux/stat.h
--- v2.1.103/linux/include/linux/stat.h	Mon Sep 30 07:47:39 1996
+++ linux/include/linux/stat.h	Mon May 25 10:32:52 1998
@@ -7,6 +7,8 @@
 
 #endif
 
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
 #define S_IFMT  00170000
 #define S_IFSOCK 0140000
 #define S_IFLNK	 0120000
@@ -41,6 +43,8 @@
 #define S_IROTH 00004
 #define S_IWOTH 00002
 #define S_IXOTH 00001
+
+#endif
 
 #ifdef __KERNEL__
 #define S_IRWXUGO	(S_IRWXU|S_IRWXG|S_IRWXO)
diff -u --recursive --new-file v2.1.103/linux/include/linux/sunrpc/sched.h linux/include/linux/sunrpc/sched.h
--- v2.1.103/linux/include/linux/sunrpc/sched.h	Fri Feb  6 15:33:04 1998
+++ linux/include/linux/sunrpc/sched.h	Thu Jun  4 23:31:02 1998
@@ -39,11 +39,11 @@
 	/*
 	 * RPC call state
 	 */
-	u32			tk_proc;	/* procedure number */
-	u32 *			tk_buffer;	/* XDR buffer */
+	__u32			tk_proc;	/* procedure number */
+	__u32 *			tk_buffer;	/* XDR buffer */
 	void *			tk_argp;	/* argument storage */
 	void *			tk_resp;	/* result storage */
-	u8			tk_garb_retry,
+	__u8			tk_garb_retry,
 				tk_cred_retry,
 				tk_suid_retry;
 
diff -u --recursive --new-file v2.1.103/linux/include/linux/zorro.h linux/include/linux/zorro.h
--- v2.1.103/linux/include/linux/zorro.h	Thu Mar 26 15:57:06 1998
+++ linux/include/linux/zorro.h	Wed May 20 18:55:15 1998
@@ -631,7 +631,7 @@
 
     /*
      *  GVP identifies most of its products through the 'extended product code'
-     *  (epc). The epc has to be and'ed with the GVP_PRODMASK before the
+     *  (epc). The epc has to be ANDed with the GVP_PRODMASK before the
      *  identification.
      */
 
diff -u --recursive --new-file v2.1.103/linux/include/net/ip.h linux/include/net/ip.h
--- v2.1.103/linux/include/net/ip.h	Thu May 14 19:47:44 1998
+++ linux/include/net/ip.h	Thu Jun  4 23:33:15 1998
@@ -23,7 +23,6 @@
 #define _IP_H
 
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/ip.h>
diff -u --recursive --new-file v2.1.103/linux/init/main.c linux/init/main.c
--- v2.1.103/linux/init/main.c	Wed May 20 19:10:42 1998
+++ linux/init/main.c	Fri May 22 19:44:07 1998
@@ -1070,7 +1070,6 @@
 	signals_init();
 	inode_init();
 	file_table_init();
-	sock_init();
 #if defined(CONFIG_SYSVIPC)
 	ipc_init();
 #endif
@@ -1083,6 +1082,7 @@
 #ifdef __SMP__
 	smp_init();
 #endif
+	sock_init();
 #ifdef CONFIG_SYSCTL
 	sysctl_init();
 #endif
diff -u --recursive --new-file v2.1.103/linux/kernel/capability.c linux/kernel/capability.c
--- v2.1.103/linux/kernel/capability.c	Fri May  8 23:14:57 1998
+++ linux/kernel/capability.c	Thu May 21 16:58:47 1998
@@ -25,9 +25,7 @@
      copy_to_user(u, k, sizeof(*k));
 }
 
-#ifdef __SMP__
-static spinlock_t task_capability_lock;
-#endif
+spinlock_t task_capability_lock;
 
 /*
  * For sys_getproccap() and sys_setproccap(), any of the three
diff -u --recursive --new-file v2.1.103/linux/kernel/module.c linux/kernel/module.c
--- v2.1.103/linux/kernel/module.c	Thu May  7 22:51:55 1998
+++ linux/kernel/module.c	Wed May 20 18:55:16 1998
@@ -323,7 +323,7 @@
 		dep->ref = mod;
 		dep->next_ref = d->refs;
 		d->refs = dep;
-		/* Being referenced by a dependant module counts as a 
+		/* Being referenced by a dependent module counts as a 
 		   use as far as kmod is concerned.  */
 		d->flags |= MOD_USED_ONCE;
 	}
diff -u --recursive --new-file v2.1.103/linux/kernel/panic.c linux/kernel/panic.c
--- v2.1.103/linux/kernel/panic.c	Tue Mar 10 10:03:36 1998
+++ linux/kernel/panic.c	Thu May 21 14:24:09 1998
@@ -35,7 +35,6 @@
 {
 	static char buf[1024];
 	va_list args;
-	int i;
 
 	va_start(args, fmt);
 	vsprintf(buf, fmt, args);
@@ -60,8 +59,7 @@
 		 * We can't use the "normal" timers since we just panicked..
 	 	 */
 		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
-		for(i = 0; i < (panic_timeout*1000); i++)
-			udelay(1000);
+		mdelay(panic_timeout*1000);
 		/*
 		 *	Should we run the reboot notifier. For the moment Im
 		 *	choosing not too. It might crash, be corrupt or do
diff -u --recursive --new-file v2.1.103/linux/kernel/sched.c linux/kernel/sched.c
--- v2.1.103/linux/kernel/sched.c	Wed May 20 19:10:42 1998
+++ linux/kernel/sched.c	Mon Jun  1 21:44:36 1998
@@ -142,6 +142,22 @@
 	prev->next_run = p;
 }
 
+static inline void move_first_runqueue(struct task_struct * p)
+{
+	struct task_struct *next = p->next_run;
+	struct task_struct *prev = p->prev_run;
+
+	/* remove from list */
+	next->prev_run = prev;
+	prev->next_run = next;
+	/* add back to list */
+	p->prev_run = &init_task;
+	next = init_task.next_run;
+	init_task.next_run = p;
+	p->next_run = next;
+	next->prev_run = p;
+}
+
 /*
  * The tasklist_lock protects the linked list of processes.
  *
@@ -1130,7 +1146,7 @@
  
 asmlinkage int sys_getpid(void)
 {
-	/* This is SMP safe - current->pid doesnt change */
+	/* This is SMP safe - current->pid doesn't change */
 	return current->pid;
 }
 
@@ -1329,7 +1345,7 @@
 	p->policy = policy;
 	p->rt_priority = lp.sched_priority;
 	if (p->next_run)
-		move_last_runqueue(p);
+		move_first_runqueue(p);
 
 	need_resched = 1;
 
diff -u --recursive --new-file v2.1.103/linux/kernel/sys.c linux/kernel/sys.c
--- v2.1.103/linux/kernel/sys.c	Wed May 20 19:10:42 1998
+++ linux/kernel/sys.c	Mon May 25 12:17:26 1998
@@ -448,7 +448,7 @@
 	if (current->euid != old_euid)
 		current->dumpable = 0;
 
-	if(new_ruid != old_ruid) {
+       if (new_ruid != old_ruid) {
 		/* See comment above about NPROC rlimit issues... */
 		charge_uid(current, -1);
 		current->uid = new_ruid;
@@ -473,7 +473,7 @@
 	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 (!capable(CAP_SETUID)) {
 		if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
 		    (ruid != current->euid) && (ruid != current->suid))
 			return -EPERM;
@@ -523,7 +523,7 @@
  */
 asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
 {
-	if (current->uid != 0 && current->euid != 0 && current->suid != 0) {
+       if (!capable(CAP_SETGID)) {
 		if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
 		    (rgid != current->egid) && (rgid != current->sgid))
 			return -EPERM;
@@ -578,13 +578,13 @@
 		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.
-         */
+	 * 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) {
@@ -749,7 +749,7 @@
 	read_lock(&tasklist_lock);
 	for_each_task(p) {
 		if (p->pgrp == current->pid)
-		        goto out;
+			goto out;
 	}
 
 	current->leader = 1;
@@ -779,7 +779,7 @@
 	i = current->ngroups;
 	if (gidsetsize) {
 		if (i > gidsetsize)
-		        return -EINVAL;
+			return -EINVAL;
 		if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
 			return -EFAULT;
 	}
@@ -994,7 +994,7 @@
 }
     
 asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
-                         unsigned long arg4, unsigned long arg5)
+			 unsigned long arg4, unsigned long arg5)
 {
 	int error = 0;
 	int sig;
@@ -1003,15 +1003,15 @@
 		case PR_SET_PDEATHSIG:
 			sig = arg2;
 			if (sig > _NSIG) {
-                        	error = -EINVAL;
-                                break;
-                        }
-                        current->pdeath_signal = sig;
-                        break;
+				error = -EINVAL;
+				break;
+			}
+			current->pdeath_signal = sig;
+			break;
 		default:
 			error = -EINVAL;
 			break;
-        }
-        return error;
+	}
+	return error;
 }
 
diff -u --recursive --new-file v2.1.103/linux/net/802/p8022.c linux/net/802/p8022.c
--- v2.1.103/linux/net/802/p8022.c	Mon Feb 23 18:12:12 1998
+++ linux/net/802/p8022.c	Wed May 20 18:55:16 1998
@@ -1,6 +1,6 @@
 /*
- *	NET3:	Support for 802.2 demultiplexing off ethernet (Token ring
- *		is kept seperate see p8022tr.c)
+ *	NET3:	Support for 802.2 demultiplexing off Ethernet (Token ring
+ *		is kept separate see p8022tr.c)
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
  *		as published by the Free Software Foundation; either version
diff -u --recursive --new-file v2.1.103/linux/net/Changes linux/net/Changes
--- v2.1.103/linux/net/Changes	Thu Jul 31 13:09:18 1997
+++ linux/net/Changes	Wed May 20 18:55:16 1998
@@ -23,7 +23,7 @@
 o	eql load balancing driver.			[TESTED]
 o	Token ring drivers.				[TESTED]
 o	IPIP and tunnels				[TESTED]
-o	Fix ethernet/token ring promisc broadcast error [TESTED]
+o	Fix Ethernet/token ring promisc broadcast error [TESTED]
 	(pkt_type set to OTHERHOST in error).
 o	Fixed bug in the routing caches			[TESTED]
 o	Protocol header cache support			[TESTED]
@@ -100,7 +100,7 @@
 
 ------->>>>>  NET3 030  <<<<<----------
 
-o	Long word align ethernet IP headers (64byte align for pentium) [TESTED]
+o	Long word align Ethernet IP headers (64byte align for Pentium) [TESTED]
 		(less helpful than I'd have liked)
 o	Fixed variable length header support to really work	[TESTED]
 o	Mend appletalk/ipx partially			[TESTED]
@@ -132,7 +132,7 @@
 	slows fragmented I/O down, speeds up smaller
 	packets. UDP send ttcp can now touch 7.5Mbyte/sec
 	with nothing else going on. UDP recv is slower 8( [TESTED]
-o	Fixed and enabled ethernet header caches	[TESTED]
+o	Fixed and enabled Ethernet header caches	[TESTED]
 o	Removed junk from igmp				[TESTED]
 o	Obscure UDP/copy&sum bug fix			[TESTED]
 o	Fixed multicast					[TESTED]
@@ -195,7 +195,7 @@
 o	AF_UNIX smarter buffer driving			[TESTED]
 o	AF_UNIX full BSD semantics on STREAM writes	[TESTED]
 o	IOVEC's support repeated calls to copy more	[TESTED]
-o	Zero fragment 'solaris nfs' bug fixed <Werner>  [TESTED]
+o	Zero fragment 'Solaris NFS' bug fixed <Werner>  [TESTED]
 o	NetROM supports sendmsg/recvmsg			[TESTED]
 o	Sendmsg verify_iovec bugfix			[TESTED]
 o	ARP PERM is really permanent now <Craig>	[TESTED]
@@ -416,8 +416,8 @@
 [done]
 
 4.	RFC1323. These are the extensions for very fast nets.
-RFC1323 will be useful for Linux talking to systems over 100Mb/sec
-ethernet and over ATM as it allows large windows and protects from some
+RFC1323 will be useful for Linux talking to systems over 100 Mb/sec
+Ethernet and over ATM as it allows large windows and protects from some
 potential high speed TCP problems.
 [In progress]
 
diff -u --recursive --new-file v2.1.103/linux/net/README linux/net/README
--- v2.1.103/linux/net/README	Thu May 14 19:47:44 1998
+++ linux/net/README	Thu May 21 13:46:14 1998
@@ -12,7 +12,7 @@
 ethernet		alan@lxorguk.ukuu.org.uk
 ipv4			davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
 ipv6			davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
-ipx			alan@lxorguk.ukuu.org.uk,greg@caldera.com
+ipx/spx			Jay.Schulist@spacs.k12.wi.us
 lapb			g4klx@g4klx.demon.co.uk
 netrom			g4klx@g4klx.demon.co.uk
 rose			g4klx@g4klx.demon.co.uk
diff -u --recursive --new-file v2.1.103/linux/net/TUNABLE linux/net/TUNABLE
--- v2.1.103/linux/net/TUNABLE	Thu May 15 16:48:05 1997
+++ linux/net/TUNABLE	Wed May 20 18:55:16 1998
@@ -10,7 +10,7 @@
 MAX_LINKS		Maximum number of netlink minor devices. (1-32)
 MAX_QBYTES		Size of a netlink device queue (tunable)
 RIF_TABLE_SIZE		Token ring RIF cache size (tunable)
-AARP_HASH_SIZE		Size of appletalk hash table (tunable)
+AARP_HASH_SIZE		Size of Appletalk hash table (tunable)
 AX25_DEF_T1		AX.25 parameters. These are all tunable via
 AX25_DEF_T2		SIOCAX25SETPARMS
 AX25_DEF_T3		T1-T3,N2 have the meanings in the specification
diff -u --recursive --new-file v2.1.103/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v2.1.103/linux/net/appletalk/ddp.c	Fri May  8 23:14:57 1998
+++ linux/net/appletalk/ddp.c	Wed May 20 18:55:16 1998
@@ -254,7 +254,7 @@
  */
 
 /*
- * Drop a device. Doesn't drop any of its routes - that is the the callers
+ * Drop a device. Doesn't drop any of its routes - that is the caller's
  * problem. Called when we down the interface or delete the address.
  */
 static void atif_drop_device(struct device *dev)
diff -u --recursive --new-file v2.1.103/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- v2.1.103/linux/net/ax25/af_ax25.c	Fri May  8 23:14:57 1998
+++ linux/net/ax25/af_ax25.c	Wed May 20 18:55:16 1998
@@ -80,7 +80,7 @@
  *						datagrams per socket.
  *	AX.25 033	Jonathan(G4KLX)		Removed auto-router.
  *			Hans(PE1AYX)		Converted to Module.
- *			Joerg(DL1BKE)		Moved BPQ Ethernet to seperate driver.
+ *			Joerg(DL1BKE)		Moved BPQ Ethernet to separate driver.
  *	AX.25 034	Jonathan(G4KLX)		2.1 changes
  *			Alan(GW4PTS)		Small POSIXisations
  *	AX.25 035	Alan(GW4PTS)		Started fixing to the new
diff -u --recursive --new-file v2.1.103/linux/net/ax25/ax25_route.c linux/net/ax25/ax25_route.c
--- v2.1.103/linux/net/ax25/ax25_route.c	Thu Feb 12 20:56:14 1998
+++ linux/net/ax25/ax25_route.c	Wed May 20 18:55:17 1998
@@ -35,7 +35,7 @@
  *					"SIOCAX25OPTRT" to set IP mode and a 'permanent' flag
  *					on routes.
  *	AX.25 033	Jonathan(G4KLX)	Remove auto-router.
- *			Joerg(DL1BKE)	Moved BPQ Ethernet driver to seperate device.
+ *			Joerg(DL1BKE)	Moved BPQ Ethernet driver to separate device.
  *	AX.25 035	Frederic(F1OAT)	Support for pseudo-digipeating.
  *			Jonathan(G4KLX)	Support for packet forwarding.
  */
diff -u --recursive --new-file v2.1.103/linux/net/ax25/ax25_timer.c linux/net/ax25/ax25_timer.c
--- v2.1.103/linux/net/ax25/ax25_timer.c	Mon Jul  7 08:19:59 1997
+++ linux/net/ax25/ax25_timer.c	Wed May 20 18:55:17 1998
@@ -18,7 +18,7 @@
  *	AX.25 032	Joerg(DL1BKE)	Fixed DAMA timeout bug
  *	AX.25 033	Jonathan(G4KLX)	Modularisation functions.
  *	AX.25 035	Frederic(F1OAT)	Support for pseudo-digipeating.
- *	AX.25 036	Jonathan(G4KLX)	Split Standard and DAMA code into seperate files.
+ *	AX.25 036	Jonathan(G4KLX)	Split Standard and DAMA code into separate files.
  *			Joerg(DL1BKE)	Fixed DAMA Slave. We are *required* to start with
  *					standard AX.25 mode.
  *	AX.25 037	Jonathan(G4KLX)	New timer architecture.
diff -u --recursive --new-file v2.1.103/linux/net/ipv4/syncookies.c linux/net/ipv4/syncookies.c
--- v2.1.103/linux/net/ipv4/syncookies.c	Mon Apr  6 17:41:01 1998
+++ linux/net/ipv4/syncookies.c	Mon May 25 10:32:52 1998
@@ -26,104 +26,74 @@
 static unsigned long tcp_lastsynq_overflow;
 
 /* 
- * This table has to be sorted. Only 8 entries are allowed and the
- * last entry has to be duplicated.
+ * This table has to be sorted and terminated with (__u16)-1.
  * XXX generate a better table.
  * Unresolved Issues: HIPPI with a 64k MSS is not well supported.
  */
 static __u16 const msstab[] = {
-	64,
-	256,	
-	512,	
-	536,
-	1024,	
-	1440,	
-	1460,	
-	4312,
-	4312 
+	64-1,
+	256-1,	
+	512-1,
+	536-1,
+	1024-1,	
+	1440-1,
+	1460-1,
+	4312-1,
+	(__u16)-1
 };
-
-static __u32 make_syncookie(struct sk_buff *skb,  __u32 counter, __u32 seq)
-{
-	__u32 z;
-
-	z = secure_tcp_syn_cookie(skb->nh.iph->saddr, skb->nh.iph->daddr,
-				  skb->h.th->source, skb->h.th->dest,
-				  seq, 
-				  counter);
-
-#if 0
-	printk(KERN_DEBUG 
-	       "msc: z=%u,cnt=%u,seq=%u,sadr=%u,dadr=%u,sp=%u,dp=%u\n",
-	       z,counter,seq,
-	       skb->nh.iph->saddr,skb->nh.iph->daddr,
-	       ntohs(skb->h.th->source), ntohs(skb->h.th->dest));
-#endif
-
-	return z;
-}
+/* The number doesn't include the -1 terminator */
+#define NUM_MSS (sizeof(msstab)/sizeof(msstab[0]) - 1)
 
 /*
- * Generate a syncookie. 
+ * Generate a syncookie.  mssp points to the mss, which is returned
+ * rounded down to the value encoded in the cookie.
  */
 __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, 
 			      __u16 *mssp)
 {
-	int i; 
-	__u32 isn; 
-	const __u16 mss = *mssp, *w; 
+	int mssind;
+	const __u16 mss = *mssp;
 
 	tcp_lastsynq_overflow = jiffies;
-
-	isn = make_syncookie(skb, (jiffies/HZ) >> 6, ntohl(skb->h.th->seq));
-	
-	/* XXX sort msstab[] by probability? */
-	w = msstab;
-	for (i = 0; i < 8; i++) 
-		if (mss >= *w && mss < *++w)
-			goto found;
-	i--;
-found:
-	*mssp = w[-1]; 
+	/* XXX sort msstab[] by probability?  Binary search? */
+	for (mssind = 0; mss > msstab[mssind+1]; mssind++)
+		;
+	*mssp = msstab[mssind]+1;
 
 	net_statistics.SyncookiesSent++;
 
-	isn |= i; 
-	return isn; 
+	return secure_tcp_syn_cookie(skb->nh.iph->saddr, skb->nh.iph->daddr,
+				     skb->h.th->source, skb->h.th->dest,
+				     ntohl(skb->h.th->seq),
+				     jiffies / (HZ*60), mssind);
 }
 
-/* This value should be dependent on TCP_TIMEOUT_INIT and 
- * sysctl_tcp_retries1. It's a rather complicated formula 
- * (exponential backoff) to compute at runtime so it's currently hardcoded
- * here.
+/* 
+ * This (misnamed) value is the age of syncookie which is permitted.
+ * Its ideal value should be dependent on TCP_TIMEOUT_INIT and
+ * sysctl_tcp_retries1. It's a rather complicated formula (exponential
+ * backoff) to compute at runtime so it's currently hardcoded here.
  */
 #define COUNTER_TRIES 4
-
 /*  
  * Check if a ack sequence number is a valid syncookie. 
+ * Return the decoded mss if it is, or 0 if not.
  */
 static inline int cookie_check(struct sk_buff *skb, __u32 cookie) 
 {
-	int mssind; 
-	int i; 
-	__u32 counter; 
 	__u32 seq; 
+	__u32 mssind;
 
-  	if ((jiffies - tcp_lastsynq_overflow) > TCP_TIMEOUT_INIT
-	    && tcp_lastsynq_overflow) {
+  	if ((jiffies - tcp_lastsynq_overflow) > TCP_TIMEOUT_INIT)
 		return 0; 
-	}
-
-	mssind = cookie & 7;
-	cookie &= ~7;
 
-	counter = (jiffies/HZ)>>6; 
 	seq = ntohl(skb->h.th->seq)-1; 
-	for (i = 0; i < COUNTER_TRIES; i++)
-	    if (make_syncookie(skb, counter-i, seq) == cookie)
-		    return msstab[mssind];	
+	mssind = check_tcp_syn_cookie(cookie,
+				      skb->nh.iph->saddr, skb->nh.iph->daddr,
+				      skb->h.th->source, skb->h.th->dest,
+				      seq, jiffies/(HZ*60), COUNTER_TRIES);
 
-	return 0;
+	return mssind < NUM_MSS ? msstab[mssind]+1 : 0;
 }
 
 extern struct or_calltable or_ipv4;
diff -u --recursive --new-file v2.1.103/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.1.103/linux/net/ipv6/af_inet6.c	Thu May 14 19:47:45 1998
+++ linux/net/ipv6/af_inet6.c	Thu May 21 13:45:01 1998
@@ -66,6 +66,11 @@
 extern int afinet6_get_info(char *, char **, off_t, int, int);
 #endif
 
+#ifdef CONFIG_SYSCTL
+extern void ipv6_sysctl_register(void);
+extern void ipv6_sysctl_unregister(void);
+#endif
+
 static int inet6_create(struct socket *sock, int protocol)
 {
 	struct sock *sk;
diff -u --recursive --new-file v2.1.103/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v2.1.103/linux/net/ipx/af_ipx.c	Fri May  8 23:14:57 1998
+++ linux/net/ipx/af_ipx.c	Thu May 21 13:46:14 1998
@@ -11,32 +11,32 @@
  *	work I am currently employed to do there.
  *
  *	All the material in this file is subject to the Gnu license version 2.
- *	Neither Alan Cox nor the Swansea University Computer Society admit liability
- *	nor provide warranty for any of this software. This material is provided
- *	as is and at no charge.
+ *	Neither Alan Cox nor the Swansea University Computer Society admit 
+ *	liability nor provide warranty for any of this software. This material
+ *	is provided as is and at no charge.
  *
  *	Revision 0.21:	Uses the new generic socket option code.
  *	Revision 0.22:	Gcc clean ups and drop out device registration. Use the
  *			new multi-protocol edition of hard_header
- *	Revision 0.23:  IPX /proc by Mark Evans.
- *     			Adding a route will overwrite any existing route to the same
- *			network.
+ *	Revision 0.23:  IPX /proc by Mark Evans. Adding a route will
+ *     			will overwrite any existing route to the same network.
  *	Revision 0.24:	Supports new /proc with no 4K limit
  *	Revision 0.25:	Add ephemeral sockets, passive local network
  *			identification, support for local net 0 and
  *			multiple datalinks <Greg Page>
- *	Revision 0.26:  Device drop kills IPX routes via it. (needed for modules)
+ *	Revision 0.26:  Device drop kills IPX routes via it. (needed for module)
  *	Revision 0.27:  Autobind <Mark Evans>
  *	Revision 0.28:  Small fix for multiple local networks <Thomas Winder>
  *	Revision 0.29:  Assorted major errors removed <Mark Evans>
  *			Small correction to promisc mode error fix <Alan Cox>
- *			Asynchronous I/O support.
- *			Changed to use notifiers and the newer packet_type stuff.
- *			Assorted major fixes <Alejandro Liu>
+ *			Asynchronous I/O support. Changed to use notifiers
+ *			and the newer packet_type stuff. Assorted major
+ *			fixes <Alejandro Liu>
  *	Revision 0.30:	Moved to net/ipx/...	<Alan Cox>
  *			Don't set address length on recvfrom that errors.
  *			Incorrect verify_area.
- *	Revision 0.31:	New sk_buffs. This still needs a lot of testing. <Alan Cox>
+ *	Revision 0.31:	New sk_buffs. This still needs a lot of 
+ *			testing. <Alan Cox>
  *	Revision 0.32:  Using sock_alloc_send_skb, firewall hooks. <Alan Cox>
  *			Supports sendmsg/recvmsg
  *	Revision 0.33:	Internal network support, routing changes, uses a
@@ -47,8 +47,8 @@
  *	Revision 0.36:	Internal bump up for 2.1
  *	Revision 0.37:	Began adding POSIXisms.
  *	Revision 0.38:  Asynchronous socket stuff made current.
- *	Revision 0.39: 	SPX interfaces
- *	Revision 0.40:	Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
+ *	Revision 0.39:  SPX interfaces
+ *	Revision 0.40:  Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
  *
  *	Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT
  *	pair. Also, now usage count is managed this way
@@ -65,6 +65,7 @@
  */
 
 #include <linux/config.h>
+#if defined (CONFIG_IPX) || defined (CONFIG_IPX_MODULE)
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/types.h>
@@ -105,44 +106,43 @@
 static char		ipxcfg_auto_create_interfaces = 0;
 
 /* Global Variables */
-static struct datalink_proto	*p8022_datalink = NULL;
-static struct datalink_proto	*p8022tr_datalink = NULL;
-static struct datalink_proto	*pEII_datalink = NULL;
-static struct datalink_proto	*p8023_datalink = NULL;
-static struct datalink_proto	*pSNAP_datalink = NULL;
+static struct datalink_proto	*p8022_datalink 	= NULL;
+static struct datalink_proto	*p8022tr_datalink 	= NULL;
+static struct datalink_proto	*pEII_datalink 		= NULL;
+static struct datalink_proto	*p8023_datalink 	= NULL;
+static struct datalink_proto	*pSNAP_datalink 	= NULL;
 
 static struct proto_ops ipx_dgram_ops;
 
 static struct net_proto_family *spx_family_ops;
 
-static ipx_route 	*ipx_routes = NULL;
-static ipx_interface	*ipx_interfaces = NULL;
-static ipx_interface	*ipx_primary_net = NULL;
-static ipx_interface	*ipx_internal_net = NULL;
+static ipx_route 	*ipx_routes 		= NULL;
+static ipx_interface	*ipx_interfaces 	= NULL;
+static ipx_interface	*ipx_primary_net 	= NULL;
+static ipx_interface	*ipx_internal_net 	= NULL;
 
 static int ipxcfg_set_auto_create(char val)
 {
-	if (ipxcfg_auto_create_interfaces != val)
+	if(ipxcfg_auto_create_interfaces != val)
 	{
-		if (val)
-		{
+		if(val)
 			MOD_INC_USE_COUNT;
-		}
 		else
-		{
 			MOD_DEC_USE_COUNT;
-		}
+
 		ipxcfg_auto_create_interfaces = val;
 	}
-	return 0;
+
+	return (0);
 }
 
 static int ipxcfg_set_auto_select(char val)
 {
 	ipxcfg_auto_select_primary = val;
-	if (val && (ipx_primary_net == NULL))
+	if(val && (ipx_primary_net == NULL))
 		ipx_primary_net = ipx_interfaces;
-	return 0;
+
+	return (0);
 }
 
 static int ipxcfg_get_config_data(ipx_config_data *arg)
@@ -151,84 +151,86 @@
 
 	vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces;
 	vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary;
-	return copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0;
-}
 
+	return (copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0);
+}
 
-/***********************************************************************************************************************\
-*															*
-*						Handlers for the socket list.						*
-*															*
-\***********************************************************************************************************************/
+/**************************************************************************\
+*                                                                          *
+* Handlers for the socket list.                                            *
+*                                                                          *
+\**************************************************************************/
 
 /*
- *	Note: Sockets may not be removed _during_ an interrupt or inet_bh
- *	handler using this technique. They can be added although we do not
- *	use this facility.
+ * Note: Sockets may not be removed _during_ an interrupt or inet_bh
+ * handler using this technique. They can be added although we do not
+ * use this facility.
  */
 
 void ipx_remove_socket(struct sock *sk)
 {
-	struct sock	*s;
-	ipx_interface	*intrfc;
-	unsigned long	flags;
+	struct sock *s;
+	ipx_interface *intrfc;
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
 
 	/* Determine interface with which socket is associated */
 	intrfc = sk->protinfo.af_ipx.intrfc;
-	if (intrfc == NULL) {
+	if(intrfc == NULL)
+	{
 		restore_flags(flags);
 		return;
 	}
 
-	s=intrfc->if_sklist;
-	if(s==sk) {
-		intrfc->if_sklist=s->next;
+	s = intrfc->if_sklist;
+	if(s == sk)
+	{
+		intrfc->if_sklist = s->next;
 		restore_flags(flags);
 		return;
 	}
 
-	while(s && s->next) {
-		if(s->next==sk) {
-			s->next=sk->next;
+	while(s && s->next)
+	{
+		if(s->next == sk)
+		{
+			s->next = sk->next;
 			restore_flags(flags);
 			return;
 		}
-		s=s->next;
+		s = s->next;
 	}
 	restore_flags(flags);
 }
 
 /*
- *	This is only called from user mode. Thus it protects itself against
- *	interrupt users but doesn't worry about being called during work.
- *	Once it is removed from the queue no interrupt or bottom half will
- *	touch it and we are (fairly 8-) ) safe.
+ * This is only called from user mode. Thus it protects itself against
+ * interrupt users but doesn't worry about being called during work.
+ * Once it is removed from the queue no interrupt or bottom half will
+ * touch it and we are (fairly 8-) ) safe.
  */
-
 static void ipx_destroy_socket(struct sock *sk)
 {
 	struct sk_buff	*skb;
 
 	ipx_remove_socket(sk);
-	while((skb=skb_dequeue(&sk->receive_queue))!=NULL) {
+	while((skb = skb_dequeue(&sk->receive_queue)) != NULL)
 		kfree_skb(skb);
-	}
 
 	sk_free(sk);
 }
 
-/* The following code is used to support IPX Interfaces (IPXITF).  An
+/* 
+ * The following code is used to support IPX Interfaces (IPXITF).  An
  * IPX interface is defined by a physical device and a frame type.
  */
-
 static ipx_route * ipxrtr_lookup(__u32);
 
 static void ipxitf_clear_primary_net(void)
 {
-	if (ipxcfg_auto_select_primary && (ipx_interfaces != NULL))
+	if(ipxcfg_auto_select_primary && (ipx_interfaces != NULL))
 		ipx_primary_net = ipx_interfaces;
 	else
 		ipx_primary_net = NULL;
@@ -238,36 +240,38 @@
 {
 	ipx_interface	*i;
 
-	for (i=ipx_interfaces;
-		i && ((i->if_dev!=dev) || (i->if_dlink_type!=datalink));
-		i=i->if_next)
+	for(i = ipx_interfaces;
+		i && ((i->if_dev != dev) || (i->if_dlink_type != datalink));
+		i = i->if_next)
 		;
-	return i;
+
+	return (i);
 }
 
 static ipx_interface *ipxitf_find_using_net(__u32 net)
 {
 	ipx_interface	*i;
 
-	if (!net)
-		return ipx_primary_net;
+	if(!net)
+		return (ipx_primary_net);
 
-	for (i=ipx_interfaces; i && (i->if_netnum!=net); i=i->if_next)
+	for(i = ipx_interfaces; i && (i->if_netnum != net); i = i->if_next)
 		;
 
-	return i;
+	return (i);
 }
 
 /* Sockets are bound to a particular IPX interface. */
 static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk)
 {
-	struct sock	*s;
+	struct sock *s;
 
 	sk->protinfo.af_ipx.intrfc = intrfc;
 	sk->next = NULL;
-	if (intrfc->if_sklist == NULL) {
+	if(intrfc->if_sklist == NULL)
 		intrfc->if_sklist = sk;
-	} else {
+	else
+	{
 		for (s = intrfc->if_sklist; s->next != NULL; s = s->next)
 			;
 		s->next = sk;
@@ -276,14 +280,14 @@
 
 static struct sock *ipxitf_find_socket(ipx_interface *intrfc, unsigned short port)
 {
-	struct sock	*s;
+	struct sock *s;
 
-	for (s=intrfc->if_sklist;
+	for(s = intrfc->if_sklist;
 		(s != NULL) && (s->protinfo.af_ipx.port != port);
-		s=s->next)
+		s = s->next)
 		;
 
-	return s;
+	return (s);
 }
 
 #ifdef CONFIG_IPX_INTERN
@@ -293,16 +297,17 @@
 {
 	struct sock *s = intrfc->if_sklist;
 
-	while (s != NULL)
+	while(s != NULL)
 	{
-		if (   (s->protinfo.af_ipx.port == port)
+		if((s->protinfo.af_ipx.port == port)
 		    && (memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN) == 0))
 		{
 			break;
 		}
 		s = s->next;
 	}
-	return s;
+
+	return (s);
 }
 #endif
 
@@ -310,14 +315,15 @@
 
 static void ipxitf_down(ipx_interface *intrfc)
 {
-	ipx_interface	*i;
-	struct sock	*s, *t;
+	ipx_interface *i;
+	struct sock *s, *t;
 
 	/* Delete all routes associated with this interface */
 	ipxrtr_del_routes(intrfc);
 
 	/* error sockets */
-	for (s = intrfc->if_sklist; s != NULL; ) {
+	for(s = intrfc->if_sklist; s != NULL; )
+	{
 		s->err = ENOLINK;
 		s->error_report(s);
 		s->protinfo.af_ipx.intrfc = NULL;
@@ -330,28 +336,27 @@
 	intrfc->if_sklist = NULL;
 
 	/* remove this interface from list */
-	if (intrfc == ipx_interfaces) {
+	if(intrfc == ipx_interfaces)
 		ipx_interfaces = intrfc->if_next;
-	} else {
-		for (i = ipx_interfaces;
+	else
+	{
+		for(i = ipx_interfaces;
 			(i != NULL) && (i->if_next != intrfc);
 			i = i->if_next)
 			;
-		if ((i != NULL) && (i->if_next == intrfc))
+		if((i != NULL) && (i->if_next == intrfc))
 			i->if_next = intrfc->if_next;
 	}
 
 	/* remove this interface from *special* networks */
-	if (intrfc == ipx_primary_net)
+	if(intrfc == ipx_primary_net)
 		ipxitf_clear_primary_net();
-	if (intrfc == ipx_internal_net)
+	if(intrfc == ipx_internal_net)
 		ipx_internal_net = NULL;
 
 	kfree_s(intrfc, sizeof(*intrfc));
-	/* sockets still dangling
-	 * - must be closed from user space
-	 */
 	MOD_DEC_USE_COUNT;
+
 	return;
 }
 
@@ -360,30 +365,29 @@
 	struct device *dev = ptr;
 	ipx_interface *i, *tmp;
 
-	if(event!=NETDEV_DOWN)
+	if(event != NETDEV_DOWN)
 		return NOTIFY_DONE;
 
-	for (i = ipx_interfaces; i != NULL; ) {
-
+	for(i = ipx_interfaces; i != NULL;)
+	{
 		tmp = i->if_next;
-		if (i->if_dev == dev)
+		if(i->if_dev == dev)
 			ipxitf_down(i);
 		i = tmp;
 
 	}
 
-	return NOTIFY_DONE;
+	return (NOTIFY_DONE);
 }
 
 static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb)
 {
-	int	retval;
+	int retval;
 
-	if((retval = sock_queue_rcv_skb(sock, skb))<0)
-	{
+	if((retval = sock_queue_rcv_skb(sock, skb)) < 0)
 		kfree_skb(skb);
-	}
-	return retval;
+
+	return (retval);
 }
 
 /*
@@ -393,25 +397,25 @@
 #ifdef CONFIG_IPX_INTERN
 static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
 {
-	struct ipxhdr	*ipx = skb->nh.ipxh;
-	struct sock	*s;
+	struct ipxhdr *ipx = skb->nh.ipxh;
+	struct sock *s;
 
 	int is_broadcast = (memcmp(ipx->ipx_dest.node, ipx_broadcast_node,
 				   IPX_NODE_LEN) == 0);
 
 	s = intrfc->if_sklist;
 
-	while (s != NULL)
+	while(s != NULL)
 	{
-		if (   (s->protinfo.af_ipx.port == ipx->ipx_dest.sock)
-		    && (   is_broadcast
+		if((s->protinfo.af_ipx.port == ipx->ipx_dest.sock)
+		    && (is_broadcast
 			|| (memcmp(ipx->ipx_dest.node, s->protinfo.af_ipx.node,
 				   IPX_NODE_LEN) == 0)))
 		{
 			/* We found a socket to which to send */
 			struct sk_buff *skb1;
 
-			if (copy != 0)
+			if(copy != 0)
 			{
 				skb1 = skb_clone(skb, GFP_ATOMIC);
 				if (skb1 == NULL)
@@ -424,57 +428,50 @@
 			}
 			ipxitf_def_skb_handler(s, skb1);
 
-			if (intrfc != ipx_internal_net)
-			{
-				/* on an external interface, at most
-                                 * one socket can listen.
-				 */
+			/* On an external interface, one socket can listen */
+			if(intrfc != ipx_internal_net)
 				break;
-			}
 		}
 		s = s->next;
 	}
 
-	if (copy == 0)
-	{
-		/* skb was solely for us, and we did not make a copy,
-		 * so free it.
-		 */
+	/* skb was solely for us, and we did not make a copy, so free it. */
+	if(copy == 0)
 		kfree_skb(skb);
-	}
-	return 0;
+
+	return (0);
 }
 
 #else
 
 static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
 {
-	struct ipxhdr	*ipx = skb->nh.ipxh;
-	struct sock	*sock1 = NULL, *sock2 = NULL;
-	struct sk_buff	*skb1 = NULL, *skb2 = NULL;
+	struct ipxhdr *ipx = skb->nh.ipxh;
+	struct sock *sock1 = NULL, *sock2 = NULL;
+	struct sk_buff *skb1 = NULL, *skb2 = NULL;
 
 	sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
 
 	/*
-	 *	We need to check if there is a primary net and if
-	 *	this is addressed to one of the *SPECIAL* sockets because
-	 *	these need to be propagated to the primary net.
-	 *	The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and
-	 *	0x456(Diagnostic).
+	 * We need to check if there is a primary net and if
+	 * this is addressed to one of the *SPECIAL* sockets because
+	 * these need to be propagated to the primary net.
+	 * The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and
+	 * 0x456(Diagnostic).
 	 */
 
-	if (ipx_primary_net && (intrfc != ipx_primary_net))
+	if(ipx_primary_net && (intrfc != ipx_primary_net))
 	{
-		switch (ntohs(ipx->ipx_dest.sock))
+		switch(ntohs(ipx->ipx_dest.sock))
 		{
 			case 0x452:
 			case 0x453:
 			case 0x456:
 				/*
-				 *	The appropriate thing to do here is to
-				 * 	dup the packet and route to the primary net
-				 *	interface via ipxitf_send; however, we'll cheat
-				 *	and just demux it here.
+				 * The appropriate thing to do here is to
+				 * dup the packet and route to the primary net
+				 * interface via ipxitf_send; however, we'll 
+				 * cheat and just demux it here.
 				 */
 				sock2 = ipxitf_find_socket(ipx_primary_net,
 					ipx->ipx_dest.sock);
@@ -485,15 +482,13 @@
 	}
 
 	/*
-	 *	if there is nothing to do, return. The kfree will
-	 *	cancel any charging.
+	 * If there is nothing to do return. The kfree will cancel any charging.
 	 */
-
-	if (sock1 == NULL && sock2 == NULL)
+	if(sock1 == NULL && sock2 == NULL)
 	{
-		if (!copy)
+		if(!copy)
 			kfree_skb(skb);
-		return 0;
+		return (0);
 	}
 
 	/*
@@ -504,191 +499,162 @@
 	 * copies, we do as much as is possible.
 	 */
 
-	if (copy)
-	{
+	if(copy)
 		skb1 = skb_clone(skb, GFP_ATOMIC);
-	}
 	else
-	{
 		skb1 = skb;
-	}
 
-	if (skb1 == NULL)
-		return -ENOMEM;
+	if(skb1 == NULL)
+		return (-ENOMEM);
 
-	/*
-	 *	Do we need 2 SKBs?
-	 */
-
-	if (sock1 && sock2)
-	{
+	/* Do we need 2 SKBs? */
+	if(sock1 && sock2)
 		skb2 = skb_clone(skb1, GFP_ATOMIC);
-	}
 	else
 		skb2 = skb1;
 
-	if (sock1)
+	if(sock1)
 		(void) ipxitf_def_skb_handler(sock1, skb1);
 
-	if (skb2 == NULL)
-		return -ENOMEM;
+	if(skb2 == NULL)
+		return (-ENOMEM);
 
-	if (sock2)
+	if(sock2)
 		(void) ipxitf_def_skb_handler(sock2, skb2);
 
-	return 0;
+	return (0);
 }
-#endif
+#endif	/* CONFIG_IPX_INTERN */
 
 static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb)
 {
-	struct sk_buff	*skb2;
-	int	in_offset = skb->h.raw - skb->head;
-	int	out_offset = intrfc->if_ipx_offset;
-	int	len;
+	struct sk_buff *skb2;
+	int in_offset = skb->h.raw - skb->head;
+	int out_offset = intrfc->if_ipx_offset;
+	int len;
 
 	/* Hopefully, most cases */
-	if (in_offset >= out_offset) {
-		return skb;
-	}
+	if(in_offset >= out_offset)
+		return (skb);
 
 	/* Need new SKB */
-	len = skb->len + out_offset;
+	len  = skb->len + out_offset;
 	skb2 = alloc_skb(len, GFP_ATOMIC);
-	if (skb2 != NULL) {
-		skb_reserve(skb2,out_offset);
-		skb2->nh.raw=
-		skb2->h.raw=skb_put(skb2,skb->len);
+	if(skb2 != NULL)
+	{
+		skb_reserve(skb2, out_offset);
+		skb2->nh.raw =
+		skb2->h.raw = skb_put(skb2,skb->len);
 		memcpy(skb2->h.raw, skb->h.raw, skb->len);
 	}
 	kfree_skb(skb);
-	return NULL;
+
+	return (NULL);
 }
 
 static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
 {
-	struct ipxhdr	*ipx = skb->nh.ipxh;
-	struct device	*dev = intrfc->if_dev;
-	struct datalink_proto	*dl = intrfc->if_dlink;
-	char		dest_node[IPX_NODE_LEN];
-	int		send_to_wire = 1;
-	int		addr_len;
+	struct ipxhdr *ipx = skb->nh.ipxh;
+	struct device *dev = intrfc->if_dev;
+	struct datalink_proto *dl = intrfc->if_dlink;
+	char dest_node[IPX_NODE_LEN];
+	int send_to_wire = 1;
+	int addr_len;
 	
 	/* 
-	 *	We need to know how many skbuffs it will take to send out this
-	 *	packet to avoid unnecessary copies.
+	 * We need to know how many skbuffs it will take to send out this
+	 * packet to avoid unnecessary copies.
 	 */
 	 
-	if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) 
+	if((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) 
 		send_to_wire = 0;	/* No non looped */
 
 	/*
-	 *	See if this should be demuxed to sockets on this interface 
+	 * See if this should be demuxed to sockets on this interface 
 	 *
-	 *	We want to ensure the original was eaten or that we only use
-	 *	up clones.
+	 * We want to ensure the original was eaten or that we only use
+	 * up clones.
 	 */
 	 
-	if (ipx->ipx_dest.net == intrfc->if_netnum) 
+	if(ipx->ipx_dest.net == intrfc->if_netnum) 
 	{
 		/*
-		 *	To our own node, loop and free the original.
-		 *	The internal net will receive on all node address.
+		 * To our own node, loop and free the original.
+		 * The internal net will receive on all node address.
 		 */
-		if ((intrfc == ipx_internal_net)
+		if((intrfc == ipx_internal_net)
 		    || memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0) 
 		{
-			/*
-			 *	Don't charge sender
-			 */
+			/* Don't charge sender */
 			skb_orphan(skb);
-			/*
-			 *	Will charge receiver
-			 */
-			return ipxitf_demux_socket(intrfc, skb, 0);
+
+			/* Will charge receiver */
+			return (ipxitf_demux_socket(intrfc, skb, 0));
 		}
-		/*
-		 *	Broadcast, loop and possibly keep to send on.
-		 */
-		if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
+
+		/* Broadcast, loop and possibly keep to send on. */
+		if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
 		{
-			if (!send_to_wire)
+			if(!send_to_wire)
 				skb_orphan(skb);
 			ipxitf_demux_socket(intrfc, skb, send_to_wire);
-			if (!send_to_wire)
-				return 0;
+			if(!send_to_wire)
+				return (0);
 		}
 	}
 
 	/*
-	 *	If the originating net is not equal to our net; this is routed
-	 *	We are still charging the sender. Which is right - the driver
-	 *	free will handle this fairly.
+	 * If the originating net is not equal to our net; this is routed
+	 * We are still charging the sender. Which is right - the driver
+	 * free will handle this fairly.
 	 */
-
-	if (ipx->ipx_source.net != intrfc->if_netnum)
+	if(ipx->ipx_source.net != intrfc->if_netnum)
 	{
 		/*
-		 *	Unshare the buffer before modifying the count in
-		 *	case its a flood or tcpdump
+		 * Unshare the buffer before modifying the count in
+		 * case its a flood or tcpdump
 		 */
-		skb=skb_unshare(skb, GFP_ATOMIC);
+		skb = skb_unshare(skb, GFP_ATOMIC);
 		if(!skb)
-			return 0;
-		ipx = skb->nh.ipxh;
-		if (++(ipx->ipx_tctrl) > ipxcfg_max_hops)
+			return (0);
+		if(++(ipx->ipx_tctrl) > ipxcfg_max_hops)
 			send_to_wire = 0;
 	}
 
-	if (!send_to_wire)
+	if(!send_to_wire)
 	{
 		kfree_skb(skb);
-		return 0;
+		return (0);
 	}
 
-	/*
-	 *	Determine the appropriate hardware address
-	 */
-
+	/* Determine the appropriate hardware address */
 	addr_len = dev->addr_len;
-	if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
+	if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
 		memcpy(dest_node, dev->broadcast, addr_len);
 	else
 		memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len);
 
-	/*
-	 *	Make any compensation for differing physical/data link size
-	 */
-
+	/* Make any compensation for differing physical/data link size */
 	skb = ipxitf_adjust_skbuff(intrfc, skb);
-	if (skb == NULL)
-		return 0;
+	if(skb == NULL)
+		return (0);
 
 	/* set up data link and physical headers */
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_IPX);
 	dl->datalink_header(dl, skb, dest_node);
-#if 0
-	/* 
-	 *	Now log the packet just before transmission 
-	 */
-	 
-	dump_pkt("IPX snd:", skb->nh.ipxh);
-	dump_data("ETH hdr:", skb->mac.raw, skb->nh.raw - skb->mac.raw);
-#endif
 
-	/*
-	 *	Send it out 
-	 */
+	/* Send it out */
 	dev_queue_xmit(skb);
-	return 0;
+
+	return (0);
 }
 
 static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *);
 
 static int ipxitf_add_local_route(ipx_interface *intrfc)
 {
-	return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL);
+	return (ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL));
 }
 
 static const char * ipx_frame_name(unsigned short);
@@ -699,26 +665,23 @@
 	struct ipxhdr	*ipx = skb->nh.ipxh;
 	ipx_interface	*i;
 
-	/*
-	 *	We firewall first, ask questions later.
-	 */
-
+	/* We firewall first, ask questions later. */
 	if (call_in_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT)
 	{
 		kfree_skb(skb);
-		return 0;
+		return (0);
 	}
 
 	/* See if we should update our network number */
-	if ( !intrfc->if_netnum &&  /* net number of intrfc not known yet (== 0) */
-		(ipx->ipx_source.net == ipx->ipx_dest.net) && /* intra-net packet */
-		ipx->ipx_source.net)  /* source net number of packet != 0 */
+	if(!intrfc->if_netnum  /* net number of intrfc not known yet (== 0) */
+		&& (ipx->ipx_source.net == ipx->ipx_dest.net) /* intra packet */
+		&& ipx->ipx_source.net)  /* source net number of packet != 0 */
 	{
 		/* NB: NetWare servers lie about their hop count so we
 		 * dropped the test based on it.  This is the best way
 		 * to determine this is a 0 hop count packet.
 		 */
-		if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL)
+		if((i=ipxitf_find_using_net(ipx->ipx_source.net)) == NULL)
 		{
 			intrfc->if_netnum = ipx->ipx_source.net;
 			(void) ipxitf_add_local_route(intrfc);
@@ -734,7 +697,9 @@
 		}
 	}
 
-	if( ipx->ipx_type == IPX_TYPE_PPROP && ipx->ipx_tctrl < 8 && skb->pkt_type != PACKET_OTHERHOST ) 
+	if(ipx->ipx_type == IPX_TYPE_PPROP
+		&& ipx->ipx_tctrl < 8 
+		&& skb->pkt_type != PACKET_OTHERHOST) 
 	{
 		int i;
         	ipx_interface *ifcs;
@@ -743,235 +708,245 @@
 		char *c;
 		
 		c = (char *) skb->data;
-		c += sizeof( struct ipxhdr );
+		c += sizeof(struct ipxhdr);
 		l = (__u32 *) c;
 
 		i = 0;
-		/* 
-		 *	Dump packet if too many hops or already seen this net 
-		 */
-		if( ipx->ipx_tctrl < 8 )
-			for( ; i < ipx->ipx_tctrl ; i++ )
-				if( *l++ == intrfc->if_netnum )
-			break;
 
-		if( i == ipx->ipx_tctrl ) 
+		/* Dump packet if too many hops or already seen this net */
+		if(ipx->ipx_tctrl < 8)
+			for( ; i < ipx->ipx_tctrl; i++)
+				if(*l++ == intrfc->if_netnum)
+					break;
+
+		if(i == ipx->ipx_tctrl) 
 		{ 
 			/* < 8 hops && input itfc not in list */
 			*l = intrfc->if_netnum; /* insert recvd netnum into list */
 			/* xmit on all other interfaces... */
-			for ( ifcs = ipx_interfaces; ifcs != NULL ; ifcs = ifcs->if_next) 
+			for(ifcs = ipx_interfaces; ifcs != NULL; ifcs = ifcs->if_next) 
 			{
 				/* That aren't in the list */
 				l = (__u32 *) c;
-				for( i = 0 ; i <= ipx->ipx_tctrl ; i++ )
-					if( ifcs->if_netnum == *l++ )
+				for(i = 0; i <= ipx->ipx_tctrl; i++)
+					if(ifcs->if_netnum == *l++)
 						break;
-				if( i - 1 == ipx->ipx_tctrl ) 
+				if(i - 1 == ipx->ipx_tctrl) 
 				{
 					ipx->ipx_dest.net = ifcs->if_netnum;
 					/* See if we are allowed to firewall forward */
-					if (call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)==FW_ACCEPT)
+					if(call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb) == FW_ACCEPT)
 					{
-					        skb2 = skb_clone(skb, GFP_ATOMIC);
+					        skb2=skb_clone(skb, GFP_ATOMIC);
 						ipxrtr_route_skb(skb2);
 					}
 				}
 			}
-			/*
-			 *	Reset network number in packet 
-			 */
+
+			/* Reset network number in packet */
 			ipx->ipx_dest.net = intrfc->if_netnum;
 		}
-
 	}
 
-	if (!ipx->ipx_dest.net)
+	if(!ipx->ipx_dest.net)
 		ipx->ipx_dest.net = intrfc->if_netnum;
-	if (!ipx->ipx_source.net)
+	if(!ipx->ipx_source.net)
 		ipx->ipx_source.net = intrfc->if_netnum;
 
-	if (intrfc->if_netnum != ipx->ipx_dest.net)
+	if(intrfc->if_netnum != ipx->ipx_dest.net)
 	{
-		/*
-		 *	See if we are allowed to firewall forward
-		 */
-		if (call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT)
+		/* See if we are allowed to firewall forward */
+		if(call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb) != FW_ACCEPT)
 		{
 			kfree_skb(skb);
-			return 0;
+			return (0);
 		}
 
 		/* We only route point-to-point packets. */
-		if (skb->pkt_type == PACKET_HOST)
+		if(skb->pkt_type == PACKET_HOST)
 		{
 			skb=skb_unshare(skb, GFP_ATOMIC);
 			if(skb)
-				return ipxrtr_route_skb(skb);
+				return (ipxrtr_route_skb(skb));
 			else
-				return 0;
+				return (0);
 		}
+
 		kfree_skb(skb);
-		return 0;
+		return (0);
 	}
 
 	/* see if we should keep it */
-	if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)
+	if((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)
 		|| (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0))
 	{
-		return ipxitf_demux_socket(intrfc, skb, 0);
+		return (ipxitf_demux_socket(intrfc, skb, 0));
 	}
 
 	/* we couldn't pawn it off so unload it */
 	kfree_skb(skb);
-	return 0;
+	return (0);
 }
 
 static void ipxitf_insert(ipx_interface *intrfc)
 {
-	ipx_interface	*i;
+	ipx_interface *i;
 
 	intrfc->if_next = NULL;
-	if (ipx_interfaces == NULL) {
+	if(ipx_interfaces == NULL)
 		ipx_interfaces = intrfc;
-	} else {
-		for (i = ipx_interfaces; i->if_next != NULL; i = i->if_next)
+	else
+	{
+		for(i = ipx_interfaces; i->if_next != NULL; i = i->if_next)
 			;
 		i->if_next = intrfc;
 	}
 
-	if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
+	if(ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
 		ipx_primary_net = intrfc;
+
 	MOD_INC_USE_COUNT;
+
 	return;
 }
 
 static int ipxitf_create_internal(ipx_interface_definition *idef)
 {
-	ipx_interface	*intrfc;
+	ipx_interface *intrfc;
 
 	/* Only one primary network allowed */
-	if (ipx_primary_net != NULL)
-		return -EEXIST;
+	if(ipx_primary_net != NULL)
+		return (-EEXIST);
 
 	/* Must have a valid network number */
-	if (!idef->ipx_network)
-		return -EADDRNOTAVAIL;
-	if (ipxitf_find_using_net(idef->ipx_network) != NULL)
-		return -EADDRINUSE;
-
-	intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
-	if (intrfc==NULL)
-		return -EAGAIN;
-	intrfc->if_dev=NULL;
-	intrfc->if_netnum=idef->ipx_network;
-	intrfc->if_dlink_type = 0;
-	intrfc->if_dlink = NULL;
-	intrfc->if_sklist = NULL;
-	intrfc->if_internal = 1;
-	intrfc->if_ipx_offset = 0;
-	intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
+	if(!idef->ipx_network)
+		return (-EADDRNOTAVAIL);
+	if(ipxitf_find_using_net(idef->ipx_network) != NULL)
+		return (-EADDRINUSE);
+
+	intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
+	if(intrfc == NULL)
+		return (-EAGAIN);
+	intrfc->if_dev		= NULL;
+	intrfc->if_netnum	= idef->ipx_network;
+	intrfc->if_dlink_type 	= 0;
+	intrfc->if_dlink 	= NULL;
+	intrfc->if_sklist 	= NULL;
+	intrfc->if_internal 	= 1;
+	intrfc->if_ipx_offset 	= 0;
+	intrfc->if_sknum 	= IPX_MIN_EPHEMERAL_SOCKET;
 	memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN);
-	ipx_internal_net = intrfc;
-	ipx_primary_net = intrfc;
+	ipx_internal_net 	= intrfc;
+	ipx_primary_net 	= intrfc;
 	ipxitf_insert(intrfc);
-	return ipxitf_add_local_route(intrfc);
+
+	return (ipxitf_add_local_route(intrfc));
 }
 
 static int ipx_map_frame_type(unsigned char type)
 {
-	switch (type) 
+	switch(type) 
 	{
 		case IPX_FRAME_ETHERII:
-			return htons(ETH_P_IPX);
+			return (htons(ETH_P_IPX));
+
 		case IPX_FRAME_8022:
-			return htons(ETH_P_802_2);
+			return (htons(ETH_P_802_2));
+
 		case IPX_FRAME_TR_8022:
-			return htons(ETH_P_TR_802_2);
+			return (htons(ETH_P_TR_802_2));
+
 		case IPX_FRAME_SNAP:
-			return htons(ETH_P_SNAP);
+			return (htons(ETH_P_SNAP));
+
 		case IPX_FRAME_8023:
-			return htons(ETH_P_802_3);
+			return (htons(ETH_P_802_3));
 	}
-	return 0;
+
+	return (0);
 }
 
 static int ipxitf_create(ipx_interface_definition *idef)
 {
-	struct device	*dev;
-	unsigned short	dlink_type = 0;
-	struct datalink_proto	*datalink = NULL;
-	ipx_interface	*intrfc;
-
-	if (idef->ipx_special == IPX_INTERNAL)
-		return ipxitf_create_internal(idef);
-
-	if ((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL))
-		return -EEXIST;
-
-	if (idef->ipx_network &&
-		(ipxitf_find_using_net(idef->ipx_network) != NULL))
-		return -EADDRINUSE;
+	struct device *dev;
+	unsigned short dlink_type = 0;
+	struct datalink_proto *datalink = NULL;
+	ipx_interface *intrfc;
+
+	if(idef->ipx_special == IPX_INTERNAL)
+		return (ipxitf_create_internal(idef));
+
+	if((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL))
+		return (-EEXIST);
 
-	switch (idef->ipx_dlink_type) 
+	if(idef->ipx_network
+		&& (ipxitf_find_using_net(idef->ipx_network) != NULL))
+		return (-EADDRINUSE);
+
+	switch(idef->ipx_dlink_type) 
 	{
 		case IPX_FRAME_ETHERII:
-			dlink_type = htons(ETH_P_IPX);
-			datalink = pEII_datalink;
+			dlink_type 	= htons(ETH_P_IPX);
+			datalink 	= pEII_datalink;
 			break;
+
 		case IPX_FRAME_TR_8022:
-			dlink_type = htons(ETH_P_TR_802_2);
-			datalink = p8022tr_datalink;
+			dlink_type 	= htons(ETH_P_TR_802_2);
+			datalink 	= p8022tr_datalink;
 			break;
+
 		case IPX_FRAME_8022:
-			dlink_type = htons(ETH_P_802_2);
-			datalink = p8022_datalink;
+			dlink_type 	= htons(ETH_P_802_2);
+			datalink 	= p8022_datalink;
 			break;
+
 		case IPX_FRAME_SNAP:
-			dlink_type = htons(ETH_P_SNAP);
-			datalink = pSNAP_datalink;
+			dlink_type 	= htons(ETH_P_SNAP);
+			datalink 	= pSNAP_datalink;
 			break;
+
 		case IPX_FRAME_8023:
-			dlink_type = htons(ETH_P_802_3);
-			datalink = p8023_datalink;
+			dlink_type 	= htons(ETH_P_802_3);
+			datalink 	= p8023_datalink;
 			break;
+
 		case IPX_FRAME_NONE:
 		default:
 			break;
 	}
 
-	if (datalink == NULL)
-		return -EPROTONOSUPPORT;
+	if(datalink == NULL)
+		return (-EPROTONOSUPPORT);
 
-	dev=dev_get(idef->ipx_device);
-	if (dev==NULL)
-		return -ENODEV;
+	dev = dev_get(idef->ipx_device);
+	if(dev == NULL)
+		return (-ENODEV);
 
-	if (!(dev->flags & IFF_UP))
-		return -ENETDOWN;
+	if(!(dev->flags & IFF_UP))
+		return (-ENETDOWN);
 
 	/* Check addresses are suitable */
-	if(dev->addr_len>IPX_NODE_LEN)
-		return -EINVAL;
+	if(dev->addr_len > IPX_NODE_LEN)
+		return (-EINVAL);
 
-	if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL)
+	if((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL)
 	{
 		/* Ok now create */
-		intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
-		if (intrfc==NULL)
-			return -EAGAIN;
-		intrfc->if_dev=dev;
-		intrfc->if_netnum=idef->ipx_network;
-		intrfc->if_dlink_type = dlink_type;
-		intrfc->if_dlink = datalink;
-		intrfc->if_sklist = NULL;
-		intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
+		intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
+		if(intrfc == NULL)
+			return (-EAGAIN);
+		intrfc->if_dev		= dev;
+		intrfc->if_netnum 	= idef->ipx_network;
+		intrfc->if_dlink_type 	= dlink_type;
+		intrfc->if_dlink 	= datalink;
+		intrfc->if_sklist 	= NULL;
+		intrfc->if_sknum 	= IPX_MIN_EPHEMERAL_SOCKET;
 		/* Setup primary if necessary */
-		if ((idef->ipx_special == IPX_PRIMARY))
+		if((idef->ipx_special == IPX_PRIMARY))
 			ipx_primary_net = intrfc;
-		intrfc->if_internal = 0;
-		intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length;
-		if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN)==0)
+		intrfc->if_internal 	= 0;
+		intrfc->if_ipx_offset 	= dev->hard_header_len + datalink->header_length;
+		if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN) == 0)
 		{
 			memset(intrfc->if_node, 0, IPX_NODE_LEN);
 			memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]),
@@ -983,234 +958,250 @@
 	}
 
 	/* If the network number is known, add a route */
-	if (!intrfc->if_netnum)
-		return 0;
+	if(!intrfc->if_netnum)
+		return (0);
 
-	return ipxitf_add_local_route(intrfc);
+	return (ipxitf_add_local_route(intrfc));
 }
 
 static int ipxitf_delete(ipx_interface_definition *idef)
 {
-	struct device	*dev = NULL;
-	unsigned short	dlink_type = 0;
-	ipx_interface	*intrfc;
+	struct device *dev = NULL;
+	unsigned short dlink_type = 0;
+	ipx_interface *intrfc;
 
-	if (idef->ipx_special == IPX_INTERNAL) 
+	if(idef->ipx_special == IPX_INTERNAL) 
 	{
-		if (ipx_internal_net != NULL) 
+		if(ipx_internal_net != NULL) 
 		{
 			ipxitf_down(ipx_internal_net);
-			return 0;
+			return (0);
 		}
-		return -ENOENT;
+		return (-ENOENT);
 	}
 
 	dlink_type = ipx_map_frame_type(idef->ipx_dlink_type);
-	if (dlink_type == 0)
-		return -EPROTONOSUPPORT;
+	if(dlink_type == 0)
+		return (-EPROTONOSUPPORT);
 
-	dev=dev_get(idef->ipx_device);
-	if (dev==NULL)
-		return -ENODEV;
+	dev = dev_get(idef->ipx_device);
+	if(dev == NULL)
+		return (-ENODEV);
 
 	intrfc = ipxitf_find_using_phys(dev, dlink_type);
-	if (intrfc != NULL) {
+	if(intrfc != NULL)
+	{
 		ipxitf_down(intrfc);
-		return 0;
+		return (0);
 	}
-	return -EINVAL;
+
+	return (-EINVAL);
 }
 
 static ipx_interface *ipxitf_auto_create(struct device *dev, 
 	unsigned short dlink_type)
 {
 	struct datalink_proto *datalink = NULL;
-	ipx_interface	*intrfc;
+	ipx_interface *intrfc;
 
-	switch (htons(dlink_type)) 
+	switch(htons(dlink_type)) 
 	{
 		case ETH_P_IPX:
 			datalink = pEII_datalink;
 			break;
+
 		case ETH_P_802_2:
 			datalink = p8022_datalink;
 			break;
+
 		case ETH_P_TR_802_2:
 			datalink = p8022tr_datalink;
 			break;
+
 		case ETH_P_SNAP:
 			datalink = pSNAP_datalink;
 			break;
+
 		case ETH_P_802_3:
 			datalink = p8023_datalink;
 			break;
+
 		default:
-			return NULL;
+			return (NULL);
 	}
 
-	if (dev == NULL)
-		return NULL;
+	if(dev == NULL)
+		return (NULL);
 
 	/* Check addresses are suitable */
-	if(dev->addr_len>IPX_NODE_LEN) return NULL;
+	if(dev->addr_len>IPX_NODE_LEN)
+		return (NULL);
 
-	intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
-	if (intrfc!=NULL) 
+	intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
+	if(intrfc != NULL) 
 	{
-		intrfc->if_dev=dev;
-		intrfc->if_netnum=0;
-		intrfc->if_dlink_type = dlink_type;
-		intrfc->if_dlink = datalink;
-		intrfc->if_sklist = NULL;
-		intrfc->if_internal = 0;
-		intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
-		intrfc->if_ipx_offset = dev->hard_header_len +
-			datalink->header_length;
+		intrfc->if_dev		= dev;
+		intrfc->if_netnum	= 0;
+		intrfc->if_dlink_type 	= dlink_type;
+		intrfc->if_dlink 	= datalink;
+		intrfc->if_sklist 	= NULL;
+		intrfc->if_internal 	= 0;
+		intrfc->if_sknum 	= IPX_MIN_EPHEMERAL_SOCKET;
+		intrfc->if_ipx_offset 	= dev->hard_header_len +
+						datalink->header_length;
 		memset(intrfc->if_node, 0, IPX_NODE_LEN);
 		memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]),
 			dev->dev_addr, dev->addr_len);
 		ipxitf_insert(intrfc);
 	}
 
-	return intrfc;
+	return (intrfc);
 }
 
-static int ipxitf_ioctl_real(unsigned int cmd, void *arg)
+static int ipxitf_ioctl(unsigned int cmd, void *arg)
 {
+	struct ifreq ifr;
+	int err, val;
+
 	switch(cmd)
 	{
 		case SIOCSIFADDR: 
 		{
-			struct ifreq ifr;
 			struct sockaddr_ipx *sipx;
 			ipx_interface_definition f;
 
-			if (copy_from_user(&ifr,arg,sizeof(ifr)))
-				return -EFAULT;
-			sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
-			if(sipx->sipx_family!=AF_IPX)
-				return -EINVAL;
-			f.ipx_network=sipx->sipx_network;
-			memcpy(f.ipx_device, ifr.ifr_name, sizeof(f.ipx_device));
+			if(copy_from_user(&ifr, arg, sizeof(ifr)))
+				return (-EFAULT);
+
+			sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
+			if(sipx->sipx_family != AF_IPX)
+				return (-EINVAL);
+
+			f.ipx_network = sipx->sipx_network;
+			memcpy(f.ipx_device,ifr.ifr_name,sizeof(f.ipx_device));
 			memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN);
-			f.ipx_dlink_type=sipx->sipx_type;
-			f.ipx_special=sipx->sipx_special;
-			if(sipx->sipx_action==IPX_DLTITF)
-				return ipxitf_delete(&f);
+			f.ipx_dlink_type = sipx->sipx_type;
+			f.ipx_special = sipx->sipx_special;
+
+			if(sipx->sipx_action == IPX_DLTITF)
+				return (ipxitf_delete(&f));
 			else
-				return ipxitf_create(&f);
+				return (ipxitf_create(&f));
 		}
+
 		case SIOCGIFADDR: 
 		{
-			struct ifreq ifr;
 			struct sockaddr_ipx *sipx;
 			ipx_interface *ipxif;
 			struct device *dev;
-			int err;
 
-			if (copy_from_user(&ifr,arg,sizeof(ifr)))
-				return -EFAULT;
-			sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
-			dev=dev_get(ifr.ifr_name);
+			if(copy_from_user(&ifr, arg, sizeof(ifr)))
+				return (-EFAULT);
+
+			sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
+			dev = dev_get(ifr.ifr_name);
 			if(!dev)
-				return -ENODEV;
-			ipxif=ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type));
-			if(ipxif==NULL)
-				return -EADDRNOTAVAIL;
-			sipx->sipx_family=AF_IPX;
-			sipx->sipx_network=ipxif->if_netnum;
+				return (-ENODEV);
+
+			ipxif = ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type));
+			if(ipxif == NULL)
+				return (-EADDRNOTAVAIL);
+
+			sipx->sipx_family	= AF_IPX;
+			sipx->sipx_network	= ipxif->if_netnum;
 			memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node));
 			err = -EFAULT;
-			if (!copy_to_user(arg, &ifr, sizeof(ifr)))
+			if(!copy_to_user(arg, &ifr, sizeof(ifr)))
 				err = 0;
-			return err;
+
+			return (err);
 		}
+
 		case SIOCAIPXITFCRT: 
 		{
-			int err, val;
 			err = get_user(val, (unsigned char *) arg);
-			if (err)
-				return err;
-			return ipxcfg_set_auto_create(val);
+			if(err)
+				return (err);
+
+			return (ipxcfg_set_auto_create(val));
 		}
+
 		case SIOCAIPXPRISLT: 
 		{
-			int err, val;
 			err = get_user(val, (unsigned char *) arg);
-			if (err)
-				return err;
-			return ipxcfg_set_auto_select(val);
+			if(err)
+				return (err);
+
+			return (ipxcfg_set_auto_select(val));
 		}
+
 		default:
-			return -EINVAL;
+			return (-EINVAL);
 	}
 }
 
-static int ipxitf_ioctl(unsigned int cmd, void *arg)
-{
-	int ret;
-	MOD_INC_USE_COUNT;
-	ret = ipxitf_ioctl_real (cmd,arg);
-	MOD_DEC_USE_COUNT;
-	return ret;
-}
-
-/*******************************************************************************************************************\
-*													            *
-*	            			Routing tables for the IPX socket layer				            *
-*														    *
-\*******************************************************************************************************************/
+/**************************************************************************\
+*                                                                          *
+* Routing tables for the IPX socket layer.                                 *
+*                                                                          *
+\**************************************************************************/
 
 static ipx_route *ipxrtr_lookup(__u32 net)
 {
 	ipx_route *r;
 
-	for (r=ipx_routes; (r!=NULL) && (r->ir_net!=net); r=r->ir_next)
+	for(r = ipx_routes; (r != NULL) && (r->ir_net != net); r = r->ir_next)
 		;
 
-	return r;
+	return (r);
 }
 
 static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, unsigned char *node)
 {
-	ipx_route	*rt;
+	ipx_route *rt;
 
 	/* Get a route structure; either existing or create */
 	rt = ipxrtr_lookup(network);
-	if (rt==NULL) 
+	if(rt == NULL) 
+	{
+		rt = (ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);
+		if(rt == NULL)
+			return (-EAGAIN);
+		rt->ir_next	= ipx_routes;
+		ipx_routes	= rt;
+	}
+	else if(intrfc == ipx_internal_net)
+		return (-EEXIST);
+
+	rt->ir_net 	= network;
+	rt->ir_intrfc 	= intrfc;
+	if(node == NULL)
 	{
-		rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);
-		if(rt==NULL)
-			return -EAGAIN;
-		rt->ir_next=ipx_routes;
-		ipx_routes=rt;
-	}
-	else if (intrfc == ipx_internal_net)
-		return(-EEXIST);
-
-	rt->ir_net = network;
-	rt->ir_intrfc = intrfc;
-	if (node == NULL) {
 		memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
 		rt->ir_routed = 0;
-	} else {
+	}
+	else
+	{
 		memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
-		rt->ir_routed=1;
+		rt->ir_routed = 1;
 	}
-	return 0;
+
+	return (0);
 }
 
 static void ipxrtr_del_routes(ipx_interface *intrfc)
 {
-	ipx_route	**r, *tmp;
+	ipx_route **r, *tmp;
 
-	for (r = &ipx_routes; (tmp = *r) != NULL; ) {
-		if (tmp->ir_intrfc == intrfc) {
+	for(r = &ipx_routes; (tmp = *r) != NULL;)
+	{
+		if(tmp->ir_intrfc == intrfc)
+		{
 			*r = tmp->ir_next;
 			kfree_s(tmp, sizeof(ipx_route));
-		} else {
-			r = &(tmp->ir_next);
 		}
+		else
+			r = &(tmp->ir_next);
 	}
 }
 
@@ -1220,33 +1211,34 @@
 
 	/* Find the appropriate interface */
 	intrfc = ipxitf_find_using_net(rd->ipx_router_network);
-	if (intrfc == NULL)
-		return -ENETUNREACH;
+	if(intrfc == NULL)
+		return (-ENETUNREACH);
 
-	return ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node);
+	return (ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node));
 }
 
-
 static int ipxrtr_delete(long net)
 {
-	ipx_route	**r;
-	ipx_route	*tmp;
+	ipx_route **r;
+	ipx_route *tmp;
 
-	for (r = &ipx_routes; (tmp = *r) != NULL; ) 
+	for(r = &ipx_routes; (tmp = *r) != NULL;) 
 	{
-		if (tmp->ir_net == net) 
+		if(tmp->ir_net == net) 
 		{
-			if (!(tmp->ir_routed))
-				/* Directly connected; can't lose route */
-				return -EPERM;
+			/* Directly connected; can't lose route */
+			if(!(tmp->ir_routed))
+				return (-EPERM);
+
 			*r = tmp->ir_next;
 			kfree_s(tmp, sizeof(ipx_route));
-			return 0;
+			return (0);
 		}
+
 		r = &(tmp->ir_next);
 	}
 
-	return -ENOENT;
+	return (-ENOENT);
 }
 
 /*
@@ -1263,59 +1255,41 @@
 	 *	don't know of a machine that isn't.)
 	 */
 
-	__u32 sum=0;
-
-	/*
-	 *	Pointer to second word - We skip the checksum field
-	 */
-
-	__u16 *p=(__u16 *)&packet->ipx_pktsize;
-
-	/*
-	 *	Number of complete words
-	 */
+	__u32 sum = 0;
 
-	__u32 i=length>>1;
-	char    hops = packet->ipx_tctrl;
+	/* Pointer to second word - We skip the checksum field */
+	__u16 *p = (__u16 *)&packet->ipx_pktsize;
 
-	packet->ipx_tctrl = 0;     /* hop count excluded from checksum calc */
+	/* Number of complete words */
+	__u32 i = length >> 1;
+	char hops = packet->ipx_tctrl;
 
-	/*
-	 *	Loop through all complete words except the checksum field
-	 */
+	/* Hop count excluded from checksum calc */
+	packet->ipx_tctrl = 0;
 
+	/* Loop through all complete words except the checksum field */
 	while(--i)
-		sum+=*p++;
-
-	/*
-	 *	Add on the last part word if it exists
-	 */
+		sum += *p++;
 
-	if(packet->ipx_pktsize&htons(1))
-		sum+=ntohs(0xff00)&*p;
+	/* Add on the last part word if it exists */
+	if(packet->ipx_pktsize & htons(1))
+		sum += ntohs(0xff00) & *p;
 
 	packet->ipx_tctrl = hops;
-	/*
-	 *	Do final fixup
-	 */
 
-	sum=(sum&0xffff)+(sum>>16);
+	/* Do final fixup */
+	sum = (sum & 0xffff) + (sum >> 16);
 
-	/*
-	 *	It's a pity there's no concept of carry in C
-	 */
-
-	if(sum>=0x10000)
+	/* It's a pity there's no concept of carry in C */
+	if(sum >= 0x10000)
 		sum++;
 
-	return ~sum;
-};
-
+	return (~sum);
+}
 
 /*
- *	Route an outgoing frame from a socket.
+ * Route an outgoing frame from a socket.
  */
-
 static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock)
 {
 	struct sk_buff *skb;
@@ -1327,7 +1301,7 @@
 	int err;
 
 	/* Find the appropriate interface on which to send packet */
-	if (!usipx->sipx_network && (ipx_primary_net != NULL))
+	if(!usipx->sipx_network && (ipx_primary_net != NULL))
 	{
 		usipx->sipx_network = ipx_primary_net->if_netnum;
 		intrfc = ipx_primary_net;
@@ -1335,35 +1309,36 @@
 	else
 	{
 		rt = ipxrtr_lookup(usipx->sipx_network);
-		if (rt==NULL)
-			return -ENETUNREACH;
+		if(rt == NULL)
+			return (-ENETUNREACH);
 
 		intrfc = rt->ir_intrfc;
 	}
 
 	ipx_offset = intrfc->if_ipx_offset;
-	size=sizeof(struct ipxhdr)+len;
-	size += ipx_offset;
+	size	= sizeof(struct ipxhdr) + len;
+	size 	+= ipx_offset;
 
-	skb=sock_alloc_send_skb(sk, size, 0, noblock, &err);
-	if(skb==NULL)
-		return err;
+	skb = sock_alloc_send_skb(sk, size, 0, noblock, &err);
+	if(skb == NULL)
+		return (err);
 
 	skb_reserve(skb,ipx_offset);
-	skb->sk=sk;
+	skb->sk = sk;
 
 	/* Fill in IPX header */
-	ipx=(struct ipxhdr *)skb_put(skb,sizeof(struct ipxhdr));
-	ipx->ipx_pktsize=htons(len+sizeof(struct ipxhdr));
-	ipx->ipx_tctrl=0;
-	ipx->ipx_type=usipx->sipx_type;
-	skb->h.raw = (void *)skb->nh.ipxh = ipx;
+	ipx = (struct ipxhdr *)skb_put(skb, sizeof(struct ipxhdr));
+	ipx->ipx_pktsize= htons(len + sizeof(struct ipxhdr));
+	ipx->ipx_tctrl 	= 0;
+	ipx->ipx_type 	= usipx->sipx_type;
+	skb->h.raw 	= (void *)skb->nh.ipxh = ipx;
 
 	ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum;
+
 #ifdef CONFIG_IPX_INTERN
 	memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
 #else
-	if ((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452)
+	if((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452)
 	{
 		/* RIP/SAP special handling for mars_nwe */
 		ipx->ipx_source.net = intrfc->if_netnum;
@@ -1374,114 +1349,119 @@
 		ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum;
 		memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
 	}
-#endif
-	ipx->ipx_source.sock = sk->protinfo.af_ipx.port;
-	ipx->ipx_dest.net=usipx->sipx_network;
+#endif	/* CONFIG_IPX_INTERN */
+
+	ipx->ipx_source.sock 	= sk->protinfo.af_ipx.port;
+	ipx->ipx_dest.net	= usipx->sipx_network;
 	memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN);
-	ipx->ipx_dest.sock=usipx->sipx_port;
+	ipx->ipx_dest.sock	= usipx->sipx_port;
 
 	err = memcpy_fromiovec(skb_put(skb,len),iov,len);
-	if (err) 
+	if(err)
 	{
 		kfree_skb(skb);
-		return -EFAULT; 
+		return (-EFAULT);
 	}	
 
-	/*
-	 *	Apply checksum. Not allowed on 802.3 links.
-	 */
-	 
-	if(sk->no_check || intrfc->if_dlink_type==IPX_FRAME_8023)
+	/* Apply checksum. Not allowed on 802.3 links. */
+	if(sk->no_check || intrfc->if_dlink_type == IPX_FRAME_8023)
 		ipx->ipx_checksum=0xFFFF;
 	else
-		ipx->ipx_checksum=ipx_set_checksum(ipx, len+sizeof(struct ipxhdr));
+		ipx->ipx_checksum = ipx_set_checksum(ipx, len + sizeof(struct ipxhdr));
 
-	if(call_out_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT)
+	if(call_out_firewall(PF_IPX, skb->dev, ipx, NULL, &skb) != FW_ACCEPT)
 	{
 		kfree_skb(skb);
-		return -EPERM;
+		return (-EPERM);
 	}
 	
-	return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? 
-				rt->ir_router_node : ipx->ipx_dest.node);
+	return (ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? 
+				rt->ir_router_node : ipx->ipx_dest.node));
 }
 	
 int ipxrtr_route_skb(struct sk_buff *skb)
 {
-	struct ipxhdr	*ipx = skb->nh.ipxh;
-	ipx_route	*r;
-	ipx_interface	*i;
+	struct ipxhdr *ipx = skb->nh.ipxh;
+	ipx_interface *i;
+	ipx_route *r;
 
 	r = ipxrtr_lookup(ipx->ipx_dest.net);
-	if (r == NULL)
+	if(r == NULL)	/* no known route */
 	{
-		/* no known route */
 		kfree_skb(skb);
-		return 0;
+		return (0);
 	}
+
 	i = r->ir_intrfc;
 	(void)ipxitf_send(i, skb, (r->ir_routed) ?
 			r->ir_router_node : ipx->ipx_dest.node);
-	return 0;
+
+	return (0);
 }
 
 /*
- *	We use a normal struct rtentry for route handling
+ * We use a normal struct rtentry for route handling
  */
-
 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
 {
-	int err;
 	struct rtentry rt;	/* Use these to behave like 'other' stacks */
 	struct sockaddr_ipx *sg,*st;
+	int err;
 
 	err = copy_from_user(&rt,arg,sizeof(rt));
-	if (err)
-		return -EFAULT;
+	if(err)
+		return (-EFAULT);
 
-	sg=(struct sockaddr_ipx *)&rt.rt_gateway;
-	st=(struct sockaddr_ipx *)&rt.rt_dst;
+	sg = (struct sockaddr_ipx *)&rt.rt_gateway;
+	st = (struct sockaddr_ipx *)&rt.rt_dst;
 
-	if(!(rt.rt_flags&RTF_GATEWAY))
-		return -EINVAL;		/* Direct routes are fixed */
-	if(sg->sipx_family!=AF_IPX)
-		return -EINVAL;
-	if(st->sipx_family!=AF_IPX)
-		return -EINVAL;
+	if(!(rt.rt_flags & RTF_GATEWAY))
+		return (-EINVAL);	/* Direct routes are fixed */
+	if(sg->sipx_family != AF_IPX)
+		return (-EINVAL);
+	if(st->sipx_family != AF_IPX)
+		return (-EINVAL);
 
 	switch(cmd)
 	{
 		case SIOCDELRT:
-			return ipxrtr_delete(st->sipx_network);
+			return (ipxrtr_delete(st->sipx_network));
+
 		case SIOCADDRT:
 		{
 			struct ipx_route_definition f;
 			f.ipx_network=st->sipx_network;
 			f.ipx_router_network=sg->sipx_network;
 			memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);
-			return ipxrtr_create(&f);
+			return (ipxrtr_create(&f));
 		}
+
 		default:
-			return -EINVAL;
+			return (-EINVAL);
 	}
 }
 
 static const char *ipx_frame_name(unsigned short frame)
 {
-	switch (ntohs(frame)) 
+	switch(ntohs(frame)) 
 	{
 		case ETH_P_IPX:
-			return "EtherII";
+			return ("EtherII");
+
 		case ETH_P_802_2:
-			return "802.2";
+			return ("802.2");
+
 		case ETH_P_SNAP:
-			return "SNAP";
+			return ("SNAP");
+
 		case ETH_P_802_3:
-			return "802.3";
+			return ("802.3");
+
 		case ETH_P_TR_802_2:
-			return "802.2TR";
+			return ("802.2TR");
+
 		default:
-			return "None";
+			return ("None");
 	}
 }
 
@@ -1496,43 +1476,44 @@
 				  int length, int dummy)
 {
 	ipx_interface *i;
-	int len=0;
-	off_t pos=0;
-	off_t begin=0;
+	off_t begin = 0, pos = 0;
+	int len = 0;
 
 	/* Theory.. Keep printing in the same place until we pass offset */
 
-	len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network",
+	len += sprintf(buffer,"%-11s%-15s%-9s%-11s%s\n", "Network",
 		"Node_Address", "Primary", "Device", "Frame_Type");
-	for (i = ipx_interfaces; i != NULL; i = i->if_next) {
+	for(i = ipx_interfaces; i != NULL; i = i->if_next)
+	{
 		len += sprintf(buffer+len, "%08lX   ", (long unsigned int)ntohl(i->if_netnum));
-		len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X   ",
+		len += sprintf(buffer+len,"%02X%02X%02X%02X%02X%02X   ",
 				i->if_node[0], i->if_node[1], i->if_node[2],
 				i->if_node[3], i->if_node[4], i->if_node[5]);
 		len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ?
 			"Yes" : "No");
-		len += sprintf (buffer+len, "%-11s", ipx_device_name(i));
-		len += sprintf (buffer+len, "%s\n",
+		len += sprintf(buffer+len, "%-11s", ipx_device_name(i));
+		len += sprintf(buffer+len, "%s\n",
 			ipx_frame_name(i->if_dlink_type));
 
 		/* Are we still dumping unwanted data then discard the record */
-		pos=begin+len;
+		pos = begin + len;
 
-		if(pos<offset) {
-			len=0;			/* Keep dumping into the buffer start */
-			begin=pos;
+		if(pos < offset)
+		{
+			len   = 0;	/* Keep dumping into the buffer start */
+			begin = pos;
 		}
-		if(pos>offset+length)		/* We have dumped enough */
+		if(pos > offset + length)	/* We have dumped enough */
 			break;
 	}
 
 	/* The data in question runs from begin to begin+len */
-	*start=buffer+(offset-begin);	/* Start of wanted data */
-	len-=(offset-begin);		/* Remove unwanted header data from length */
-	if(len>length)
-		len=length;		/* Remove unwanted tail data from length */
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin); /* Remove unwanted header data from length */
+	if(len > length)
+		len = length;	/* Remove unwanted tail data from length */
 
-	return len;
+	return (len);
 }
 
 static int ipx_get_info(char *buffer, char **start, off_t offset,
@@ -1540,21 +1521,23 @@
 {
 	struct sock *s;
 	ipx_interface *i;
-	int len=0;
-	off_t pos=0;
-	off_t begin=0;
+	off_t begin = 0, pos = 0;
+	int len = 0;
 
 	/* Theory.. Keep printing in the same place until we pass offset */
 
 #ifdef CONFIG_IPX_INTERN
-	len += sprintf (buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
+	len += sprintf(buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
 #else
-	len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
-#endif
+	len += sprintf(buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
+#endif	/* CONFIG_IPX_INTERN */
 			"Remote_Address", "Tx_Queue", "Rx_Queue",
 			"State", "Uid");
-	for (i = ipx_interfaces; i != NULL; i = i->if_next) {
-		for (s = i->if_sklist; s != NULL; s = s->next) {
+
+	for(i = ipx_interfaces; i != NULL; i = i->if_next)
+	{
+		for(s = i->if_sklist; s != NULL; s = s->next)
+		{
 #ifdef CONFIG_IPX_INTERN
 			len += sprintf(buffer+len,
 				       "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",
@@ -1570,11 +1553,13 @@
 			len += sprintf(buffer+len,"%08lX:%04X  ",
 				       htonl(i->if_netnum),
 				       htons(s->protinfo.af_ipx.port));
-#endif
-			if (s->state!=TCP_ESTABLISHED) {
+#endif	/* CONFIG_IPX_INTERN */
+
+			if(s->state != TCP_ESTABLISHED)
 				len += sprintf(buffer+len, "%-28s", "Not_Connected");
-			} else {
-				len += sprintf (buffer+len,
+			else
+			{
+				len += sprintf(buffer+len,
 					"%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",
 					(long unsigned int) htonl(s->protinfo.af_ipx.dest_addr.net),
 					s->protinfo.af_ipx.dest_addr.node[0],
@@ -1585,92 +1570,99 @@
 					s->protinfo.af_ipx.dest_addr.node[5],
 					htons(s->protinfo.af_ipx.dest_addr.sock));
 			}
-			len += sprintf (buffer+len,"%08X  %08X  ",
+
+			len += sprintf(buffer+len,"%08X  %08X  ",
 				atomic_read(&s->wmem_alloc),
-					atomic_read(&s->rmem_alloc));
-			len += sprintf (buffer+len,"%02X     %03d\n",
+				atomic_read(&s->rmem_alloc));
+			len += sprintf(buffer+len,"%02X     %03d\n",
 				s->state, SOCK_INODE(s->socket)->i_uid);
 
-			/* Are we still dumping unwanted data then discard the record */
-			pos=begin+len;
-
-			if(pos<offset)
+			pos = begin + len;
+			if(pos < offset)
 			{
-				len=0;			/* Keep dumping into the buffer start */
-				begin=pos;
+				len   = 0;
+				begin = pos;
 			}
-			if(pos>offset+length)		/* We have dumped enough */
+
+			if(pos > offset + length)  /* We have dumped enough */
 				break;
 		}
 	}
 
 	/* The data in question runs from begin to begin+len */
-	*start=buffer+(offset-begin);	/* Start of wanted data */
-	len-=(offset-begin);		/* Remove unwanted header data from length */
-	if(len>length)
-		len=length;		/* Remove unwanted tail data from length */
+	*start = buffer + (offset-begin);
+	len -= (offset - begin);
+	if(len > length)
+		len = length;
 
-	return len;
+	return (len);
 }
 
 static int ipx_rt_get_info(char *buffer, char **start, off_t offset,
 			   int length, int dummy)
 {
 	ipx_route *rt;
-	int len=0;
-	off_t pos=0;
-	off_t begin=0;
+	off_t begin = 0, pos = 0;
+	int len = 0;
 
-	len += sprintf (buffer,"%-11s%-13s%s\n",
+	len += sprintf(buffer,"%-11s%-13s%s\n",
 			"Network", "Router_Net", "Router_Node");
-	for (rt = ipx_routes; rt != NULL; rt = rt->ir_next)
+	for(rt = ipx_routes; rt != NULL; rt = rt->ir_next)
 	{
-		len += sprintf (buffer+len,"%08lX   ", (long unsigned int) ntohl(rt->ir_net));
-		if (rt->ir_routed) {
-			len += sprintf (buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n",
+		len += sprintf(buffer+len,"%08lX   ", (long unsigned int) ntohl(rt->ir_net));
+		if(rt->ir_routed)
+		{
+			len += sprintf(buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n",
 				(long unsigned int) ntohl(rt->ir_intrfc->if_netnum),
 				rt->ir_router_node[0], rt->ir_router_node[1],
 				rt->ir_router_node[2], rt->ir_router_node[3],
 				rt->ir_router_node[4], rt->ir_router_node[5]);
-		} else {
-			len += sprintf (buffer+len, "%-13s%s\n",
+		}
+		else
+		{
+			len += sprintf(buffer+len, "%-13s%s\n",
 					"Directly", "Connected");
 		}
-		pos=begin+len;
-		if(pos<offset)
+
+		pos = begin + len;
+		if(pos < offset)
 		{
-			len=0;
-			begin=pos;
+			len   = 0;
+			begin = pos;
 		}
-		if(pos>offset+length)
+
+		if(pos > offset + length)
 			break;
 	}
-	*start=buffer+(offset-begin);
-	len-=(offset-begin);
-	if(len>length)
-		len=length;
-	return len;
+
+	*start = buffer + (offset - begin);
+	len -= (offset - begin);
+	if(len > length)
+		len = length;
+
+	return (len);
 }
 
-/*******************************************************************************************************************\
-*													            *
-*	      Handling for system calls applied via the various interfaces to an IPX socket object		    *
-*														    *
-\*******************************************************************************************************************/
+/**************************************************************************\
+*                                                                          *
+* Handling for system calls applied via the various interfaces to an       *
+* IPX socket object.                                                       *
+*                                                                          *
+\**************************************************************************/
 
 static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
 {
 	struct sock *sk;
-	int err,opt;
+	int err, opt;
 
-	sk=sock->sk;
+	sk = sock->sk;
 
-	if (optlen!=sizeof(int))
-		return(-EINVAL);
+	if(optlen != sizeof(int))
+		return (-EINVAL);
 
 	err = get_user(opt, (unsigned int *)optval);
-	if (err)
-		return err;
+	if(err)
+		return (err);
 
 	switch(level)
 	{
@@ -1678,15 +1670,16 @@
 			switch(optname)
 			{
 				case IPX_TYPE:
-					sk->protinfo.af_ipx.type=opt;
-					return 0;
+					sk->protinfo.af_ipx.type = opt;
+					return (0);
+
 				default:
-					return -ENOPROTOOPT;
+					return (-ENOPROTOOPT);
 			}
 			break;
 
 		default:
-			return -ENOPROTOOPT;
+			return (-ENOPROTOOPT);
 	}
 }
 
@@ -1697,142 +1690,157 @@
 	int val=0;
 	int len;
 
-	sk=sock->sk;
+	sk = sock->sk;
 
 	switch(level)
 	{
-
 		case SOL_IPX:
 			switch(optname)
 			{
 				case IPX_TYPE:
-					val=sk->protinfo.af_ipx.type;
+					val = sk->protinfo.af_ipx.type;
 					break;
+
 				default:
-					return -ENOPROTOOPT;
+					return (-ENOPROTOOPT);
 			}
 			break;
 
 		default:
-			return -ENOPROTOOPT;
+			return (-ENOPROTOOPT);
 	}
-	if(get_user(len,optlen))
-		return -EFAULT;
-	len=min(len,sizeof(int));
+
+	if(get_user(len, optlen))
+		return (-EFAULT);
+
+	len = min(len, sizeof(int));
 	if(put_user(len, optlen))
-		return -EFAULT;
-	if(copy_to_user(optval,&val,len))
-		return -EFAULT;
-	return 0;
+		return (-EFAULT);
+
+	if(copy_to_user(optval, &val, len))
+		return (-EFAULT);
+
+	return (0);
 }
 
 static int ipx_create(struct socket *sock, int protocol)
 {
 	struct sock *sk;
+
 	switch(sock->type)
 	{
 		case SOCK_DGRAM:
-			sk=sk_alloc(PF_IPX, GFP_KERNEL, 1);
-			if(sk==NULL)
-				return(-ENOMEM);
+			sk = sk_alloc(PF_IPX, GFP_KERNEL, 1);
+			if(sk == NULL)
+                		return (-ENOMEM);
                         sock->ops = &ipx_dgram_ops;
                         break;
+
 		case SOCK_SEQPACKET:
 			/*
-			 *	From this point on SPX sockets are handled
-			 *	by af_spx.c and the methods replaced.
+			 * From this point on SPX sockets are handled
+			 * by af_spx.c and the methods replaced.
 			 */
 			if(spx_family_ops)
-				return spx_family_ops->create(sock,protocol);
-			/* Fall through if SPX is not loaded */			
-		case SOCK_STREAM:	/* Allow higher levels to piggyback */
+				return (spx_family_ops->create(sock,protocol));
+			/* Fall through if SPX is not loaded */
+		case SOCK_STREAM:       /* Allow higher levels to piggyback */
 		default:
-			return(-ESOCKTNOSUPPORT);
+			return (-ESOCKTNOSUPPORT);
 	}
-	sock_init_data(sock,sk);
-	sk->destruct=NULL;
-	sk->mtu=IPX_MTU;
-	sk->no_check = 1;		/* Checksum off by default */
+
+	sock_init_data(sock, sk);
+	sk->destruct	= NULL;
+	sk->mtu		= IPX_MTU;
+	sk->no_check 	= 1;		/* Checksum off by default */
+
 	MOD_INC_USE_COUNT;
-	return 0;
+
+	return (0);
 }
 
 static int ipx_release(struct socket *sock, struct socket *peer)
 {
-	struct sock *sk=sock->sk;
-	if(sk==NULL)
-		return(0);
+	struct sock *sk = sock->sk;
+
+	if(sk == NULL)
+		return (0);
+
 	if(!sk->dead)
 		sk->state_change(sk);
-	sk->dead=1;
-	sock->sk=NULL;
+
+	sk->dead = 1;
+	sock->sk = NULL;
 	ipx_destroy_socket(sk);
-	if ( sock->type == SOCK_DGRAM ) {
+
+	if(sock->type == SOCK_DGRAM)
 		MOD_DEC_USE_COUNT;
-	}
-	return(0);
+
+	return (0);
 }
 
 static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc)
 {
-	unsigned short	socketNum = intrfc->if_sknum;
+	unsigned short socketNum = intrfc->if_sknum;
 
-	if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
+	if(socketNum < IPX_MIN_EPHEMERAL_SOCKET)
 		socketNum = IPX_MIN_EPHEMERAL_SOCKET;
 
-	while (ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)
-		if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
+	while(ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)
+	{
+		if(socketNum > IPX_MAX_EPHEMERAL_SOCKET)
 			socketNum = IPX_MIN_EPHEMERAL_SOCKET;
 		else
 			socketNum++;
+	}
 
 	intrfc->if_sknum = socketNum;
-	return	ntohs(socketNum);
+
+	return (ntohs(socketNum));
 }
 
 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
 	struct sock *sk;
 	ipx_interface *intrfc;
-	struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
+	struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr;
 
-	sk=sock->sk;
+	sk = sock->sk;
 
-	if(sk->zapped==0)
-		return -EINVAL;
+	if(sk->zapped == 0)
+		return (-EINVAL);
 
-	if(addr_len!=sizeof(struct sockaddr_ipx))
-		return -EINVAL;
+	if(addr_len != sizeof(struct sockaddr_ipx))
+		return (-EINVAL);
 
 	intrfc = ipxitf_find_using_net(addr->sipx_network);
-	if (intrfc == NULL)
-		return -EADDRNOTAVAIL;
+	if(intrfc == NULL)
+		return (-EADDRNOTAVAIL);
 
-	if (addr->sipx_port == 0) {
+	if(addr->sipx_port == 0)
+	{
 		addr->sipx_port = ipx_first_free_socketnum(intrfc);
-		if (addr->sipx_port == 0)
-			return -EINVAL;
+		if(addr->sipx_port == 0)
+			return (-EINVAL);
 	}
 
-	if(ntohs(addr->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
-		return -EACCES;	/* protect IPX system stuff like routing/sap */
+	/* protect IPX system stuff like routing/sap */
+	if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !suser())
+		return (-EACCES);
 
-	sk->protinfo.af_ipx.port=addr->sipx_port;
+	sk->protinfo.af_ipx.port = addr->sipx_port;
 
 #ifdef CONFIG_IPX_INTERN
-	if (intrfc == ipx_internal_net)
+	if(intrfc == ipx_internal_net)
 	{
 		/* The source address is to be set explicitly if the
 		 * socket is to be bound on the internal network. If a
 		 * node number 0 was specified, the default is used.
 		 */
 
-		if (memcmp(addr->sipx_node, ipx_broadcast_node,
-			   IPX_NODE_LEN) == 0)
-		{
-			return -EINVAL;
-		}
-		if (memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0)
+		if(memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN) == 0)
+			return (-EINVAL);
+		if(memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0)
 		{
 			memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,
 			       IPX_NODE_LEN);
@@ -1841,14 +1849,15 @@
 		{
 			memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN);
 		}
-		if (ipxitf_find_internal_socket(intrfc,
+
+		if(ipxitf_find_internal_socket(intrfc,
 			sk->protinfo.af_ipx.node,
 			sk->protinfo.af_ipx.port) != NULL)
 		{
 			SOCK_DEBUG(sk,
 				"IPX: bind failed because port %X in use.\n",
 				ntohs((int)addr->sipx_port));
-			return -EADDRINUSE;
+			return (-EADDRINUSE);
 		}
 	}
 	else
@@ -1861,85 +1870,96 @@
 		memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,
 			IPX_NODE_LEN);
 
-		if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
+		if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL)
+		{
 			SOCK_DEBUG(sk,
 				"IPX: bind failed because port %X in use.\n",
 				ntohs((int)addr->sipx_port));
-			return -EADDRINUSE;
+			return (-EADDRINUSE);
 		}
 	}
 
-#else
+#else	/* !def CONFIG_IPX_INTERN */
 
 	/* Source addresses are easy. It must be our network:node pair for
 	   an interface routed to IPX with the ipx routing ioctl() */
 
-	if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
+	if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL)
+	{
 		SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n",
 				ntohs((int)addr->sipx_port));
-		return -EADDRINUSE;
+		return (-EADDRINUSE);
 	}
 
-#endif
+#endif	/* CONFIG_IPX_INTERN */
 
 	ipxitf_insert_socket(intrfc, sk);
-	sk->zapped=0;
+	sk->zapped = 0;
 	SOCK_DEBUG(sk, "IPX: bound socket 0x%04X.\n", ntohs(addr->sipx_port) );
 
-	return 0;
+	return (0);
 }
 
 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
 	int addr_len, int flags)
 {
-	struct sock *sk=sock->sk;
+	struct sock *sk = sock->sk;
 	struct sockaddr_ipx *addr;
 
-	sk->state = TCP_CLOSE;
-	sock->state = SS_UNCONNECTED;
+	sk->state	= TCP_CLOSE;
+	sock->state 	= SS_UNCONNECTED;
 
-	if(addr_len!=sizeof(*addr))
-		return(-EINVAL);
-	addr=(struct sockaddr_ipx *)uaddr;
+	if(addr_len != sizeof(*addr))
+		return (-EINVAL);
+	addr = (struct sockaddr_ipx *)uaddr;
 
-	if(sk->protinfo.af_ipx.port==0)
 	/* put the autobinding in */
+	if(sk->protinfo.af_ipx.port == 0)
 	{
 		struct sockaddr_ipx uaddr;
 		int ret;
 
-		uaddr.sipx_port = 0;
-		uaddr.sipx_network = 0;
+		uaddr.sipx_port		= 0;
+		uaddr.sipx_network 	= 0;
+
 #ifdef CONFIG_IPX_INTERN
 		memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,
 		       IPX_NODE_LEN);
-#endif
-		ret = ipx_bind (sock, (struct sockaddr *)&uaddr,
+#endif	/* CONFIG_IPX_INTERN */
+
+		ret = ipx_bind(sock, (struct sockaddr *)&uaddr,
 				sizeof(struct sockaddr_ipx));
-		if (ret != 0) return (ret);
+		if(ret != 0)
+			return (ret);
 	}
 
-	if(ipxrtr_lookup(addr->sipx_network)==NULL)
-		return -ENETUNREACH;
-	sk->protinfo.af_ipx.dest_addr.net=addr->sipx_network;
-	sk->protinfo.af_ipx.dest_addr.sock=addr->sipx_port;
+	if(ipxrtr_lookup(addr->sipx_network) == NULL)
+		return (-ENETUNREACH);
+
+	sk->protinfo.af_ipx.dest_addr.net  = addr->sipx_network;
+	sk->protinfo.af_ipx.dest_addr.sock = addr->sipx_port;
 	memcpy(sk->protinfo.af_ipx.dest_addr.node,
 		addr->sipx_node,IPX_NODE_LEN);
-	sk->protinfo.af_ipx.type=addr->sipx_type;
-	if(sock->type == SOCK_DGRAM ) {
-		sock->state = SS_CONNECTED;
-		sk->state=TCP_ESTABLISHED;
+	sk->protinfo.af_ipx.type = addr->sipx_type;
+
+	if(sock->type == SOCK_DGRAM )
+	{
+		sock->state 	= SS_CONNECTED;
+		sk->state 	= TCP_ESTABLISHED;
 	}
-	return 0;
+
+	return (0);
 }
 
 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
 {
-	if(newsock->sk) {
+	if(newsock->sk)
+	{
 		sk_free(newsock->sk);
 		MOD_DEC_USE_COUNT;
 	}
-	return -EOPNOTSUPP;
+
+	return (-EOPNOTSUPP);
 }
 
 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
@@ -1949,163 +1969,105 @@
 	struct sockaddr_ipx sipx;
 	struct sock *sk;
 
-	sk=sock->sk;
+	sk = sock->sk;
 
 	*uaddr_len = sizeof(struct sockaddr_ipx);
 
-	if(peer) {
-		if(sk->state!=TCP_ESTABLISHED)
-			return -ENOTCONN;
-		addr=&sk->protinfo.af_ipx.dest_addr;
+	if(peer)
+	{
+		if(sk->state != TCP_ESTABLISHED)
+			return (-ENOTCONN);
+
+		addr = &sk->protinfo.af_ipx.dest_addr;
 		sipx.sipx_network = addr->net;
 		memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN);
 		sipx.sipx_port = addr->sock;
-	} else {
-		if (sk->protinfo.af_ipx.intrfc != NULL) {
-			sipx.sipx_network = sk->protinfo.af_ipx.intrfc->if_netnum;
+	}
+	else
+	{
+		if(sk->protinfo.af_ipx.intrfc != NULL)
+		{
+			sipx.sipx_network=sk->protinfo.af_ipx.intrfc->if_netnum;
 #ifdef CONFIG_IPX_INTERN
 			memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
 #else
-			memcpy(sipx.sipx_node,
-				sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
-#endif
+			memcpy(sipx.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
+#endif	/* CONFIG_IPX_INTERN */
 
-		} else {
+		}
+		else
+		{
 			sipx.sipx_network = 0;
 			memset(sipx.sipx_node, '\0', IPX_NODE_LEN);
 		}
+
 		sipx.sipx_port = sk->protinfo.af_ipx.port;
 	}
 
 	sipx.sipx_family = AF_IPX;
-	sipx.sipx_type = sk->protinfo.af_ipx.type;
+	sipx.sipx_type   = sk->protinfo.af_ipx.type;
 	memcpy(uaddr,&sipx,sizeof(sipx));
-	return 0;
-}
-
-#if 0
-/*
- * User to dump IPX packets (debugging)
- */
-void dump_data(char *str,unsigned char *d, int len) 
-{
-	static char h2c[] = "0123456789ABCDEF";
-	int l,i;
-	char *p, b[64];
-	for (l=0;len > 0 && l<16;l++) 
-	{
-		p = b;
-		for (i=0; i < 8 ; i++, --len) 
-		{
-			if (len > 0) 
-			{
-				*(p++) = h2c[(d[i] >> 4) & 0x0f];
-				*(p++) = h2c[d[i] & 0x0f];
-			}
-			else
-			{
-				*(p++) = ' ';
-				*(p++) = ' ';
-			}
-			*(p++) = ' ';
-		}
-		*(p++) = '-';
-		*(p++) = ' ';
-		len += 8;
-		for (i=0; i < 8 ; i++, --len)
-		{
-			if (len > 0)
-				*(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.';
-			else
-				*(p++) = ' ';
-		}
-		*p = '\000';
-		d += i;
-		printk(KERN_DEBUG"%s-%04X: %s\n",str,l*8,b);
-	}
-}
-
-void dump_addr(char *str,ipx_address *p)
-{
-	printk(KERN_DEBUG"%s: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
-		str,(long unsigned int)ntohl(p->net),p->node[0],p->node[1],p->node[2],
-		p->node[3],p->node[4],p->node[5],ntohs(p->sock));
-}
-
-void dump_hdr(char *str,struct ipxhdr *p) 
-{
-	printk(KERN_DEBUG"%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n",
-		str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize),
-		p->ipx_tctrl,p->ipx_tctrl,p->ipx_type);
-	dump_addr("  IPX-DST",&p->ipx_dest);
-	dump_addr("  IPX-SRC",&p->ipx_source);
-}
 
-void dump_pkt(char *str,struct ipxhdr *p) 
-{
-	int len = ntohs(p->ipx_pktsize);
-	dump_hdr(str,p);
-	if (len > 30)
-		dump_data(str,(unsigned char *)p + 30, len - 30);
+	return (0);
 }
-#endif
 
 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 {
 	/* NULL here for pt means the packet was looped back */
-	ipx_interface	*intrfc;
+	ipx_interface *intrfc;
 	struct ipxhdr *ipx;
 
 	ipx = skb->nh.ipxh;
 	
 	/* Too small? */
-	if(ntohs(ipx->ipx_pktsize)<sizeof(struct ipxhdr)) {
+	if(ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr))
+	{
 		kfree_skb(skb);
-		return 0;
+		return (0);
 	}
 	
-	if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) 
+	if(ipx->ipx_checksum != IPX_NO_CHECKSUM) 
 	{
-		if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize))!=ipx->ipx_checksum)
+		if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize)) != ipx->ipx_checksum)
 		{
 			kfree_skb(skb);
-			return 0;
+			return (0);
 		}
 	}
 
 	/* Determine what local ipx endpoint this is */
 	intrfc = ipxitf_find_using_phys(dev, pt->type);
-	if (intrfc == NULL)
+	if(intrfc == NULL)
 	{
-		if (ipxcfg_auto_create_interfaces &&
-		    ntohl(ipx->ipx_dest.net)!=0L)
+		if(ipxcfg_auto_create_interfaces
+		    && ntohl(ipx->ipx_dest.net) != 0L)
 		{
 			intrfc = ipxitf_auto_create(dev, pt->type);
 		}
 
-		if (intrfc == NULL) {
-			/* Not one of ours */
+		if(intrfc == NULL)	/* Not one of ours */
+		{
 			kfree_skb(skb);
-			return 0;
+			return (0);
 		}
 	}
 
-	return ipxitf_rcv(intrfc, skb);
+	return (ipxitf_rcv(intrfc, skb));
 }
 
 static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
 	struct scm_cookie *scm)
 {
-	struct sock *sk=sock->sk;
+	struct sock *sk = sock->sk;
 	struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name;
 	struct sockaddr_ipx local_sipx;
 	int retval;
 	int flags = msg->msg_flags;
 
-	if (sk->zapped)
-		return -EIO; /* Socket not bound */
-	if (flags&~MSG_DONTWAIT)
-		return -EINVAL;
+	if(sk->zapped)
+		return (-EIO);	/* Socket not bound */
+	if(flags & ~MSG_DONTWAIT)
+		return (-EINVAL);
 
 	if(usipx)
 	{
@@ -2120,185 +2082,193 @@
 			memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc
 				->if_node, IPX_NODE_LEN);
 #endif
-			ret = ipx_bind (sock, (struct sockaddr *)&uaddr,
+			ret = ipx_bind(sock, (struct sockaddr *)&uaddr,
 					sizeof(struct sockaddr_ipx));
-			if (ret != 0) return ret;
+			if(ret != 0)
+				return (ret);
 		}
 
-		if(msg->msg_namelen <sizeof(*usipx))
-			return -EINVAL;
+		if(msg->msg_namelen < sizeof(*usipx))
+			return (-EINVAL);
 		if(usipx->sipx_family != AF_IPX)
-			return -EINVAL;
+			return (-EINVAL);
 	}
 	else
 	{
-		if(sk->state!=TCP_ESTABLISHED)
-			return -ENOTCONN;
+		if(sk->state != TCP_ESTABLISHED)
+			return (-ENOTCONN);
+
 		usipx=&local_sipx;
-		usipx->sipx_family=AF_IPX;
-		usipx->sipx_type=sk->protinfo.af_ipx.type;
-		usipx->sipx_port=sk->protinfo.af_ipx.dest_addr.sock;
-		usipx->sipx_network=sk->protinfo.af_ipx.dest_addr.net;
+		usipx->sipx_family 	= AF_IPX;
+		usipx->sipx_type 	= sk->protinfo.af_ipx.type;
+		usipx->sipx_port 	= sk->protinfo.af_ipx.dest_addr.sock;
+		usipx->sipx_network 	= sk->protinfo.af_ipx.dest_addr.net;
 		memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
 	}
 
 	retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, flags&MSG_DONTWAIT);
-	if (retval < 0)
-		return retval;
+	if(retval < 0)
+		return (retval);
 
-	return len;
+	return (len);
 }
 
 
 static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size,
 		int flags, struct scm_cookie *scm)
 {
-	struct sock *sk=sock->sk;
-	struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)msg->msg_name;
+	struct sock *sk = sock->sk;
+	struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name;
 	struct ipxhdr *ipx = NULL;
 	struct sk_buff *skb;
 	int copied, err;
 
-	if (sk->zapped)
-		return -ENOTCONN;
+	if(sk->zapped)
+		return (-ENOTCONN);
 
-	skb=skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err);
-	if (!skb)
+	skb = skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err);
+	if(!skb)
 		goto out;
 
-	ipx = skb->nh.ipxh;
-	copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr);
+	ipx 	= skb->nh.ipxh;
+	copied 	= ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr);
 	if(copied > size)
 	{
 		copied=size;
-		msg->msg_flags|=MSG_TRUNC;
+		msg->msg_flags |= MSG_TRUNC;
 	}
 
 	err = skb_copy_datagram_iovec(skb, sizeof(struct ipxhdr), msg->msg_iov,
 					copied);
-	if (err)
+	if(err)
 		goto out_free;
-	sk->stamp=skb->stamp;
+	sk->stamp = skb->stamp;
 
 	msg->msg_namelen = sizeof(*sipx);
 
 	if(sipx)
 	{
-		sipx->sipx_family=AF_IPX;
-		sipx->sipx_port=ipx->ipx_source.sock;
+		sipx->sipx_family	= AF_IPX;
+		sipx->sipx_port		= ipx->ipx_source.sock;
 		memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN);
-		sipx->sipx_network=ipx->ipx_source.net;
-		sipx->sipx_type = ipx->ipx_type;
+		sipx->sipx_network	= ipx->ipx_source.net;
+		sipx->sipx_type 	= ipx->ipx_type;
 	}
 	err = copied;
 
 out_free:
 	skb_free_datagram(sk, skb);
 out:
-	return err;
+	return (err);
 }
 
 /*
- *	FIXME: We have to support shutdown really.
+ * FIXME: We have to really support shutdown.
  */
- 
 static int ipx_shutdown(struct socket *sk,int how)
 {
-	return -EOPNOTSUPP;
+	return (-EOPNOTSUPP);
 }
 
 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
 {
-	long amount=0;
-	struct sock *sk=sock->sk;
+	long amount = 0;
+	struct sock *sk = sock->sk;
 
 	switch(cmd)
 	{
 		case TIOCOUTQ:
 			amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
-			if(amount<0)
-				amount=0;
-			return put_user(amount, (int *)arg);
+			if(amount < 0)
+				amount = 0;
+			return (put_user(amount, (int *)arg));
+
 		case TIOCINQ:
 		{
 			struct sk_buff *skb;
 			/* These two are safe on a single CPU system as only user tasks fiddle here */
-			if((skb=skb_peek(&sk->receive_queue))!=NULL)
-				amount=skb->len-sizeof(struct ipxhdr);
-			return put_user(amount, (int *)arg);
+			if((skb = skb_peek(&sk->receive_queue)) != NULL)
+				amount = skb->len - sizeof(struct ipxhdr);
+			return (put_user(amount, (int *)arg));
 		}
+
 		case SIOCADDRT:
 		case SIOCDELRT:
 			if(!suser())
-				return -EPERM;
-			return(ipxrtr_ioctl(cmd,(void *)arg));
+				return (-EPERM);
+			return (ipxrtr_ioctl(cmd,(void *)arg));
+
 		case SIOCSIFADDR:
 		case SIOCAIPXITFCRT:
 		case SIOCAIPXPRISLT:
 			if(!suser())
-				return -EPERM;
+				return (-EPERM);
+
 		case SIOCGIFADDR:
-			return(ipxitf_ioctl(cmd,(void *)arg));
+			return (ipxitf_ioctl(cmd,(void *)arg));
+
 		case SIOCIPXCFGDATA:
-		{
-			return(ipxcfg_get_config_data((void *)arg));
-		}
+			return (ipxcfg_get_config_data((void *)arg));
+
 		case SIOCGSTAMP:
 		{
 			int ret = -EINVAL;
-			if (sk)
+			if(sk)
 			{
-				if(sk->stamp.tv_sec==0)
-					return -ENOENT;
+				if(sk->stamp.tv_sec == 0)
+					return (-ENOENT);
 				ret = -EFAULT;
-				if (!copy_to_user((void *)arg, &sk->stamp,
+				if(!copy_to_user((void *)arg, &sk->stamp,
 						sizeof(struct timeval)))
 					ret = 0;
 			}
-			return ret;
+
+			return (ret);
 		}
+
 		case SIOCGIFDSTADDR:
 		case SIOCSIFDSTADDR:
 		case SIOCGIFBRDADDR:
 		case SIOCSIFBRDADDR:
 		case SIOCGIFNETMASK:
 		case SIOCSIFNETMASK:
-			return -EINVAL;
+			return (-EINVAL);
+
 		default:
-			return(dev_ioctl(cmd,(void *) arg));
+			return (dev_ioctl(cmd,(void *) arg));
 	}
-	/*NOTREACHED*/
-	return(0);
+
+	/*NOT REACHED*/
+	return (0);
 }
 
 /*
- *	SPX interface support
+ *      SPX interface support
  */
 
 int ipx_register_spx(struct proto_ops **p, struct net_proto_family *spx)
 {
-	if(spx_family_ops!=NULL)
-		return -EBUSY;
-	cli();
-	MOD_INC_USE_COUNT;
-	*p=&ipx_dgram_ops;
-	spx_family_ops=spx;
-	sti();
-	return 0;
+        if(spx_family_ops!=NULL)
+                return -EBUSY;
+        cli();
+        MOD_INC_USE_COUNT;
+        *p=&ipx_dgram_ops;
+        spx_family_ops=spx;
+        sti();
+        return 0;
 }
 
 int ipx_unregister_spx(void)
 {
-	spx_family_ops=NULL;
-	MOD_DEC_USE_COUNT;
-	return 0;
+        spx_family_ops=NULL;
+        MOD_DEC_USE_COUNT;
+        return 0;
 }
 
-
 /*
- *	Socket family declarations
+ * Socket family declarations
  */
- 
+
 static struct net_proto_family ipx_family_ops = {
 	PF_IPX,
 	ipx_create
@@ -2352,10 +2322,10 @@
 };
 
 
-extern struct datalink_proto	*make_EII_client(void);
-extern struct datalink_proto	*make_8023_client(void);
-extern void	destroy_EII_client(struct datalink_proto *);
-extern void	destroy_8023_client(struct datalink_proto *);
+extern struct datalink_proto *make_EII_client(void);
+extern struct datalink_proto *make_8023_client(void);
+extern void destroy_EII_client(struct datalink_proto *);
+extern void destroy_8023_client(struct datalink_proto *);
 
 struct proc_dir_entry ipx_procinfo = {
 	PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO,
@@ -2372,32 +2342,32 @@
 	1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info
 };
 
-static unsigned char	ipx_8022_type = 0xE0;
-static unsigned char	ipx_snap_id[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
+static unsigned char ipx_8022_type = 0xE0;
+static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
 
-void
-ipx_proto_init(struct net_proto *pro)
+void ipx_proto_init(struct net_proto *pro)
 {
 	(void) sock_register(&ipx_family_ops);
 
 	pEII_datalink = make_EII_client();
-	ipx_dix_packet_type.type=htons(ETH_P_IPX);
+	ipx_dix_packet_type.type = htons(ETH_P_IPX);
 	dev_add_pack(&ipx_dix_packet_type);
 
 	p8023_datalink = make_8023_client();
-	ipx_8023_packet_type.type=htons(ETH_P_802_3);
+	ipx_8023_packet_type.type = htons(ETH_P_802_3);
 	dev_add_pack(&ipx_8023_packet_type);
 
-	if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
+	if((p8022_datalink = register_8022_client(ipx_8022_type,ipx_rcv)) == NULL)
 		printk(KERN_CRIT "IPX: Unable to register with 802.2\n");
 
-	if ((p8022tr_datalink = register_8022tr_client(ipx_8022_type, ipx_rcv)) == NULL)
+	if((p8022tr_datalink = register_8022tr_client(ipx_8022_type,ipx_rcv)) == NULL)
 		printk(KERN_CRIT "IPX: Unable to register with 802.2TR\n");
 
-	if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
+	if((pSNAP_datalink = register_snap_client(ipx_snap_id,ipx_rcv)) == NULL)
 		printk(KERN_CRIT "IPX: Unable to register with SNAP\n");
 
 	register_netdevice_notifier(&ipx_dev_notifier);
+
 #ifdef CONFIG_PROC_FS
 	proc_net_register(&ipx_procinfo);
 	proc_net_register(&ipx_if_procinfo);
@@ -2414,7 +2384,8 @@
 	ipx_route *rt = NULL;
 
 	rt = ipxrtr_lookup(ipx_net_number);
-	return ( rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH );
+
+	return (rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH);
 }
 
 /* Export symbols for higher layers */
@@ -2424,7 +2395,6 @@
 EXPORT_SYMBOL(ipx_register_spx);
 EXPORT_SYMBOL(ipx_unregister_spx);
 
-
 #ifdef MODULE
 /* Note on MOD_{INC,DEC}_USE_COUNT:
  *
@@ -2443,10 +2413,11 @@
 {
 	ipx_interface	*ifc;
 
-	while (ipx_interfaces) {
+	while(ipx_interfaces)
+	{
 		ifc = ipx_interfaces;
-		ipx_interfaces = ifc->if_next;
-		ifc->if_next = NULL;
+		ipx_interfaces 	= ifc->if_next;
+		ifc->if_next 	= NULL;
 		ipxitf_down(ifc);
 	}
 
@@ -2459,21 +2430,21 @@
 	unregister_netdevice_notifier(&ipx_dev_notifier);
 
 	unregister_snap_client(ipx_snap_id);
-	pSNAP_datalink = NULL;
+	pSNAP_datalink 	= NULL;
 
 	unregister_8022tr_client(ipx_8022_type);
 	p8022tr_datalink = NULL;
 
 	unregister_8022_client(ipx_8022_type);
-	p8022_datalink = NULL;
+	p8022_datalink 	= NULL;
 
 	dev_remove_pack(&ipx_8023_packet_type);
 	destroy_8023_client(p8023_datalink);
-	p8023_datalink = NULL;
+	p8023_datalink 	= NULL;
 
 	dev_remove_pack(&ipx_dix_packet_type);
 	destroy_EII_client(pEII_datalink);
-	pEII_datalink = NULL;
+	pEII_datalink 	= NULL;
 
 	(void) sock_unregister(ipx_family_ops.family);
 
@@ -2483,7 +2454,7 @@
 int init_module(void)
 {
 	ipx_proto_init(NULL);
-	return 0;
+	return (0);
 }
 
 void cleanup_module(void)
@@ -2491,4 +2462,6 @@
 	ipx_proto_finito();
 	return;
 }
-#endif /* def MODULE */
+
+#endif /* MODULE */
+#endif /* CONFIG_IPX || CONFIG_IPX_MODULE */
diff -u --recursive --new-file v2.1.103/linux/net/ipx/af_spx.c linux/net/ipx/af_spx.c
--- v2.1.103/linux/net/ipx/af_spx.c	Fri May  8 23:14:57 1998
+++ linux/net/ipx/af_spx.c	Mon May 25 10:38:05 1998
@@ -48,6 +48,8 @@
 static void spx_watchdog(unsigned long data);
 void spx_rcv(struct sock *sk, int bytes);
 
+extern void ipx_remove_socket(struct sock *sk);
+
 /* Create the SPX specific data */
 static int spx_sock_init(struct sock *sk)
 {
@@ -328,6 +330,8 @@
  * As we simply have a default retry time of 1*HZ and a max retry
  * time of 5*HZ. Between those values we increase the timeout based
  * on the number of retransmit tries.
+ *
+ * FixMe: This is quite fake, but will work for now. (JS)
  */
 static inline unsigned long spx_calc_rtt(int tries)
 {
@@ -344,11 +348,12 @@
 	int err = 0;
 
 	skb = skb_unshare(skb, GFP_ATOMIC);
-	if(skb==NULL)
-		return -ENOBUFS;
+	if(skb == NULL)
+		return (-ENOBUFS);
 
 	switch(type)
 	{
+		case (CONREQ):
 		case (DATA):
 			if(!skb_queue_empty(&pdata->retransmit_queue))
 			{
@@ -366,7 +371,6 @@
         	        skb_queue_tail(&pdata->retransmit_queue, skb2);
 
 		case (ACK):
-		case (CONREQ):
 		case (CONACK):
 		case (WDREQ):
 		case (WDACK):
@@ -388,7 +392,8 @@
 {
         struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
         struct ipxspxhdr *ipxh;
-	int flags, err;
+	unsigned long flags;
+	int err;
 
 	if(skb == NULL)
 	{
@@ -397,11 +402,11 @@
 
 		save_flags(flags);
 		cli();
-        	skb = sock_alloc_send_skb(sk, size, 0, 0, &err);
+        	skb = sock_alloc_send_skb(sk, size, 1, 0, &err);
         	if(skb == NULL)
                 	return (-ENOMEM);
         	skb_reserve(skb, offset);
-        	skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr));
+        	skb->h.raw = skb->nh.raw = skb_put(skb,sizeof(struct ipxspxhdr));
 		restore_flags(flags);
 	}
 
@@ -435,10 +440,10 @@
                 	pdata->sequence++;
 			break;
 
-		case (ACK):	/* Connection/WD/Data ACK */
+		case (ACK):	/* ACK */
 			pdata->rmt_seq++;
-		case (WDACK):
-		case (CONACK):
+		case (WDACK):	/* WD ACK */
+		case (CONACK):	/* Connection ACK */
 			ipxh->spx.cctl 		= CCTL_SYS;
 			ipxh->spx.ackseq 	= htons(pdata->rmt_seq);
 			break;
@@ -472,9 +477,7 @@
 	}
 
 	/* Send data */
-	spx_route_skb(pdata, skb, type);
-
-        return (0);
+        return (spx_route_skb(pdata, skb, type));
 }
 
 /* Check the state of the connection and send a WD request if needed. */
@@ -484,6 +487,8 @@
         struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
 
         del_timer(&pdata->watchdog);
+	if(pdata->state == SPX_CLOSED)
+                return;
 	if(pdata->retries > pdata->max_retries)
         {
 		spx_close_socket(sk);	/* Unilateral Abort */
@@ -502,21 +507,27 @@
 	struct sock *sk = (struct sock*)data;
         struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
 	struct sk_buff *skb;
+	unsigned long flags;
 	int err;
 
 	del_timer(&pdata->retransmit);
+	if(pdata->state == SPX_CLOSED)
+		return;
 	if(pdata->retransmits > RETRY_COUNT)
 	{
 		spx_close_socket(sk);   /* Unilateral Abort */
                 return;
         }
 
-	/* need to leave skb on the queue! */
+	/* Need to leave skb on the queue, aye the fear */
+	save_flags(flags);
+	cli();
 	skb = skb_peek(&pdata->retransmit_queue);
 	if(skb_cloned(skb))
                 skb = skb_copy(skb, GFP_ATOMIC);
         else
                 skb = skb_clone(skb, GFP_ATOMIC);
+	restore_flags(flags);
 
 	pdata->retransmit.expires = jiffies + spx_calc_rtt(pdata->retransmits);
 	add_timer(&pdata->retransmit);
@@ -527,13 +538,46 @@
 	return;
 }
 
+/* Check packet for retransmission, ConReqAck aware */
+static int spx_retransmit_chk(struct spx_opt *pdata, int ackseq, int type)
+{
+	struct ipxspxhdr *ipxh;
+	struct sk_buff *skb;
+
+	skb = skb_dequeue(&pdata->retransmit_queue);
+	if(!skb)
+		return (-ENOENT);
+
+	/* Check Data/ACK seq */
+	switch(type)
+	{
+		case ACK:	/* Check Sequence, Should == 1 */
+			ipxh = (struct ipxspxhdr *)skb->nh.raw;
+			if(!(ntohs(ipxh->spx.sequence) - htons(ackseq)))
+				break;
+
+		case CONACK:
+			del_timer(&pdata->retransmit);
+			pdata->retransmits = 0;
+			kfree_skb(skb);
+			if(skb_queue_empty(&pdata->retransmit_queue))
+			{
+				skb = skb_dequeue(&pdata->transmit_queue);
+				if(skb != NULL)
+					spx_route_skb(pdata, skb, TQUEUE);
+			}
+			return (0);
+	}
+
+	skb_queue_head(&pdata->retransmit_queue, skb);
+	return (-1);
+}
+
 /* SPX packet receive engine */
 void spx_rcv(struct sock *sk, int bytes)
 {
 	struct sk_buff *skb;
-	struct sk_buff *skb2;
 	struct ipxspxhdr *ipxh;
-	struct ipxspxhdr *ipxh2;
 	struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
 
 	skb = skb_dequeue(&sk->receive_queue);
@@ -543,15 +587,13 @@
 
 	/* Can't receive on a closed connection */
         if((pdata->state == SPX_CLOSED) && (ipxh->spx.sequence != 0))
-		return;
+		goto toss_skb;
 	if(ntohs(ipxh->ipx.ipx_pktsize) < SPX_SYS_PKT_LEN)
-		return;
+		goto toss_skb;
         if(ipxh->ipx.ipx_type != IPX_TYPE_SPX)
-		return;
-
-	/* insanity - rcv'd ACK of unsent data ?? */
+		goto toss_skb;
         if(ntohs(ipxh->spx.ackseq) > pdata->sequence)
-		return;
+		goto toss_skb;
 
 	/* Reset WD timer on any received packet */
 	del_timer(&pdata->watchdog);
@@ -577,7 +619,7 @@
 			}
 			else	/* WD Request */
 				spx_transmit(sk, skb, WDACK, 0);
-			break;
+			goto finish;
 
 		case CCTL_SYS:	/* ACK */
 			if((ipxh->spx.dtype == 0)       /* ConReq ACK */
@@ -588,62 +630,56 @@
                                 && (pdata->state != SPX_CONNECTED))
                         {
                                 pdata->state = SPX_CONNECTED;
+				pdata->dest_connid = ipxh->spx.sconn;
+
+				if(spx_retransmit_chk(pdata, 0, CONACK) < 0)
+					goto toss_skb;
 
                                 skb_queue_tail(&sk->receive_queue, skb);
                                 wake_up_interruptible(sk->sleep);
-                                break;
-                        }
-
-			/* Check Data/ACK seq */
-                        skb2 = skb_dequeue(&pdata->retransmit_queue);
-                        if(skb2)
-                        {
-				ipxh2 = (struct ipxspxhdr *)skb2->nh.raw;
-                                if((ntohs(ipxh2->spx.sequence)
-                                        == (ntohs(ipxh->spx.ackseq) - 1))
-					|| (ntohs(ipxh2->spx.sequence) == 65535
-					&& ntohs(ipxh->spx.ackseq) == 0))
-                                {
-					del_timer(&pdata->retransmit);
-					pdata->retransmits = 0;
-                                        kfree_skb(skb2);
-					if(skb_queue_empty(&pdata->retransmit_queue))
-					{
-						skb2 = skb_dequeue(&pdata->transmit_queue);
-						if(skb2 != NULL)
-							spx_route_skb(pdata, skb2, TQUEUE);
-					}
-                                }
-                                else    /* Out of Seq - ERROR! */
-				skb_queue_head(&pdata->retransmit_queue, skb2);
+                                goto finish;
                         }
 
-			kfree_skb(skb);
-			break;
+			spx_retransmit_chk(pdata, ipxh->spx.ackseq, ACK);
+			goto toss_skb;
 
-		case (CCTL_ACK):	/* Informed Disconnect */
+		case (CCTL_ACK):
+			/* Informed Disconnect */
 			if(ipxh->spx.dtype == SPX_DTYPE_ECONN)
 			{
+				
 				spx_transmit(sk, skb, DISACK, 0);
 				spx_close_socket(sk);
+				goto finish;
 			}
-			break;
+			/* Fall through */
 
 		default:
 			if(ntohs(ipxh->spx.sequence) == pdata->rmt_seq)
 			{
 				pdata->rmt_seq = ntohs(ipxh->spx.sequence);
+				pdata->rmt_ack = ntohs(ipxh->spx.ackseq);
+				if(pdata->rmt_ack > 0 || pdata->rmt_ack == 0)
+					spx_retransmit_chk(pdata,pdata->rmt_ack, ACK);
+
 				skb_queue_tail(&pdata->rcv_queue, skb);
 				wake_up_interruptible(sk->sleep);
-				spx_transmit(sk, NULL, ACK, 0);
-				break;
+				if(ipxh->spx.cctl&CCTL_ACK)
+					spx_transmit(sk, NULL, ACK, 0);
+				goto finish;
 			}
 
-			/* Catch All */
-			kfree_skb(skb);
-			break;
+			if(ipxh->spx.dtype == SPX_DTYPE_ECACK)
+			{
+				if(pdata->state != SPX_CLOSED)
+					spx_close_socket(sk);
+				goto toss_skb;
+			}
 	}
 
+toss_skb:	/* Catch All */
+	kfree_skb(skb);
+finish:
         return;
 }
 
@@ -665,13 +701,16 @@
 
 	offset	= ipx_if_offset(sk->tp_pinfo.af_spx.dest_addr.net);
         size 	= offset + sizeof(struct ipxspxhdr) + len;
+
+	cli();
         skb  	= sock_alloc_send_skb(sk, size, 0, flags&MSG_DONTWAIT, &err);
         if(skb == NULL)
                 return (err);
+	sti();
 
 	skb->sk = sk;
         skb_reserve(skb, offset);
-	skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr));
+	skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr));
 
 	err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
 	if(err)
@@ -844,7 +883,7 @@
 
 	/* route socket(PF_IPX, SOCK_SEQPACKET) calls through spx_create() */
 
-	printk(KERN_INFO "Sequenced Packet eXchange (SPX) 0.01 for Linux NET3.037\n");
+	printk(KERN_INFO "Sequenced Packet eXchange (SPX) 0.02 for Linux NET3.037\n");
 	return;
 }
 
diff -u --recursive --new-file v2.1.103/linux/net/wanrouter/wanmain.c linux/net/wanrouter/wanmain.c
--- v2.1.103/linux/net/wanrouter/wanmain.c	Thu May  7 22:51:56 1998
+++ linux/net/wanrouter/wanmain.c	Thu May 21 13:53:24 1998
@@ -24,6 +24,7 @@
 * Jun 27, 1997  Alan Cox	realigned with vendor code
 * Oct 15, 1997  Farhan Thawar   changed wan_encapsulate to add a pad byte of 0
 * Apr 20, 1998	Alan Cox	Fixed 2.1 symbols
+* May 17, 1998  K. Baranowski	Fixed SNAP encapsulation in wan_encapsulate
 *****************************************************************************/
 
 #include <linux/stddef.h>	/* offsetof(), etc. */
@@ -288,11 +289,11 @@
 	case ETH_P_IPX:		/* SNAP encapsulation */
 	case ETH_P_ARP:
 		hdr_len += 7;
-		skb_push(skb, 6);
+		skb_push(skb, 7);
 		skb->data[0] = 0;
 		skb->data[1] = NLPID_SNAP;
-		memcpy(&skb->data[1], oui_ether, sizeof(oui_ether));
-		*((unsigned short*)&skb->data[4]) = htons(skb->protocol);
+		memcpy(&skb->data[2], oui_ether, sizeof(oui_ether));
+		*((unsigned short*)&skb->data[5]) = htons(skb->protocol);
 		break;
 
 	default:		/* Unknown packet type */
diff -u --recursive --new-file v2.1.103/linux/scripts/ksymoops.cc linux/scripts/ksymoops.cc
--- v2.1.103/linux/scripts/ksymoops.cc	Sun Sep 21 10:48:50 1997
+++ linux/scripts/ksymoops.cc	Wed Jun  3 12:38:37 1998
@@ -26,6 +26,9 @@
 // command-line argument, and redirect the oops-log into stdin.  Out
 // will come the EIP and call-trace in symbolic form.
 
+// Changed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+// adapted to Linux/m68k
+
 //////////////////////////////////////////////////////////////////////////////
 
 // BUGS:
@@ -39,8 +42,9 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <a.out.h>
 
-inline int strnequ(char const* x, char const* y, size_t n) { return (::strncmp(x, y, n) == 0); }
+inline int strnequ(char const* x, char const* y, size_t n) { return (strncmp(x, y, n) == 0); }
 
 const int code_size = 20;
 
@@ -149,32 +153,34 @@
     /* This is a hack to avoid using gcc.  We create an object file by
        concatenating objfile_head, the twenty bytes of code, and
        objfile_tail.  */
-    unsigned char objfile_head[] = {
-	0x07, 0x01, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    static struct exec objfile_head = {
+	OMAGIC, code_size + 4, 0, 0, sizeof (struct nlist) * 3, 0, 0, 0
     };
-    unsigned char objfile_tail[] = {
-	0x00, 0x90, 0x90, 0x90,
-	0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x25, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
-	'g',  'c',  'c',  '2',  '_',  'c',  'o',  'm',  
-	'p',  'i',  'l',  'e',  'd',  '.',  '\0', '_',  
-	'E',  'I',  'P',  '\0', '\0', '\0', '\0', '\0',
-	'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
-	'\0', '\0', '\0', '\0', '\0', '\0'
+    static struct {
+	unsigned char tail[4];
+	struct nlist syms[3];
+	unsigned long strsize;
+	char strings[42];
+    } objfile_tail = {
+#ifdef i386
+	{ 0x00, 0x90, 0x90, 0x90 },
+#endif
+#ifdef mc68000
+	{ 0x00, 0x00, 0x00, 0x00 },
+#endif
+	{ { (char *) 4, N_TEXT, 0, 0, 0 },
+	  { (char *) 19, N_TEXT, 0, 0, 0 },
+	  { (char *) 37, N_TEXT | N_EXT, 0, 0, 0 } },
+	42,
+	"gcc2_compiled.\0___gnu_compiled_c\0_EIP\0"
     };
     char const* objdump_command = "objdump -d oops_decode.o";
     char const* objfile_name = &objdump_command[11];
     ofstream objfile_stream(objfile_name);
 
-    objfile_stream.write(objfile_head, sizeof(objfile_head));
+    objfile_stream.write((char *) &objfile_head, sizeof(objfile_head));
     objfile_stream.write(code, code_size);
-    objfile_stream.write(objfile_tail, sizeof(objfile_tail));
+    objfile_stream.write((char *) &objfile_tail, sizeof(objfile_tail));
     objfile_stream.close();
     
     FILE* objdump_FILE = popen(objdump_command, "r");
@@ -197,8 +203,8 @@
 	    memset(newbuf, '\0', sizeof(newbuf));
 	    ostrstream ost(newbuf, sizeof(newbuf));
 	    ost.width(8);
-	    ost << offset;
-	    ost << " <_EIP+" << offset << ">: " << &buf[6] << ends;
+	    ost << hex << offset;
+	    ost << " <_EIP+" << hex << offset << ">: " << &buf[6] << ends;
 	    strcpy(buf, newbuf);
 	}
 	if (!strnequ(&buf[9], "<_EIP", 5))
@@ -233,6 +239,7 @@
 	    bp++;
 	if (!isxdigit(*bp)) {
 	    cout << bp_0;
+#ifdef i386
 	} else if (*bp_1 == 'j' || strnequ(bp_1, "call", 4)) { // a jump or call insn
 	    long rel_addr = strtol(bp, 0, 16);
 	    ksym = find(eip_addr + rel_addr);
@@ -241,6 +248,21 @@
 		cout << bp_0 << *ksym << endl;
 	    } else
 		cout << bp_0;
+#endif
+#ifdef mc68000
+	} else if ((bp_1[0] == 'b' && bp_1[4] == ' ' && strchr("swl", bp_1[3]))
+		   || (bp_1[0] == 'd' && bp_1[1] == 'b')) {
+	    // a branch or decr-and-branch insn
+	    if (bp_1[0] == 'd') // skip register
+		while (*bp && *bp++ != ',');
+	    long rel_addr = strtoul(bp, 0, 16);
+	    ksym = find(eip_addr + rel_addr);
+	    if (ksym) {
+		*bp++ = '\0';
+		cout << bp_0 << *ksym << endl;
+	    } else
+	      cout << bp_0;
+#endif
 	} else {
 	    cout << bp_0;
 	}
@@ -308,6 +330,7 @@
 	if (cin.eof())
 	    break;
 	cin.get(c);	/* swallow newline */
+#ifdef i386
 	if (strstr(buffer, "EIP:") && names.valid()) {
 	    oops_column =  strstr(buffer, "EIP:");
 	    if (sscanf(oops_column+13, "[<%x>]", &eip_addr) != 1) {
@@ -321,6 +344,22 @@
 	    else
 		cout << ::hex << eip_addr << " cannot be resolved" << endl;
 	}
+#endif
+#ifdef mc68000
+	if (strstr(buffer, "PC:") && names.valid()) {
+	    oops_column =  strstr(buffer, "PC:");
+	    if (sscanf(oops_column+4, "[<%x>]", &eip_addr) != 1) {
+	    	cout << "Cannot read pc address from PC: line.  Is this a valid oops file?" << endl;
+		exit(1);
+	    }
+	    cout << ">>PC: ";
+	    KSym* ksym = names.find(eip_addr);
+	    if (ksym)
+		cout << *ksym << endl;
+	    else
+		cout << ::hex << eip_addr << " cannot be resolved" << endl;
+	}
+#endif
 	else if (oops_column && strstr(oops_column, "[<") && names.valid()) {
 	    unsigned long address;
 	    while (strstr(oops_column, "[<")) {
@@ -356,6 +395,9 @@
 		    ++p;
 		if (sscanf(p, "%x", &c) != 1)
 		    break;
+#ifdef mc68000
+		*cp++ = c >> 8;
+#endif
 		*cp++ = c;
 	    	while (*p && *p++ != ' ')
 		    ;
