diff -u --recursive --new-file v2.0.7/linux/CREDITS linux/CREDITS
--- v2.0.7/linux/CREDITS	Wed Jul 10 15:20:24 1996
+++ linux/CREDITS	Tue Jul 16 16:52:30 1996
@@ -225,7 +225,8 @@
 D: Originator of design for new combined interrupt handlers
 S: William Gates Department
 S: Stanford University
-S: Stanford, California 94305, USA
+S: Stanford, California 94305
+S: USA
 
 N: Juan Jose Ciarlante
 E: jjciarla@raiz.uncu.edu.ar
@@ -856,11 +857,11 @@
 N: Mike McLagan
 E: mike.mclagan@linux.org
 W: http://www.invlogic.com/~mmclagan
+D: DLCI/FRAD drivers for Sangoma SDLAs
 S: Innovative Logic Corp
 S: P.O. Box 1068
 S: Laurel, MD  20732
 S: USA
-D: DLCI/FRAD drivers for Sangoma SDLAs
 
 N: Bradley McLean
 E: brad@bradpc.gaylord.com
@@ -1191,8 +1192,8 @@
 S: c/o Ingenia Communications Corporation
 S: Suite 4200, CTTC Building
 S: 1125 Colonel By Drive
-S: Ottawa, Ontario, Canada
-S: K1S 5R1
+S: Ottawa, Ontario
+S: Canada K1S 5R1
 
 N: John Shifflett
 E: john@geolog.com
@@ -1276,7 +1277,7 @@
 S: IRISA
 S: Universit=E9 de Rennes I
 S: F-35042 Rennes Cedex
-S: FRANCE
+S: France
 
 N: Jon Tombs
 E: jon@gtex02.us.es
@@ -1445,6 +1446,7 @@
 S: Roger Maris Cancer Center
 S: 820 4th St. N.
 S: Fargo, ND  58122
+S: USA
 
 N: Hans-Joachim Widmaier
 E: jbhr@sofal.tynet.sub.org
@@ -1536,6 +1538,15 @@
 S: San Jose, California 95148
 S: USA
 
-# Don't add your name here, unless you really _are_ after Leonard
-# alphabetically.  Leonard is very proud of being the last entry,
-# and this file really _is_ supposed to be in alphabetic order.
+N: Marc Zyngier
+E: maz@gloups.fdn.fr
+D: MD driver
+S: 11 rue Victor HUGO
+S: 95560 Montsoult
+S: France
+
+# Don't add your name here, unless you really _are_ after Marc
+# alphabetically. Leonard used to be very proud of being the 
+# last entry, and he'll get positively pissed if he can't even
+# be second-to-last.  (and this file really _is_ supposed to be
+# in alphabetic order) 
diff -u --recursive --new-file v2.0.7/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.0.7/linux/Documentation/Configure.help	Wed Jul 17 08:12:15 1996
+++ linux/Documentation/Configure.help	Wed Jul 17 07:17:29 1996
@@ -238,34 +238,35 @@
   This driver is enabled at runtime using the "ide0=dtc2278" kernel
   boot parameter.  It enables support for the secondary IDE interface
   of the DTC-2278 card, and permits faster I/O speeds to be set as
-  well.  See the README.ide and dtc2278.c files for more info.
+  well.  See the Documentation/ide.txt and dtc2278.c files for more
+  info.
 
 Holtek HT6560B support
 CONFIG_BLK_DEV_HT6560B
   This driver is enabled at runtime using the "ide0=ht6560b" kernel
   boot parameter.  It enables support for the secondary IDE interface
   of the Holtek card, and permits faster I/O speeds to be set as well.
-  See the README.ide and ht6560b.c files for more info.
+  See the Documentation/ide.txt and ht6560b.c files for more info.
 
 QDI QD6580 support
 CONFIG_BLK_DEV_QD6580
   This driver is enabled at runtime using the "ide0=qd6580" kernel
-  boot parameter.  It permits faster I/O speeds to be set.
-  See the README.ide and qd6580.c files for more info.
+  boot parameter.  It permits faster I/O speeds to be set.  See the
+  Documentation/ide.txt and qd6580.c files for more info.
 
 UMC 8672 support
 CONFIG_BLK_DEV_UMC8672
   This driver is enabled at runtime using the "ide0=umc8672" kernel
   boot parameter.  It enables support for the secondary IDE interface
   of the UMC-8672, and permits faster I/O speeds to be set as well.
-  See the README.ide and umc8672.c files for more info.
+  See the Documentation/ide.txt and umc8672.c files for more info.
 
 ALI M1439/M1445 support
 CONFIG_BLK_DEV_ALI14XX
   This driver is enabled at runtime using the "ide0=ali14xx" kernel
   boot parameter.  It enables support for the secondary IDE interface
   of the chipset, and permits faster I/O speeds to be set as well.
-  See the README.ide and ali14xx.c files for more info.
+  See the Documentation/ide.txt and ali14xx.c files for more info.
 
 PROMISE DC4030 support (EXPERIMENTAL)
 CONFIG_BLK_DEV_PROMISE
@@ -273,9 +274,9 @@
   boot parameter.  It enables support for the secondary IDE interface
   of the chipset, and takes advantage of the caching features of the
   card.  This driver is known to incur timeouts/retries during heavy
-  I/O to drives attached to the secondary interface.  CDROM and
-  TAPE devices are not supported yet.
-  See the README.ide and promise.c files for more info.
+  I/O to drives attached to the secondary interface.  CDROM and TAPE
+  devices are not supported yet.  See the Documentation/ide.txt and
+  promise.c files for more info.
 
 XT harddisk support
 CONFIG_BLK_DEV_XD
@@ -823,17 +824,19 @@
   about 2kB. You may need to read the FIREWALL-HOWTO, available via
   ftp (user: anonymous) in
   sunsite.unc.edu:/pub/Linux/docs/HOWTO. Also, you will need the
-  ipfwadm tool to allow selective blocking of internet traffic based
+  ipfwadm tool (available via ftp (user: anonymous) from ftp.xos.nl) 
+  to allow selective blocking of internet traffic based
   on type, origin and destination.  You need to enable IP firewalling
   in order to be able to use IP masquerading (i.e. local computers can
   chat with an outside host, but that outside host is made to think
   that it is talking to the firewall box. Makes the local network
   completely invisible and avoids the need to allocate valid IP host
-  addresses for the machines on the local net) or to use the ip packet
+  addresses for the machines on the local net) or to use the IP packet
   accounting to see what is using all your network bandwidth.
   This option is also needed when you want to enable the transparent
-  proxying support (via which non-local connections can be redirected
-  to local proxy servers).
+  proxying support (makes the computers on the local network think
+  they're talking to a remote computer, while in reality the traffic
+  is redirected by your Linux firewall to a local proxy server).
 
 IP: accounting
 CONFIG_IP_ACCT
@@ -853,10 +856,12 @@
   encapsulating protocol. This particular tunneling driver implements
   encapsulation of IP within IP, which sounds kind of pointless, but
   can be useful if you want to make your (or some other) machine
-  appear on a different network than it physically is, or to use the 
-  mobile IP facilities (which effectively are doing that). Enabling this
-  option will produce two modules ( = code which can be inserted in
-  and removed from the running kernel whenever you want), one
+  appear on a different network than it physically is, or to use
+  mobile-IP facilities (allowing laptops to seamlessly move between
+  networks without changing their IP addresses; check out
+  http://anchor.cs.binghamton.edu/~mobileip/LJ/index.html). Enabling
+  this option will produce two modules ( = code which can be inserted
+  in and removed from the running kernel whenever you want), one
   encapsulator and one decapsulator. You can read details in
   drivers/net/README.tunnel. Most people can say N.
   
@@ -868,10 +873,14 @@
 
 IP: transparent proxying (EXPERIMENTAL)
 CONFIG_IP_TRANSPARENT_PROXY
-  This enables you to redirect any network traffic to a local server,
-  acting as a "transparent proxy server".  Redirection is activated
-  by defining special input firewall rules (using the ipfwadm utility)
-  and/or by doing an appropriate bind() system call.
+  This enables your Linux firewall to transparently redirect any
+  network traffic originating from the local network and destined
+  for a remote host to a local server, called a "transparent proxy
+  server".  This makes the local computers think they are talking to
+  the remote end, while in fact they are connected to the local
+  proxy. Redirection is activated by defining special input firewall
+  rules (using the ipfwadm utility) and/or by doing an appropriate
+  bind() system call.
 
 IP: masquerading (EXPERIMENTAL)
 CONFIG_IP_MASQUERADE
@@ -889,28 +898,31 @@
   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
-  from ftp://sunsite.unc.edu/pub/Linux/system/Network/serial/
+  from ftp://sunsite.unc.edu/pub/Linux/system/Network/serial/].)
   Details on how to set things up are contained in the
   IP Masquerading FAQ, available at http://www.indyramp.com/masq/
   This is EXPERIMENTAL code, which means that it need not be completely
   stable. If you want this, say Y.
 
-IP: always defragment
-CONFIG_IP_ALWAYS_DEFRAG
-   This option means that all incoming fragments will be reassembled
-   (defragmented) before being processed, even if those packets
-   should be forwarded.  This option is highly recommended if you
-   have enabled CONFIG_IP_MASQUERADE, because these facilities requires
-   that second and further fragments can be related to TCP or UDP port
-   numbers, which are only stored in the first fragment.  When using
-   CONFIG_IP_FIREWALL, you might also want to enable this option, to
-   have a more reliable firewall (otherwise second and further fragments
-   will always be accepted by the firewall).  When using transparent
-   proxying (CONFIG_IP_TRANSPARENT_PROXY), this option is implicit,
-   although it is safe to say Y here. Do not say Y to this option except
-   when running either a firewall that is the sole link to your network or
-   a transparent proxy. Never ever say Y to this for a normal router or
-   host.
+IP: always defragment 
+CONFIG_IP_ALWAYS_DEFRAG 
+  This option means that all incoming fragments (= parts of IP packets
+  that arose when some host between origin and destination decided
+  that the IP packets were too large and cut them in pieces) will be
+  reassembled (defragmented) before being processed, even if they are
+  about to be forwarded.  This option is highly recommended if you
+  have enabled the masquerading support (CONFIG_IP_MASQUERADE),
+  because this facility requires that second and further fragments can
+  be related to TCP or UDP port numbers, which are only stored in the
+  first fragment.  When using IP firewall support
+  (CONFIG_IP_FIREWALL), you might also want to enable this option, to
+  have a more reliable firewall (otherwise second and further
+  fragments will always be accepted by the firewall).  When using
+  transparent proxying (CONFIG_IP_TRANSPARENT_PROXY), this option is
+  implicit, although it is safe to say Y here. Do not say Y to this
+  option except when running either a firewall that is the sole link
+  to your network or a transparent proxy. Never ever say Y to this for
+  a normal router or host.
 
 IP: aliasing support
 CONFIG_IP_ALIAS
@@ -1252,13 +1264,14 @@
 
 Adaptec AHA152X/2825 support
 CONFIG_SCSI_AHA152X
-  This is support for a SCSI host adaptor. It is explained in section
-  3.3 of the SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't work out of the
-  box, you may have to change some settings in drivers/scsi/aha152x.h.
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you
-  want). If you want to compile it as a module, say M here and read
+  This is support for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
+  SCSI host adaptors. It is explained in section 3.3 of the
+  SCSI-HOWTO, available via ftp (user: anonymous) at
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO. You might also want to read
+  the comments at the top of drivers/scsi/aha152x.c. This driver is
+  also available as a module ( = code which can be inserted in and
+  removed from the running kernel whenever you want). If you want to
+  compile it as a module, say M here and read
   Documentation/modules.txt.
 
 Adaptec AHA1542 support
@@ -1322,26 +1335,27 @@
 
 EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support
 CONFIG_SCSI_EATA_DMA
-  This is support for the EATA-DMA protocol compliant SCSI Host Adaptors
-  like the SmartCache III/IV, SmartRAID controller families and the DPT 
-  PM2011B and PM2012B controllers.  
-  Please read the SCSI-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. 
-  This driver is also available as a module (= code which can be inserted 
-  in and removed from the running kernel whenever you want). If you want 
-  to compile it as a module, say M here and read Documentation/modules.txt.
+  This is support for the EATA-DMA protocol compliant SCSI Host
+  Adaptors like the SmartCache III/IV, SmartRAID controller families
+  and the DPT PM2011B and PM2012B controllers.  Please read the
+  SCSI-HOWTO, available via ftp (user: anonymous) at
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  This driver is also
+  available as a module (= code which can be inserted in and removed
+  from the running kernel whenever you want). If you want to compile
+  it as a module, say M here and read Documentation/modules.txt.
 
 EATA-PIO (old DPT PM2001, PM2012A) support
 CONFIG_SCSI_EATA_PIO
-  This driver supports all EATA-PIO protocol compliant SCSI Host Adaptors
-  like the DPT PM2001 and the PM2012A. EATA-DMA compliant HBAs can also use 
-  this driver but are discouraged from doing so, since this driver only 
-  supports harddisks and lacks numerous features.
-  You might want to have a look at the SCSI-HOWTO, available via ftp 
-  (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO.  
-  If you want to compile this as a module ( = code which can be inserted 
-  in and removed from the running kernel whenever you want), say M here 
-  and read Documentation/modules.txt.
+  This driver supports all EATA-PIO protocol compliant SCSI Host
+  Adaptors like the DPT PM2001 and the PM2012A. EATA-DMA compliant
+  HBAs can also use this driver but are discouraged from doing so,
+  since this driver only supports harddisks and lacks numerous
+  features.  You might want to have a look at the SCSI-HOWTO,
+  available via ftp (user: anonymous) at
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to compile this
+  as a module ( = code which can be inserted in and removed from the
+  running kernel whenever you want), say M here and read
+  Documentation/modules.txt.
 
 UltraStor 14F/34F support
 CONFIG_SCSI_U14_34F
@@ -1424,91 +1438,94 @@
  
 allow DISCONNECT
 CONFIG_SCSI_NCR53C7xx_DISCONNECT
-  This enables the disconnect/reconnect feature of the NCR SCSI controller.
-  When this is enabled, a slow SCSI device will not lock the SCSI bus
-  while processing a request, allowing simultaneous use of e.g. a SCSI
-  hard disk and SCSI tape or CD-ROM drive, and providing much better 
-  performance when using slow and fast SCSI devices at the same time. Some 
-  devices, however, do not operate properly with this option enabled, and 
-  will cause your SCSI system to hang, which might cause a system crash. 
-  The safe answer therefore is to say N.
+  This enables the disconnect/reconnect feature of the NCR SCSI
+  controller.  When this is enabled, a slow SCSI device will not lock
+  the SCSI bus while processing a request, allowing simultaneous use
+  of e.g. a SCSI hard disk and SCSI tape or CD-ROM drive, and
+  providing much better performance when using slow and fast SCSI
+  devices at the same time. Some devices, however, do not operate
+  properly with this option enabled, and will cause your SCSI system
+  to hang, which might cause a system crash.  The safe answer
+  therefore is to say N.
 
 NCR53C8XX SCSI support
 CONFIG_SCSI_NCR53C8XX
-  This is the BSD ncr driver adapted to linux for NCR53C8XX family of PCI-SCSI 
-  controllers. This driver supports parity checking, tagged command queueing,
-  fast scsi II transfer up to 10 MB/s with narrow scsi devices and 20 MB/s
-  with wide scsi devices.
-  This driver has been tested ok with linux/i386  and is currently untested
-  under linux/Alpha. If you intend to use this driver under linux/Alpha, just 
-  try it first with read-only or mounted read-only devices.
-  Memory mapped io are currently not supported under linux/Alpha.
+  This is the BSD ncr driver adapted to linux for the NCR53C8XX family
+  of PCI-SCSI controllers. This driver supports parity checking,
+  tagged command queuing, fast scsi II transfer up to 10 MB/s with
+  narrow scsi devices and 20 MB/s with wide scsi devices.
+  This driver has been tested OK with linux/i386 and is currently
+  untested under linux/Alpha. If you intend to use this driver under
+  linux/Alpha, just try it first with read-only or mounted read-only
+  devices.  Memory mapped io is currently not supported under
+  linux/Alpha. Please read drivers/scsi/README.ncr53c8xx for more
+  information. 
 
 force normal IO
 CONFIG_SCSI_NCR53C8XX_IOMAPPED
-  Under linux/Alpha only normal io are currently supported.
-  Under linux/i386, this option allow to force the driver to use normal IO.
-  Memory mapped IO have less latency than normal IO.
-  During initialisation phase, the driver first tries to use memory mapped io.
-  If nothing seems wrong, it will use memory mapped io.
-  If a flaw is detected,  it will use normal io.
-  However, it's possible that memory mapped does not work properly for you and 
-  the driver has not detected the problem.
-  The normal answer therefore is N.
+  Under linux/Alpha only normal io is currently supported.
+  Under linux/i386, this option allows you to force the driver to use
+  normal IO.  Memory mapped IO has less latency than normal IO.
+  During the initialization phase, the driver first tries to use
+  memory mapped io.  If nothing seems wrong, it will use memory mapped
+  io.  If a flaw is detected, it will use normal io.  However, it's
+  possible that memory mapped does not work properly for you and the
+  driver has not detected the problem; then you would want to say Y
+  here.  The normal answer therefore is N.
 
 not allow targets to disconnect
 CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
-  This option is only provided for safe if you suspect some scsi device 
-  of yours to not support properly this feature.
-  To not allow targets to disconnect is not reasonnable if there is more 
-  than 1 device on a scsi bus.
-  The normal answer therefore is N.
+  This option is only provided for safety if you suspect some scsi
+  device of yours to not support properly this feature. In that case,
+  you would say Y here. In general however, to not allow targets to
+  disconnect is not reasonable if there is more than 1 device on a
+  scsi bus.  The normal answer therefore is N.
 
-enable tagged command queueing
+enable tagged command queuing
 CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
-  This option allow to enable tagged command queuing support at linux start-up.
-  Some scsi devices do not support properly this feature.
-  The suggested method may be to not validate this option in the configuration 
-  but to use the "settags" control command after boot-up to enable this feature.
+  This option allows you to enable tagged command queuing support at
+  linux start-up.  Some scsi devices do not properly support this
+  feature.  The suggested method is to say N here and to use the
+  "settags" control command after boot-up to enable this feature:
       echo "settags 2 4" >/proc/scsi/ncr53c8xx/0
-  Ask the driver to use up to 4 concurrent tagged commands for target 2 of 
-  controller 0.
-  See the README.ncr53c8xx file for more information.
-  WARNING! tagged queue support requires to allow targets to disconnect.
+  asks the driver to use up to 4 concurrent tagged commands for target
+  2 of controller 0.
+  See the file drivers/scsi/README.ncr53c8xx for more information.
+  WARNING! tagged queue support requires to allow targets to
+  disconnect (see above).
   The safe answer therefore is N.
   The normal answer therefore is Y.
 
 force asynchronous transfer mode
 CONFIG_SCSI_NCR53C8XX_FORCE_ASYNCHRONOUS
-  This option allow to force asynchronous transfer mode for all devices at 
-  linux startup. You can enable synchronous negotiation with the "setsync" 
-  control command after boot-up, for example:
+  This option allows you to force asynchronous transfer mode for all
+  devices at linux startup. You can enable synchronous negotiation
+  with the "setsync" control command after boot-up, for example:
      echo "setsync 2 25" >/proc/scsi/ncr53c8xx/0
-  Ask the driver to set the period to 25 ns (10MB/sec) for target 2 of 
-  controller 0.
-  The safe answer therefore is Y.
-  The normal answer therefore is N.
+  asks the driver to set the period to 25 ns (10MB/sec) for target 2
+  of controller 0 (please read drivers/scsi/README.ncr53c8xx for more
+  information). The safe answer therefore is Y.  The normal answer
+  therefore is N.
  
 force synchronous negotiation
 CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
-  Some scsi-2 devices support synchronous negotiations but do not report 
-  this feature in byte 7 of inquiry data.
+  Some scsi-2 devices support synchronous negotiations but do not
+  report this feature in byte 7 of inquiry data.
   Answer Y only if you suspect some device to be so humble.
   The normal answer therefore is N.
  
 disable master parity checking
 CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
-  Some hardware may have problems with parity during master cycles on PCI bus.
-  Only seen once. Answer Y if you suspect such problem.
-  The normal answer therefore is N.
+  Some hardware may have problems with parity during master cycles on
+  PCI bus.  Only seen once. Answer Y if you suspect such problem.  The
+  normal answer therefore is N.
 
 disable scsi parity checking
 CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
-  Parity on scsi bus is a system option. If one device checks parity, then 
-  all devices on the scsi bus must generate parity.
-  However, the parity can be ignored by the scsi devices.
-  Answer Y only if you know what you are doing.
-  The normal answer therefore is N.
+  Parity on scsi bus is a system option. If one device checks parity,
+  then all devices on the scsi bus must generate parity.  However, the
+  parity can be ignored by the scsi devices.  Answer Y only if you
+  know what you are doing.  The normal answer therefore is N.
 
 Always IN2000 SCSI support
 CONFIG_SCSI_IN2000
@@ -2637,7 +2654,7 @@
   FX-001 or FX-001D CDROM drive. In addition, this driver uses much less
   kernel memory than the old one, if that is a concern. This driver is
   able to support more than one drive, but each drive needs a separate
-  interface card.
+  interface card. Check out Documentation/cdrom/mcdx.
 
 Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support
 CONFIG_SBPCD
@@ -2698,7 +2715,11 @@
 
 Optics Storage DOLPHIN 8000AT CDROM support
 CONFIG_OPTCD
-  If this is your CDROM drive, say Y here.
+  This is the driver for the 'DOLPHIN' drive with a 34-pin Sony
+  compatible interface. It also works with the Lasermate CR328A. If
+  you have one of those, say Y. This driver does not work for the
+  Optics Storage 8001 drive; use the IDE-ATAPI CDROM driver for this
+  one. 
 
 Sanyo CDR-H94A CDROM support
 CONFIG_SJCD
@@ -3116,17 +3137,18 @@
   serial ports.  People who might say N here are those that are
   setting up dedicated ethernet WWW/ftp servers, or users that have
   one of the various bus mice instead of a serial mouse.  (Note that
-  the Cyclades and Stallion drivers do not need this driver built in
-  for them to work. They are completely independent of each other.)
-  If you want to compile this driver as a module, say M here and read
-  Documentation/modules.txt.  [WARNING: Do not compile this driver as
-  a module if you are using non-standard serial ports, since the
-  configuration information will be lost when kerneld automatically
-  unloads the driver.  This limitation may be lifted in the future.]
-  Most people will say Y or M here, so that they can use serial mice,
-  modems and similar devices connecting to the standard serial ports.
+  the Cyclades and Stallion multi serial port drivers do not need this
+  driver built in for them to work. They are completely independent of
+  each other.)  If you want to compile this driver as a module, say M
+  here and read Documentation/modules.txt.  [WARNING: Do not compile
+  this driver as a module if you are using non-standard serial ports,
+  since the configuration information will be lost when kerneld
+  automatically unloads the driver.  This limitation may be lifted in
+  the future.]  Most people will say Y or M here, so that they can use
+  serial mice, modems and similar devices connecting to the standard
+  serial ports.
 
-Digiboard PC/X Support
+Digiboard PC/Xx Support
 CONFIG_DIGI
   This is a driver for the Digiboard PC/Xe, PC/Xi, and PC/Xeve cards
   that give you many serial ports. You would need something like this
@@ -3207,6 +3229,22 @@
   tells you how to specify the port and IRQ to be used by PLIP at
   module load time.
 
+
+Mouse Support (not serial mice)
+CONFIG_MOUSE
+  This is for machines with a bus mouse or a PS/2 mouse as opposed to
+  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
+  (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO and say Y
+  here. If you have a laptop, you either have to check the
+  documentation or experiment a bit to find out whether the trackball
+  is a serial mouse or not; it's best to say Y here for you. Note that
+  the answer to this question won't directly affect the kernel: saying
+  N will just cause this configure script to skip all the questions
+  about non-serial mice.  If unsure, say Y.
+
 Logitech busmouse support
 CONFIG_BUSMOUSE
   Logitech mouse connected to a proprietary interface card. It's
@@ -3218,10 +3256,7 @@
   as a module ( = code which can be inserted in and removed from the
   running kernel whenever you want), say M here and read
   Documentation/modules.txt. If you are unsure, say N and read the
-  HOWTO nevertheless: it will tell you what you have. Chances are that
-  you have a regular serial MouseSystem or Microsoft mouse (made by
-  Logitech) plugging in a COM port (rectangular with 9 or 25 pins)
-  which is supported automatically.
+  HOWTO nevertheless: it will tell you what you have. 
 
 PS/2 mouse (aka "auxiliary device") support
 CONFIG_PSMOUSE
@@ -3230,16 +3265,15 @@
   the mouse does not use any serial ports. This port can also be used
   for other input devices like light pens, tablets, keypads. Compaq,
   AST and IBM all use this as their mouse port on currently shipping
-  machines. The trackballs of some laptops are PS/2 mice
-  also. Although this is not a busmouse, it is explained in detail in
-  the Busmouse-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to compile this
-  as a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want), say M here and read
-  Documentation/modules.txt. If you are unsure, say N and read the
-  HOWTO nevertheless: it will tell you what you have. Chances are that
-  you have a regular serial MouseSystem or Microsoft mouse plugging in
-  a COM port (9 or 25 pins) which is supported automatically.
+  machines. The trackballs of some laptops are PS/2 mice also. In
+  particular, the C&T 82C710 mouse on TI Travelmates is a PS/2
+  mouse. Although PS/2 mice are not technically bus mice, they are
+  explained in detail in the Busmouse-HOWTO, available via ftp (user:
+  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to
+  compile this as a module ( = code which can be inserted in and
+  removed from the running kernel whenever you want), say M here and
+  read Documentation/modules.txt. If you are unsure, say N and read
+  the HOWTO nevertheless: it will tell you what you have.
 
 C&T 82C710 mouse port support (as on TI Travelmate)
 CONFIG_82C710_MOUSE
@@ -3257,11 +3291,9 @@
   want to compile this as a module ( = code which can be inserted in
   and removed from the running kernel whenever you want), say M here
   and read Documentation/modules.txt. If you are unsure, say N and
-  read the HOWTO nevertheless: it will tell you what you have. Chances
-  are that you have a regular serial MouseSystem or Microsoft mouse
-  plugging in a COM port which is supported automatically. Also be aware
-  several vendors talk about 'Microsoft busmouse' and actually mean PS/2
-  busmouse - so count the pins on the connector.
+  read the HOWTO nevertheless: it will tell you what you have. Also be
+  aware that several vendors talk about 'Microsoft busmouse' and
+  actually mean PS/2 busmouse - so count the pins on the connector.
 
 ATIXL busmouse support
 CONFIG_ATIXL_BUSMOUSE
@@ -3272,10 +3304,7 @@
   compile this as a module ( = code which can be inserted in and
   removed from the running kernel whenever you want), say M here and
   read Documentation/modules.txt. If you are unsure, say N and read
-  the HOWTO nevertheless: it will tell you what you have. Chances are
-  that you have a regular serial MouseSystem or Microsoft mouse
-  plugging in a COM port (9 or 25 pins) which is supported
-  automatically.
+  the HOWTO nevertheless: it will tell you what you have. 
 
 Support for user miscellaneous modules
 CONFIG_UMISC
@@ -3681,7 +3710,8 @@
   with the ISDN utility package for example), you will be able
   to use your Linux box as an ISDN-answering machine. Of course, this
   must be supported by the lowlevel driver also. Currently, the Teles
-  driver is the only voice-supporting one.
+  driver is the only voice-supporting one. See
+  Documentation/isdn/README.audio for more information.
 
 ICN 2B and 4B support
 CONFIG_ISDN_DRV_ICN
@@ -3790,9 +3820,18 @@
 # 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
 # LocalWords:  hitchcock Crynwr cnam pktdrvr NCSA's CyDROM CyCDROM FreeBSD NeXT
-# LocalWords:  NeXTstep disklabel disklabels SMD FFS tm AmigaOS diskfiles Un
+# LocalWords:  NeXTstep disklabel disklabels SMD FFS tm AmigaOS diskfiles Un IQ
 # 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
+# LocalWords:  winsock RNIS caltech OSPF honour Honouring Mbit Localtalk DEFRAG
 # LocalWords:  localtalk download Packetwin Baycom baycom interwork ascii JNT
-# LocalWords:  Camtec
+# 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
+# LocalWords:  Thunderboard SM OPL FM ADLIB TSR Gravis MPU PSS ADI SW DSP codec
+# LocalWords:  ADSP ESC ASIC daughtercard GUSMAX MSS NX AdLib Excell Ensoniq YM
+# LocalWords:  SoundScape Spea MediaTriX AudioTriX WSS OTI ThunderBoard VoxWare
+# LocalWords:  Soundscape SSCAPE TRIX MediaTrix PnP Maui dsp midixx EIA getty
+# LocalWords:  mgetty sendfax gert greenie muc lowlevel Lasermate LanManager io
+# LocalWords:  OOPSes trackball binghamton mobileip ncr IOMAPPED settags ns ser
+# LocalWords:  setsync NEGO MPARITY
diff -u --recursive --new-file v2.0.7/linux/Makefile linux/Makefile
--- v2.0.7/linux/Makefile	Wed Jul 17 08:12:15 1996
+++ linux/Makefile	Wed Jul 17 15:30:17 1996
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 0
-SUBLEVEL = 7
+SUBLEVEL = 8
 
 ARCH = i386
 
diff -u --recursive --new-file v2.0.7/linux/arch/alpha/lib/csum_partial_copy.c linux/arch/alpha/lib/csum_partial_copy.c
--- v2.0.7/linux/arch/alpha/lib/csum_partial_copy.c	Wed Jul 17 08:12:15 1996
+++ linux/arch/alpha/lib/csum_partial_copy.c	Wed Jul 17 14:39:21 1996
@@ -36,25 +36,26 @@
  */
 static inline unsigned long csum_partial_copy_aligned(
 	unsigned long *src, unsigned long *dst,
-	long len, unsigned long checksum,
-	unsigned long word)
+	long len, unsigned long checksum)
 {
 	unsigned long carry = 0;
 
 	while (len >= 0) {
+		unsigned long word = *src;
 		checksum += carry;
 		src++;
 		checksum += word;
 		len -= 8;
 		carry = checksum < word;
 		*dst = word;
-		word = *src;
 		dst++;
 	}
 	len += 8;
 	checksum += carry;
 	if (len) {
-		unsigned long tmp = *dst;
+		unsigned long word, tmp;
+		word = *src;
+		tmp = *dst;
 		mskql(word, len, word);
 		checksum += word;
 		mskqh(tmp, len, tmp);
@@ -72,11 +73,14 @@
 static inline unsigned long csum_partial_copy_dest_aligned(
 	unsigned long *src, unsigned long *dst,
 	unsigned long soff,
-	long len, unsigned long checksum,
-	unsigned long first)
+	long len, unsigned long checksum)
 {
-	unsigned long word, carry = 0;
+	unsigned long first;
+	unsigned long word, carry;
+	unsigned long lastsrc = 7+len+(unsigned long)src;
 
+	ldq_u(first,src);
+	carry = 0;
 	while (len >= 0) {
 		unsigned long second;
 
@@ -98,7 +102,7 @@
 	if (len) {
 		unsigned long tmp;
 		unsigned long second;
-		ldq_u(second, src+1);
+		ldq_u(second, lastsrc);
 		tmp = *dst;
 		extql(first, soff, word);
 		extqh(second, soff, first);
@@ -120,15 +124,15 @@
 	unsigned long *src, unsigned long *dst,
 	unsigned long doff,
 	long len, unsigned long checksum,
-	unsigned long word,
 	unsigned long partial_dest)
 {
 	unsigned long carry = 0;
+	unsigned long word;
 
 	mskql(partial_dest, doff, partial_dest);
 	while (len >= 0) {
 		unsigned long second_dest;
-
+		word = *src;
 		len -= 8;
 		insql(word, doff, second_dest);
 		checksum += carry;
@@ -137,16 +141,14 @@
 		checksum += word;
 		insqh(word, doff, partial_dest);
 		carry = checksum < word;
-		word = *src;
 		dst++;
 	}
 	len += doff;
 	checksum += carry;
 	if (len >= 0) {
 		unsigned long second_dest;
-
+		word = *src;
 		mskql(word, len-doff, word);
-		src++;
 		checksum += word;
 		insql(word, doff, second_dest);
 		stq_u(partial_dest | second_dest, dst);
@@ -160,6 +162,7 @@
 		checksum += carry;
 	} else if (len & 7) {
 		unsigned long second_dest;
+		word = *src;
 		ldq_u(second_dest, dst);
 		mskql(word, len-doff, word);
 		checksum += word;
@@ -180,10 +183,14 @@
 	unsigned long * src, unsigned long * dst,
 	unsigned long soff, unsigned long doff,
 	long len, unsigned long checksum,
-	unsigned long first, unsigned long partial_dest)
+	unsigned long partial_dest)
 {
 	unsigned long carry = 0;
+	unsigned long first;
+	unsigned long lastsrc;
 
+	ldq_u(first, src);
+	lastsrc = 7+len+(unsigned long)src;
 	mskql(partial_dest, doff, partial_dest);
 	while (len >= 0) {
 		unsigned long second, word;
@@ -210,11 +217,10 @@
 		unsigned long second, word;
 		unsigned long second_dest;
 		
-		ldq_u(second, src+1);
+		ldq_u(second, lastsrc);
 		extql(first, soff, word);
 		extqh(second, soff, first);
 		word |= first;
-		src++;
 		first = second;
 		mskql(word, len-doff, word);
 		checksum += word;
@@ -232,7 +238,7 @@
 		unsigned long second, word;
 		unsigned long second_dest;
 
-		ldq_u(second, src+1);
+		ldq_u(second, lastsrc);
 		extql(first, soff, word);
 		extqh(second, soff, first);
 		word |= first;
@@ -255,19 +261,17 @@
 	unsigned long doff = 7 & (unsigned long) dst;
 
 	if (len) {
-		unsigned long first;
-		ldq_u(first, src);
 		if (!doff) {
 			if (!soff)
 				checksum = csum_partial_copy_aligned(
 					(unsigned long *) src,
 					(unsigned long *) dst,
-					len-8, checksum, first);
+					len-8, checksum);
 			else
 				checksum = csum_partial_copy_dest_aligned(
 					(unsigned long *) src,
 					(unsigned long *) dst,
-					soff, len-8, checksum, first);
+					soff, len-8, checksum);
 		} else {
 			unsigned long partial_dest;
 			ldq_u(partial_dest, dst);
@@ -276,13 +280,13 @@
 					(unsigned long *) src,
 					(unsigned long *) dst,
 					doff, len-8, checksum,
-					first, partial_dest);
+					partial_dest);
 			else
 				checksum = csum_partial_copy_unaligned(
 					(unsigned long *) src,
 					(unsigned long *) dst,
 					soff, doff, len-8, checksum,
-					first, partial_dest);
+					partial_dest);
 		}
 		/* 64 -> 33 bits */
 		checksum = (checksum & 0xffffffff) + (checksum >> 32);
diff -u --recursive --new-file v2.0.7/linux/arch/i386/Makefile linux/arch/i386/Makefile
--- v2.0.7/linux/arch/i386/Makefile	Sat Mar  9 13:31:42 1996
+++ linux/arch/i386/Makefile	Wed Jul 17 14:59:14 1996
@@ -37,9 +37,10 @@
 
 LD=$(CROSS_COMPILE)ld -m elf_i386
 CPP=$(CC) -E -D__ELF__
-OBJDUMP =$(CROSS_COMPILE)objdump
-ENCAPS=$(CROSS_COMPILE)encaps
+OBJDUMP=$(CROSS_COMPILE)objdump
 OBJDUMP_FLAGS=-k -q 
+ENCAPS=$(CROSS_COMPILE)encaps
+OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment
 ZLDFLAGS=-e startup_32 
 LDFLAGS=-e stext
 ZIMAGE_OFFSET=0x1000
diff -u --recursive --new-file v2.0.7/linux/arch/i386/boot/Makefile linux/arch/i386/boot/Makefile
--- v2.0.7/linux/arch/i386/boot/Makefile	Tue May  7 16:22:17 1996
+++ linux/arch/i386/boot/Makefile	Wed Jul 17 14:59:14 1996
@@ -18,7 +18,11 @@
 
 zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
 ifdef CONFIG_KERNEL_ELF
-	$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out
+	if hash $(ENCAPS) 2> /dev/null; then \
+	  $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out; \
+	else \
+	  $(OBJCOPY) compressed/vmlinux compressed/vmlinux.out; \
+	fi
 	tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
 else
 	tools/build bootsect setup compressed/vmlinux $(ROOT_DEV) > zImage
@@ -27,7 +31,11 @@
 
 bzImage: $(CONFIGURE) bbootsect setup compressed/bvmlinux tools/bbuild
 ifdef CONFIG_KERNEL_ELF
-	$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out
+	if hash $(ENCAPS) 2> /dev/null; then \
+	  $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \
+	else \
+	  $(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out; \
+	fi
 	tools/bbuild bbootsect setup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
 else
 	tools/bbuild bbootsect setup compressed/bvmlinux $(ROOT_DEV) > bzImage
diff -u --recursive --new-file v2.0.7/linux/arch/i386/boot/compressed/Makefile linux/arch/i386/boot/compressed/Makefile
--- v2.0.7/linux/arch/i386/boot/compressed/Makefile	Sat Mar  9 13:31:42 1996
+++ linux/arch/i386/boot/compressed/Makefile	Wed Jul 17 14:59:14 1996
@@ -46,12 +46,21 @@
 # You cannot compress a file and have the kernel uncompress it, it must
 # be stdin
 piggy.o:	$(SYSTEM)
-	tmppiggy=/tmp/$$$$.piggy; \
-	rm -f $$tmppiggy $$tmppiggy.gz; \
-	$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) $(SYSTEM) > $$tmppiggy; \
+	tmppiggy=/tmp/$$$$piggy; \
+	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
+	if hash $(ENCAPS) 2> /dev/null; then \
+	  $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) $(SYSTEM) > $$tmppiggy; \
+	else \
+	  $(OBJCOPY) $(SYSTEM) $$tmppiggy; \
+	fi; \
 	gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
-	$(ENCAPS) $(TARGET) piggy.o $$tmppiggy.gz $(INPUT_DATA) $(INPUT_LEN); \
-	rm -f $$tmppiggy $$tmppiggy.gz
+	if hash $(ENCAPS) 2> /dev/null; then \
+	  $(ENCAPS) $(TARGET) piggy.o $$tmppiggy.gz $(INPUT_DATA) $(INPUT_LEN); \
+	else \
+	  echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+	  ld -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
+	fi; \
+	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
 else
 
 piggy.o:	$(SYSTEM) xtract piggyback
diff -u --recursive --new-file v2.0.7/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.0.7/linux/arch/i386/kernel/entry.S	Wed May 15 11:01:14 1996
+++ linux/arch/i386/kernel/entry.S	Wed Jul 17 12:33:25 1996
@@ -381,22 +381,21 @@
 	push %es
 	push %ds
 	pushl %eax
+	xorl %eax,%eax
 	pushl %ebp
 	pushl %edi
 	pushl %esi
 	pushl %edx
+	decl %eax			# eax = -1
 	pushl %ecx
 	pushl %ebx
-	movl $0,%eax
-	movl %eax,%db7			# disable hardware debugging...
 	cld
-	movl $-1, %eax
-	xchgl %eax, ORIG_EAX(%esp)	# orig_eax (get the error code. )
 	xorl %ebx,%ebx			# zero ebx
+	xchgl %eax, ORIG_EAX(%esp)	# orig_eax (get the error code. )
 	mov %gs,%bx			# get the lower order bits of gs
+	movl %esp,%edx
 	xchgl %ebx, GS(%esp)		# get the address and save gs.
 	pushl %eax			# push the error code
-	lea 4(%esp),%edx
 	pushl %edx
 	movl $(KERNEL_DS),%edx
 	mov %dx,%ds
@@ -405,9 +404,6 @@
 	mov %dx,%fs
 #ifdef __SMP__
 	ENTER_KERNEL
-#endif
-	pushl %eax
-#ifdef __SMP__
 	GET_PROCESSOR_OFFSET(%eax)
 	movl SYMBOL_NAME(current_set)(,%eax), %eax
 #else
@@ -415,7 +411,6 @@
 #endif
 	movl %db6,%edx
 	movl %edx,dbgreg6(%eax)  # save current hardware debugging status
-	popl %eax
 	call *%ebx
 	addl $8,%esp
 	jmp ret_from_sys_call
diff -u --recursive --new-file v2.0.7/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.0.7/linux/drivers/block/floppy.c	Sat Jun  1 20:11:30 1996
+++ linux/drivers/block/floppy.c	Mon Jul 15 16:59:30 1996
@@ -155,6 +155,7 @@
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h> /* CMOS defines */
 #include <linux/ioport.h>
+#include <linux/interrupt.h>
 
 #include <asm/dma.h>
 #include <asm/irq.h>
@@ -1039,6 +1040,7 @@
 	INT_OFF;
 	fd_disable_dma();
 	fd_clear_dma_ff();
+	fd_cacheflush(raw_cmd->kernel_data, raw_cmd->length);
 	fd_set_dma_mode((raw_cmd->flags & FD_RAW_READ)?
 			DMA_MODE_READ : DMA_MODE_WRITE);
 	fd_set_dma_addr(virt_to_bus(raw_cmd->kernel_data));
@@ -1685,9 +1687,15 @@
 		} while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
 	}
 	if (handler) {
-		/* expected interrupt */
-		floppy_tq.routine = (void *)(void *) handler;
-		queue_task_irq(&floppy_tq, &tq_timer);
+		if(intr_count >= 2)
+			{
+				/* expected interrupt */
+				floppy_tq.routine = (void *)(void *) handler;
+				queue_task_irq(&floppy_tq, &tq_immediate);
+				mark_bh(IMMEDIATE_BH);
+			}
+		else
+			handler();
 	} else
 		FDCS->reset = 1;
 	is_alive("normal interrupt end");
@@ -1925,8 +1933,8 @@
 	unsigned long flags;
 
 	floppy_tq.routine = (void *)(void *) handler;
-	queue_task(&floppy_tq, &tq_timer);
-
+	queue_task(&floppy_tq, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
 	INT_OFF;
 	while(command_status < 2 && NO_SIGNAL){
 		is_alive("wait_til_done");
@@ -2385,13 +2393,10 @@
 		if (((unsigned long)buffer) % 512)
 			DPRINT("%p buffer not aligned\n", buffer);
 #endif
-		if (CT(COMMAND) == FD_READ) {
-			fd_cacheflush(dma_buffer, size);
+		if (CT(COMMAND) == FD_READ)
 			memcpy(buffer, dma_buffer, size);
-		} else {
+		else
 			memcpy(dma_buffer, buffer, size);
-			fd_cacheflush(dma_buffer, size);
-		}
 		remaining -= size;
 		if (!remaining)
 			break;
@@ -2708,6 +2713,7 @@
 		raw_cmd = & default_raw_cmd;
 		raw_cmd->flags = 0;
 		if (start_motor(redo_fd_request)) return;
+		disk_change(current_drive);
 		if (test_bit(current_drive, &fake_change) ||
 		   TESTF(FD_DISK_CHANGED)){
 			DPRINT("disk absent or changed during operation\n");
@@ -2736,7 +2742,8 @@
 		if (TESTF(FD_NEED_TWADDLE))
 			twaddle();
 		floppy_tq.routine = (void *)(void *) floppy_start;
-		queue_task(&floppy_tq, &tq_timer);
+		queue_task(&floppy_tq, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
 #ifdef DEBUGT
 		debugt("queue fd request");
 #endif
@@ -2757,11 +2764,13 @@
 static void process_fd_request(void)
 {
 	cont = &rw_cont;
-	queue_task(&request_tq, &tq_timer);
+	queue_task(&request_tq, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
 }
 
 static void do_fd_request(void)
 {
+	sti();
 	if (fdc_busy){
 		/* fdc busy, this new request will be treated when the
 		   current one is done */
@@ -2839,9 +2848,6 @@
 	int ret;
 
 	ECALL(verify_area(VERIFY_WRITE,param,size));
-	fd_cacheflush(address, size); /* is this necessary ??? */
-	/* Ralf: Yes; only the l2 cache is completely chipset
-	   controlled */
 	memcpy_tofs(param,(void *) address, size);
 	return 0;
 }
@@ -2883,7 +2889,7 @@
 	int i;
 
 	if (!flag) {
-		raw_cmd->flags = FD_RAW_FAILURE;
+		raw_cmd->flags |= FD_RAW_FAILURE;
 		raw_cmd->flags |= FD_RAW_HARDFAILURE;
 	} else {
 		raw_cmd->reply_count = inr;
diff -u --recursive --new-file v2.0.7/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.0.7/linux/drivers/block/ide.c	Wed Jul  3 22:05:07 1996
+++ linux/drivers/block/ide.c	Tue Jul 16 12:02:42 1996
@@ -1685,7 +1685,7 @@
 					return drive;
 			} else if (major == IDE0_MAJOR && unit < 4) {
 				printk("ide: probable bad entry for /dev/hd%c\n", 'a'+unit);
-				printk("ide: to fix it, run:  /usr/src/linux/drivers/block/MAKEDEV.ide\n");
+				printk("ide: to fix it, run:  /usr/src/linux/scripts/MAKEDEV.ide\n");
 			}
 			break;
 		}
diff -u --recursive --new-file v2.0.7/linux/drivers/char/psaux.c linux/drivers/char/psaux.c
--- v2.0.7/linux/drivers/char/psaux.c	Tue May  7 16:22:25 1996
+++ linux/drivers/char/psaux.c	Wed Jul 17 14:57:51 1996
@@ -25,6 +25,10 @@
  * Rearranged SIGIO support to use code from tty_io.  9Sept95 ctm@ardi.com
  *
  * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
+ *
+ * Fixed keyboard lockups at open time (intervening kbd interrupts), handle
+ * RESEND replies, better error checking
+ * 3-Jul-96 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
  */
 
 /* Uncomment the following line if your mouse needs initialization. */
@@ -57,8 +61,10 @@
 #define AUX_STATUS	0x64		/* Aux device status reg */
 
 /* aux controller status bits */
+#define AUX_KOBUF_FULL	0x01		/* output buffer (from controller) full */
 #define AUX_OBUF_FULL	0x21		/* output buffer (from device) full */
 #define AUX_IBUF_FULL	0x02		/* input buffer (to device) full */
+#define AUX_TIMEOUT	0x40		/* controller reports timeout */
 
 /* aux controller commands */
 #define AUX_CMD_WRITE	0x60		/* value to write to controller */
@@ -81,6 +87,14 @@
 #define AUX_DISABLE_DEV	0xf5		/* disable aux device */
 #define AUX_RESET	0xff		/* reset aux device */
 
+/* kbd controller commands */
+#define KBD_DISABLE	0xad
+#define KBD_ENABLE	0xae
+
+/* replies */
+#define AUX_ACK		0xfa
+#define AUX_RESEND	0xfe
+
 #define MAX_RETRIES	60		/* some aux operations take long time*/
 #if defined(__alpha__) && !defined(CONFIG_PCI)
 # define AUX_IRQ	9		/* Jensen is odd indeed */
@@ -121,7 +135,6 @@
 static int aux_count = 0;
 static int aux_present = 0;
 static int poll_aux_status(void);
-static int poll_aux_status_nosleep(void);
 static int fasync_aux(struct inode *inode, struct file *filp, int on);
 
 #ifdef CONFIG_82C710_MOUSE
@@ -136,49 +149,70 @@
 
 
 /*
- * Write to aux device
+ * Write a byte to the kbd controller and wait for it being processed
  */
 
-static void aux_write_dev(int val)
+static int aux_write_byte(int val,int port)
 {
-	poll_aux_status();
-	outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);	/* write magic cookie */
-	poll_aux_status();
-	outb_p(val,AUX_OUTPUT_PORT);		/* write data */
+	outb_p(val, port);
+	return poll_aux_status();
 }
 
 /*
- * Write to device & handle returned ack
+ * Write to device, handle returned resend requests and wait for ack
  */
-#if defined INITIALIZE_DEVICE
 static int aux_write_ack(int val)
 {
-	int retries = 0;
+	int rv, retries = 0, stat;
 
-	poll_aux_status_nosleep();
-	outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
-	poll_aux_status_nosleep();
-	outb_p(val,AUX_OUTPUT_PORT);
-	poll_aux_status_nosleep();
-
-	if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
-	{
-		return (inb(AUX_INPUT_PORT));
+  repeat:
+	if (poll_aux_status() < 0)
+		return -1;
+	outb_p(AUX_MAGIC_WRITE, AUX_COMMAND);
+	if (poll_aux_status() < 0)
+		return -1;
+	outb_p(val, AUX_OUTPUT_PORT);
+
+	if ((rv = poll_aux_status()) < 0)
+		/* timeout */
+		return -1;
+	else if (rv == AUX_RESEND)
+	    /* controller needs last byte again... */
+		goto repeat;
+	else if (rv == AUX_ACK)
+	    /* already got ACK */
+		return 0;
+	else {
+		/* wait for ACK from controller */
+		while (retries < MAX_RETRIES) {
+			stat = inb_p(AUX_STATUS);
+			if ((stat & AUX_OBUF_FULL) == AUX_OBUF_FULL &&
+				inb_p(AUX_INPUT_PORT) == AUX_ACK)
+				return 0;
+			current->state = TASK_INTERRUPTIBLE;
+			current->timeout = jiffies + (5*HZ + 99) / 100;
+			schedule();
+			retries++;
+		}
+		return -1;
 	}
-	return 0;
 }
-#endif /* INITIALIZE_DEVICE */
 
 /*
  * Write aux device command
  */
 
-static void aux_write_cmd(int val)
+static int aux_write_cmd(int val)
 {
-	poll_aux_status();
-	outb_p(AUX_CMD_WRITE,AUX_COMMAND);
-	poll_aux_status();
-	outb_p(val,AUX_OUTPUT_PORT);
+	if (poll_aux_status() < 0)
+		return -1;
+	outb_p(AUX_CMD_WRITE, AUX_COMMAND);
+	if (poll_aux_status() < 0)
+		return -1;
+	outb_p(val, AUX_OUTPUT_PORT);
+	if (poll_aux_status() < 0)
+		return -1;
+	return 0;
 }
 
 
@@ -258,10 +292,19 @@
 	fasync_aux(inode, file, 0);
 	if (--aux_count)
 		return;
-	aux_write_cmd(AUX_INTS_OFF);		/* disable controller ints */
-	poll_aux_status();
-	outb_p(AUX_DISABLE,AUX_COMMAND);      	/* Disable Aux device */
+	/* disable keyboard to avoid clashes with multi-byte command sequences */
 	poll_aux_status();
+	if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
+		printk(KERN_ERR "psaux: controller timeout\n");
+	/* disable controller ints */
+	if (aux_write_cmd(AUX_INTS_OFF) < 0)
+		printk(KERN_ERR "psaux: controller timeout\n");
+	/* Disable Aux device */
+	if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0)
+		printk(KERN_ERR "psaux: controller timeout\n");
+	/* re-enable keyboard */
+	if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
+		printk(KERN_ERR "psaux: controller timeout\n");
 	free_irq(AUX_IRQ, NULL);
 	MOD_DEC_USE_COUNT;
 }
@@ -306,7 +349,7 @@
 		return -ENODEV;
 	if (aux_count++)
 		return 0;
-	if (!poll_aux_status()) {
+	if (poll_aux_status() < 0) {
 		aux_count--;
 		return -EBUSY;
 	}
@@ -317,12 +360,27 @@
 	}
 	MOD_INC_USE_COUNT;
 	poll_aux_status();
-	outb_p(AUX_ENABLE,AUX_COMMAND);		/* Enable Aux */
-	aux_write_dev(AUX_ENABLE_DEV);		/* enable aux device */
-	aux_write_cmd(AUX_INTS_ON);		/* enable controller ints */
-	poll_aux_status();
+	/* disable keyboard to avoid clashes with multi-byte command sequences */
+	if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
+		goto open_error;
+	/* Enable Aux in kbd controller */
+	if (aux_write_byte(AUX_ENABLE, AUX_COMMAND) < 0)
+		goto open_error;
+	/* enable aux device */
+	if (aux_write_ack(AUX_ENABLE_DEV) < 0)
+		goto open_error;
+	/* enable controller ints */
+	if (aux_write_cmd(AUX_INTS_ON) < 0)
+		goto open_error;
+	/* re-enable keyboard */
+	if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
+		goto open_error;
+
 	aux_ready = 0;
 	return 0;
+  open_error:
+	printk( KERN_ERR "psaux: controller timeout\n" );
+	return -EIO;
 }
 
 #ifdef CONFIG_82C710_MOUSE
@@ -378,17 +436,31 @@
 static int write_aux(struct inode * inode, struct file * file, const char * buffer, int count)
 {
 	int i = count;
+	int rv = 0;
+	
+	/* temporary disable keyboard to avoid clashes with multi-byte command
+	 * sequence */
+	if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
+		return -EIO;
 
 	while (i--) {
-		if (!poll_aux_status())
-			return -EIO;
+		if (poll_aux_status() < 0) {
+			rv = -EIO;
+			break;
+		}
 		outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
-		if (!poll_aux_status())
-			return -EIO;
+		if (poll_aux_status() < 0) {
+			rv = -EIO;
+			break;
+		}
 		outb_p(get_user(buffer++),AUX_OUTPUT_PORT);
 	}
+	/* reenable keyboard */
+	if (poll_aux_status() < 0 || aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
+		rv = -EIO;
+
 	inode->i_mtime = CURRENT_TIME;
-	return count;
+	return rv ? rv : count;
 }
 
 
@@ -519,13 +591,11 @@
 		aux_write_ack(AUX_SET_RES);
 		aux_write_ack(3);			/* 8 counts per mm */
 		aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
-		poll_aux_status_nosleep();
 #endif /* INITIALIZE_DEVICE */
-		outb_p(AUX_DISABLE,AUX_COMMAND);   /* Disable Aux device */
-		poll_aux_status_nosleep();
-		outb_p(AUX_CMD_WRITE,AUX_COMMAND);
-		poll_aux_status_nosleep();             /* Disable interrupts */
-		outb_p(AUX_INTS_OFF, AUX_OUTPUT_PORT); /*  on the controller */
+		/* Disable Aux device and its interrupts on the controller */
+		if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0 ||
+		    aux_write_cmd(AUX_INTS_OFF) < 0)
+		    printk(KERN_ERR "psaux: controller timeout\n");
 	}
 	return 0;
 }
@@ -533,7 +603,7 @@
 #ifdef MODULE
 int init_module(void)
 {
-	return psaux_init(); /*?? Bjorn */
+	return psaux_init();
 }
 
 void cleanup_module(void)
@@ -545,28 +615,18 @@
 static int poll_aux_status(void)
 {
 	int retries=0;
+	int reply=0;
 
-	while ((inb(AUX_STATUS)&0x03) && retries < MAX_RETRIES) {
+	while ((inb(AUX_STATUS) & (AUX_KOBUF_FULL|AUX_IBUF_FULL)) &&
+	       retries < MAX_RETRIES) {
  		if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
-			inb_p(AUX_INPUT_PORT);
+			reply = inb_p(AUX_INPUT_PORT);
 		current->state = TASK_INTERRUPTIBLE;
 		current->timeout = jiffies + (5*HZ + 99) / 100;
 		schedule();
 		retries++;
 	}
-	return !(retries==MAX_RETRIES);
-}
-
-static int poll_aux_status_nosleep(void)
-{
-	int retries = 0;
-
-	while ((inb(AUX_STATUS)&0x03) && retries < 1000000) {
- 		if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
-			inb_p(AUX_INPUT_PORT);
-		retries++;
-	}
-	return !(retries == 1000000);
+	return (retries==MAX_RETRIES) ? -1 : reply;
 }
 
 #ifdef CONFIG_82C710_MOUSE
diff -u --recursive --new-file v2.0.7/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- v2.0.7/linux/drivers/isdn/isdn_net.c	Wed Jul  3 22:05:09 1996
+++ linux/drivers/isdn/isdn_net.c	Wed Jul 17 11:55:48 1996
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.17 1996/06/25 18:37:37 fritz Exp $
+/* $Id: isdn_net.c,v 1.18 1996/07/03 13:48:51 hipp Exp $
  *
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -21,6 +21,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_net.c,v $
+ * Revision 1.18  1996/07/03 13:48:51  hipp
+ * bugfix: Call dev_purge_queues() only for master device
+ *
  * Revision 1.17  1996/06/25 18:37:37  fritz
  * Fixed return count for empty return string in isdn_net_getphones().
  *
@@ -121,7 +124,7 @@
  
 extern void dev_purge_queues(struct device *dev);	/* move this to net/core/dev.c */
 
-char *isdn_net_revision = "$Revision: 1.17 $";
+char *isdn_net_revision = "$Revision: 1.18 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -202,7 +205,8 @@
                 dev_kfree_skb(lp->sav_skb,FREE_WRITE);
 		lp->sav_skb = NULL;
 	}
-	dev_purge_queues(&lp->netdev->dev);
+	if(!lp->master) /* purge only for master device */
+		dev_purge_queues(&lp->netdev->dev);
 	lp->dialstate = 0;
 	dev->rx_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
 	dev->st_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
diff -u --recursive --new-file v2.0.7/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- v2.0.7/linux/drivers/isdn/isdn_ppp.c	Wed Jul  3 22:05:09 1996
+++ linux/drivers/isdn/isdn_ppp.c	Wed Jul 17 11:55:48 1996
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.12 1996/06/24 17:42:03 fritz Exp $
+/* $Id: isdn_ppp.c,v 1.13 1996/07/01 19:47:24 hipp Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
@@ -19,6 +19,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_ppp.c,v $
+ * Revision 1.13  1996/07/01 19:47:24  hipp
+ * Fixed memory leak in VJ handling and more VJ changes
+ *
  * Revision 1.12  1996/06/24 17:42:03  fritz
  * Minor bugfixes.
  *
@@ -93,7 +96,7 @@
 		int BEbyte, int *sqno, int min_sqno);
 #endif
 
-char *isdn_ppp_revision              = "$Revision: 1.12 $";
+char *isdn_ppp_revision              = "$Revision: 1.13 $";
 struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
 extern int isdn_net_force_dial_lp(isdn_net_local *);
@@ -137,6 +140,7 @@
 	ippp_table[lp->ppp_minor]->lp = NULL;	/* link is down .. set lp to NULL */
 	lp->ppp_minor = -1;			/* is this OK ?? */
 	restore_flags(flags);
+
 	return 0;
 }
 
@@ -254,12 +258,6 @@
         /*
          * VJ header compression init
          */
-	ippp_table[minor]->cbuf = kmalloc(ippp_table[minor]->mru + PPP_HARD_HDR_LEN + 2, GFP_KERNEL);
-
-	if (ippp_table[minor]->cbuf == NULL) {
-		printk(KERN_DEBUG "ippp: Can't allocate memory buffer for VJ compression.\n");
-		return -ENOMEM;
-	}
 	ippp_table[minor]->slcomp = slhc_init(16, 16);	/* not necessary for 2. link in bundle */
 #endif
 
@@ -300,7 +298,6 @@
 #ifdef CONFIG_ISDN_PPP_VJ
 	slhc_free(ippp_table[minor]->slcomp);
 	ippp_table[minor]->slcomp = NULL;
-	kfree(ippp_table[minor]->cbuf);
 #endif
 
 	ippp_table[minor]->state = 0;
@@ -673,7 +670,8 @@
 	if(skb->data[0] == 0xff && skb->data[1] == 0x03)
 		skb_pull(skb,2);
 	else if (ippp_table[lp->ppp_minor]->pppcfg & SC_REJ_COMP_AC) {
-		dev_kfree_skb(skb,FREE_WRITE);
+		skb->free = 1;
+		dev_kfree_skb(skb,0 /* FREE_READ */ );
 		return;		/* discard it silently */
 	}
 
@@ -767,7 +765,8 @@
 				if (!q) {
 					net_dev->ib.modify = 0;
 					printk(KERN_WARNING "ippp/MPPP: Bad! Can't alloc sq node!\n");
-					dev_kfree_skb(skb,FREE_WRITE);
+					skb->free = 1;
+					dev_kfree_skb(skb, 0 /* FREE_READ */ );
 					return;		/* discard */
 				}
 				q->skb = skb;
@@ -840,30 +839,46 @@
 
 	switch (proto) {
 	case PPP_IPX: /* untested */
+		if(ippp_table[lp->ppp_minor]->debug & 0x20)
+			printk(KERN_DEBUG "isdn_ppp: _IPX\n");
 		skb->dev = dev;
 		skb->mac.raw = skb->data;
 		skb->protocol = htons(ETH_P_IPX);
 		break;
 #ifdef CONFIG_ISDN_PPP_VJ
 	case PPP_VJC_UNCOMP:
-		slhc_remember(ippp_table[net_dev->local.ppp_minor]->slcomp, skb->data, skb->len);
+		if(ippp_table[lp->ppp_minor]->debug & 0x20)
+			printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
+		if(slhc_remember(ippp_table[net_dev->local.ppp_minor]->slcomp, skb->data, skb->len) <= 0) {
+			printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
+			net_dev->local.stats.rx_dropped++;
+			skb->free = 1;
+			dev_kfree_skb(skb,0 /* FREE_READ */ );
+			return;
+		}
 #endif
 	case PPP_IP:
+		if(ippp_table[lp->ppp_minor]->debug & 0x20)
+			printk(KERN_DEBUG "isdn_ppp: IP\n");
 		skb->dev = dev;
 		skb->mac.raw = skb->data;
 		skb->protocol = htons(ETH_P_IP);
 		break;
 	case PPP_VJC_COMP:
+                if(ippp_table[lp->ppp_minor]->debug & 0x20)
+                        printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
 #ifdef CONFIG_ISDN_PPP_VJ
 		{
 			struct sk_buff *skb_old = skb;
 			int pkt_len;
 			skb = dev_alloc_skb(skb_old->len + 40);
 
+			skb_old->free = 1;
+
 			if (!skb) {
 				printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
 				net_dev->local.stats.rx_dropped++;
-				dev_kfree_skb(skb_old,FREE_WRITE);
+				dev_kfree_skb(skb_old,0 /* FREE_READ */ );
 				return;
 			}
 			skb->dev = dev;
@@ -872,9 +887,10 @@
 			skb->mac.raw = skb->data;
 			pkt_len = slhc_uncompress(ippp_table[net_dev->local.ppp_minor]->slcomp,
 						  skb->data, skb_old->len);
-			dev_kfree_skb(skb_old,FREE_WRITE);
+			dev_kfree_skb(skb_old,0 /* FREE_READ */ );
 			if(pkt_len < 0) {
-				dev_kfree_skb(skb,FREE_WRITE);
+				skb->free = 1;
+				dev_kfree_skb(skb, 0 /* FREE_READ */ );
 				lp->stats.rx_dropped++;
 				return;
 			}
@@ -884,13 +900,15 @@
 #else
 		printk(KERN_INFO "isdn: Ooopsa .. VJ-Compression support not compiled into isdn driver.\n");
 		lp->stats.rx_dropped++;
-		dev_kfree_skb(skb,FREE_WRITE);
+		skb->free = 1;
+		dev_kfree_skb(skb,0 /* FREE_READ */ );
 		return;
 #endif
 		break;
 	default:
 		isdn_ppp_fill_rq(skb->data, skb->len,proto, lp->ppp_minor);	/* push data to pppd device */
-		dev_kfree_skb(skb,FREE_WRITE);
+		skb->free = 1;
+		dev_kfree_skb(skb,0 /* FREE_READ */ );
 		return;
 	}
 
@@ -905,6 +923,9 @@
 /*
  * send ppp frame .. we expect a PIDCOMPressable proto -- 
  *  (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
+ *
+ * VJ compression may change skb pointer!!! .. requeue with old
+ * skb isn't allowed!! 
  */
 
 int isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
@@ -957,8 +978,7 @@
 
 #ifdef CONFIG_ISDN_PPP_VJ
 	if (ipts->pppcfg & SC_COMP_TCP) {	/* ipts here? probably yes .. but check again */
-		u_char *buf = skb->data;
-		int pktlen;
+		struct sk_buff *new_skb;
 		int len = 4;
 #ifdef CONFIG_ISDN_MPP
 		if (ipt->mpppcfg & SC_MP_PROT) /* sigh */ 	/* ipt or ipts ?? */
@@ -967,20 +987,41 @@
 			else
 				len += 5;
 #endif
-		buf += len;
-		pktlen = slhc_compress(ipts->slcomp, buf, skb->len-len, ipts->cbuf,
-				&buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
-		skb_trim(skb,pktlen+len);
-		if(buf != skb->data+len) { /* copied to new buffer ??? (btw: WHY must slhc copy it?? *sigh*)  */
-			memcpy(skb->data+len,buf,pktlen);
-		}
-		if (skb->data[len] & SL_TYPE_COMPRESSED_TCP) {	/* cslip? style -> PPP */
-			proto = PPP_VJC_COMP;
-			skb->data[len] ^= SL_TYPE_COMPRESSED_TCP;
-		} else {
-			if (skb->data[len] >= SL_TYPE_UNCOMPRESSED_TCP)
-				proto = PPP_VJC_UNCOMP;
-			skb->data[len] = (skb->data[len] & 0x0f) | 0x40;
+		new_skb = dev_alloc_skb(skb->len);
+		if(new_skb) {
+			u_char *buf;
+			int pktlen;
+
+			new_skb->dev = skb->dev;
+			new_skb->free = 1;
+			skb_put(new_skb,skb->len);
+			skb_pull(skb,len);	/* pull PPP header */
+			skb_pull(new_skb,len);	/* pull PPP header */
+			buf = skb->data;
+
+			pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
+					&buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
+
+			if(buf != skb->data) { /* copied to new buffer ??? (btw: WHY must slhc copy it?? *sigh*)  */
+				if(new_skb->data != buf)
+					printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
+				dev_kfree_skb(skb,FREE_WRITE);
+				skb = new_skb;
+			}
+			else {
+				dev_kfree_skb(new_skb,0 /* FREE_WRITE */ );
+			}
+
+			skb_trim(skb,pktlen);
+			if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) {	/* cslip? style -> PPP */
+				proto = PPP_VJC_COMP;
+				skb->data[0] ^= SL_TYPE_COMPRESSED_TCP;
+			} else {
+				if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP)
+					proto = PPP_VJC_UNCOMP;
+				skb->data[0] = (skb->data[0] & 0x0f) | 0x40;
+			}
+			skb_push(skb,len);
 		}
 	}
 #endif
@@ -1019,7 +1060,7 @@
         /* tx-stats are now updated via BSENT-callback */
 	if(isdn_net_send_skb(dev , lp , skb)) {	
 		if(lp->sav_skb) {	/* whole sav_skb processing with disabled IRQs ?? */
-			printk(KERN_ERR "%s: whoops .. there is another stored skb!\n!",dev->name);
+			printk(KERN_ERR "%s: whoops .. there is another stored skb!\n",dev->name);
 			dev_kfree_skb(skb,FREE_WRITE);
 		}
 		else
@@ -1035,8 +1076,10 @@
 	p->ib.sq = NULL;
 	while(q) {
 		struct sqqueue *qn = q->next;
-		if(q->skb)
-			dev_kfree_skb(q->skb,FREE_WRITE);
+		if(q->skb) {
+			q->skb->free = 1;
+			dev_kfree_skb(q->skb,0 /* FREE_READ */ );
+		}
 		kfree(q);
 		q = qn;
 	}
@@ -1048,7 +1091,8 @@
 	struct mpqueue *ql, *q = p->mp_last;
 	while (q) {
 		ql = q->next;
- 		dev_kfree_skb(q->skb,FREE_WRITE);
+		q->skb->free = 1;
+ 		dev_kfree_skb(q->skb,0 /* FREE_READ */ );
 		kfree(q);
 		q = ql;
 	}
@@ -1217,7 +1261,8 @@
 	if (!(*skb)) {
 		while (q) {
 			struct mpqueue *ql = q->next;
-			dev_kfree_skb(q->skb,FREE_WRITE);
+			q->skb->free = 1;
+			dev_kfree_skb(q->skb,0 /* FREE_READ */ );
 			kfree(q);
 			q = ql;
 		}
@@ -1229,7 +1274,8 @@
 		struct mpqueue *ql = q->next;
 		memcpy((*skb)->data + cnt, q->skb->data, q->skb->len);
 		cnt += q->skb->len;
-		dev_kfree_skb(q->skb,FREE_WRITE);
+		q->skb->free = 1;
+		dev_kfree_skb(q->skb,0 /* FREE_READ */ );
 		kfree(q);
 		q = ql;
 	}
@@ -1262,7 +1308,8 @@
 					q->next->last = NULL;
 				while (q) {
 					ql = q->last;
-					dev_kfree_skb(q->skb,FREE_WRITE);
+					q->skb->free = 1;
+					dev_kfree_skb(q->skb,0 /* FREE_READ */ );
 					kfree(q);
 #ifdef CONFIG_ISDN_PPP_VJ
 					toss = 1;
@@ -1380,7 +1427,7 @@
 	int len;
 	isdn_net_local *lp = (isdn_net_local *) dev->priv;
 
-#if 1
+#if 0
 	printk(KERN_DEBUG "ippp, dev_ioctl: cmd %#08x , %d \n",cmd,lp->ppp_minor);
 #endif
 
diff -u --recursive --new-file v2.0.7/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.0.7/linux/drivers/net/3c59x.c	Mon Jul  8 16:09:54 1996
+++ linux/drivers/net/3c59x.c	Thu Jul 18 10:08:45 1996
@@ -750,9 +750,13 @@
 	   we actually have room for this packet.
 	   */
 
+#if 0
+	/* unstable optimization */
 	if (inw(ioaddr + TxFree) > skb->len) /* We actually have free room. */
 	  dev->tbusy = 0;			/* Fake out the check below. */
-	else if (dev->tbusy) {
+	else
+#endif
+	if (dev->tbusy) {
 		/* Transmitter timeout, serious problems. */
 		int tickssofar = jiffies - dev->trans_start;
 		int i;
diff -u --recursive --new-file v2.0.7/linux/drivers/net/bsd_comp.c linux/drivers/net/bsd_comp.c
--- v2.0.7/linux/drivers/net/bsd_comp.c	Fri Apr 12 15:51:55 1996
+++ linux/drivers/net/bsd_comp.c	Wed Jul 17 07:17:29 1996
@@ -58,7 +58,6 @@
 
 #include <linux/module.h>
 
-#include <endian.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -77,6 +76,7 @@
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/segment.h>
+#include <asm/byteorder.h>
 
 #include <linux/if.h>
 
@@ -141,11 +141,11 @@
     union {				/* hash value */
 	unsigned long	fcode;
 	struct {
-#ifndef BIG_ENDIAN_BITFIELD /* Little endian order */
+#if defined(__LITTLE_ENDIAN) /* Little endian order */
 	    unsigned short	prefix;	/* preceding code */
 	    unsigned char	suffix; /* last character of new code */
 	    unsigned char	pad;
-#else /* Big endian order */
+#elif defined(__BIG_ENDIAN) /* Big endian order */
 	    unsigned char	pad;
 	    unsigned char	suffix; /* last character of new code */
 	    unsigned short	prefix; /* preceding code */
diff -u --recursive --new-file v2.0.7/linux/drivers/net/new_tunnel.c linux/drivers/net/new_tunnel.c
--- v2.0.7/linux/drivers/net/new_tunnel.c	Mon Jun  3 16:46:55 1996
+++ linux/drivers/net/new_tunnel.c	Fri Jul 19 08:24:05 1996
@@ -233,8 +233,9 @@
 printk("Room left at tail: %d\n", skb_tailroom(skb));
 printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
 #endif
-	if (skb_headroom(skb) >= max_headroom) {
+	if (skb_headroom(skb) >= max_headroom && skb->free) {
 		skb->h.iph = (struct iphdr *) skb_push(skb, tunnel_hlen);
+		skb_device_unlock(skb);
 	} else {
 		struct sk_buff *new_skb;
 
@@ -289,7 +290,7 @@
 	iph->tot_len		=	htons(skb->len);
 	iph->id			=	htons(ip_id_count++);	/* Race condition here? */
 	ip_send_check(iph);
-	skb->ip_hdr 		= skb->h.iph;
+	skb->ip_hdr 		=	skb->h.iph;
 	skb->protocol		=	htons(ETH_P_IP);
 #ifdef TUNNEL_DEBUG
 	printk("New IP Header....\n");
@@ -303,7 +304,7 @@
 	 */
 
 #ifdef CONFIG_IP_FORWARD
-	if (ip_forward(skb, dev, 0, target))
+	if (ip_forward(skb, dev, IPFWD_NOTTLDEC, target))
 #endif
 		kfree_skb(skb, FREE_WRITE);
 
diff -u --recursive --new-file v2.0.7/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v2.0.7/linux/drivers/net/ppp.c	Fri May 31 08:02:19 1996
+++ linux/drivers/net/ppp.c	Wed Jul 17 07:17:30 1996
@@ -60,7 +60,6 @@
  */
 
 #include <linux/module.h>
-#include <endian.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
diff -u --recursive --new-file v2.0.7/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v2.0.7/linux/drivers/scsi/53c7,8xx.c	Wed Jun  5 10:41:28 1996
+++ linux/drivers/scsi/53c7,8xx.c	Tue Jul 16 12:02:42 1996
@@ -3546,6 +3546,7 @@
     case MODE_SELECT: 
     case WRITE_6:
     case WRITE_10:
+    case START_STOP: /* also SCAN, which may do DATA OUT */
 #if 0
 	printk("scsi%d : command is ", host->host_no);
 	print_command(cmd->cmnd);
@@ -3564,7 +3565,6 @@
      * These commands do no data transfer, we should force an
      * interrupt if a data phase is attempted on them.
      */
-    case START_STOP:
     case TEST_UNIT_READY:
     	datain = dataout = 0;
 	break;
diff -u --recursive --new-file v2.0.7/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- v2.0.7/linux/drivers/scsi/BusLogic.c	Mon Jul  8 16:09:54 1996
+++ linux/drivers/scsi/BusLogic.c	Wed Jul 17 21:22:13 1996
@@ -24,8 +24,8 @@
 */
 
 
-#define BusLogic_DriverVersion		"2.0.5"
-#define BusLogic_DriverDate		"7 July 1996"
+#define BusLogic_DriverVersion		"2.0.6"
+#define BusLogic_DriverDate		"17 July 1996"
 
 
 #include <linux/module.h>
@@ -162,7 +162,7 @@
 
 
 /*
-  BusLogic_DriverInfo returns the Board Name to identify this SCSI Driver
+  BusLogic_DriverInfo returns the Controller Name to identify this SCSI Driver
   and Host Adapter.
 */
 
@@ -170,7 +170,7 @@
 {
   BusLogic_HostAdapter_T *HostAdapter =
     (BusLogic_HostAdapter_T *) Host->hostdata;
-  return HostAdapter->BoardName;
+  return HostAdapter->ControllerName;
 }
 
 
@@ -387,12 +387,12 @@
   the Host Adapter (including any discarded data); on failure, it returns
   -1 if the command was invalid, or -2 if a timeout occurred.
 
-  This function is only called during board detection and initialization, so
-  performance and latency are not critical, and exclusive access to the Host
-  Adapter hardware is assumed.  Once the board and driver are initialized, the
-  only Host Adapter command that is issued is the single byte Execute Mailbox
-  Command operation code , which does not require waiting for the Host Adapter
-  Ready bit to be set in the Status Register.
+  This function is only called during controller detection and initialization,
+  so performance and latency are not critical, and exclusive access to the Host
+  Adapter hardware is assumed.  Once the controller and driver are initialized,
+  the only Host Adapter command that is issued is the single byte Execute
+  Mailbox Command operation code, which does not require waiting for the Host
+  Adapter Ready bit to be set in the Status Register.
 */
 
 static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
@@ -478,7 +478,7 @@
     {
     case BusLogic_InquireInstalledDevicesID0to7:
     case BusLogic_InquireInstalledDevicesID8to15:
-    case BusLogic_InquireDevices:
+    case BusLogic_InquireTargetDevices:
       /* Approximately 60 seconds. */
       TimeoutCounter = loops_per_sec << 2;
       break;
@@ -737,10 +737,10 @@
     rejected later when the Inquire Extended Setup Information command is
     issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
     BusLogic clone that implements the same interface as earlier BusLogic
-    boards, including the undocumented commands, and is therefore supported by
-    this driver.  However, the AMI FastDisk always returns 0x00 upon reading
-    the Geometry Register, so the extended translation option should always be
-    left disabled on the AMI FastDisk.
+    controllers, including the undocumented commands, and is therefore
+    supported by this driver.  However, the AMI FastDisk always returns 0x00
+    upon reading the Geometry Register, so the extended translation option
+    should always be left disabled on the AMI FastDisk.
   */
   GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
   if (TraceProbe)
@@ -889,7 +889,7 @@
   BusLogic_Configuration_T Configuration;
   BusLogic_SetupInformation_T SetupInformation;
   BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
-  BusLogic_BoardModelNumber_T BoardModelNumber;
+  BusLogic_ControllerModelNumber_T ControllerModelNumber;
   BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
   BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
   BusLogic_GenericIOPortInformation_T GenericIOPortInformation;
@@ -934,24 +934,25 @@
       != sizeof(ExtendedSetupInformation))
     return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
   /*
-    Issue the Inquire Board Model Number command.
+    Issue the Inquire Controller Model Number command.
   */
   if (ExtendedSetupInformation.BusType == 'A' &&
       BoardID.FirmwareVersion1stDigit == '2')
     /* BusLogic BT-542B ISA 2.xx */
-    strcpy(BoardModelNumber, "542B");
+    strcpy(ControllerModelNumber, "542B");
   else if (ExtendedSetupInformation.BusType == 'E' &&
 	   BoardID.FirmwareVersion1stDigit == '0')
     /* AMI FastDisk EISA Series 441 0.x */
-    strcpy(BoardModelNumber, "747A");
+    strcpy(ControllerModelNumber, "747A");
   else
     {
-      RequestedReplyLength = sizeof(BoardModelNumber);
-      if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber,
+      RequestedReplyLength = sizeof(ControllerModelNumber);
+      if (BusLogic_Command(HostAdapter, BusLogic_InquireControllerModelNumber,
 			   &RequestedReplyLength, sizeof(RequestedReplyLength),
-			   &BoardModelNumber, sizeof(BoardModelNumber))
-	  != sizeof(BoardModelNumber))
-	return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER");
+			   &ControllerModelNumber,
+			   sizeof(ControllerModelNumber))
+	  != sizeof(ControllerModelNumber))
+	return BusLogic_Failure(HostAdapter, "INQUIRE CONTROLLER MODEL NUMBER");
     }
   /*
     Issue the Inquire Firmware Version 3rd Digit command.
@@ -979,22 +980,22 @@
     0.xx	AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
   */
   /*
-    Save the Model Name and Board Name in the Host Adapter structure.
+    Save the Model Name and Controller Name in the Host Adapter structure.
   */
   TargetPointer = HostAdapter->ModelName;
   *TargetPointer++ = 'B';
   *TargetPointer++ = 'T';
   *TargetPointer++ = '-';
-  for (i = 0; i < sizeof(BoardModelNumber); i++)
+  for (i = 0; i < sizeof(ControllerModelNumber); i++)
     {
-      Character = BoardModelNumber[i];
+      Character = ControllerModelNumber[i];
       if (Character == ' ' || Character == '\0') break;
       *TargetPointer++ = Character;
     }
   *TargetPointer++ = '\0';
-  strcpy(HostAdapter->BoardName, "BusLogic ");
-  strcat(HostAdapter->BoardName, HostAdapter->ModelName);
-  strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
+  strcpy(HostAdapter->ControllerName, "BusLogic ");
+  strcat(HostAdapter->ControllerName, HostAdapter->ModelName);
+  strcpy(HostAdapter->InterruptLabel, HostAdapter->ControllerName);
   /*
     Save the Firmware Version in the Host Adapter structure.
   */
@@ -1141,8 +1142,8 @@
   /*
     Save the Disconnect/Reconnect Permitted flag bits in the Host Adapter
     structure.  The Disconnect Permitted information is only valid on "W" and
-    "C" Series boards, but Disconnect/Reconnect is always permitted on "S" and
-    "A" Series boards.
+    "C" Series controllers, but Disconnect/Reconnect is always permitted on "S"
+    and "A" Series controllers.
   */
   if (HostAdapter->FirmwareVersion[0] >= '4')
     HostAdapter->DisconnectPermitted =
@@ -1169,6 +1170,13 @@
     ExtendedSetupInformation.HostAutomaticConfiguration;
   HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
   /*
+    Determine whether 64 LUN Format CCBs are supported and save the information
+    in the Host Adapter structure.
+  */
+  if (HostAdapter->FirmwareVersion[0] == '5' ||
+      (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
+    HostAdapter->Host64LUNSupport = true;
+  /*
     Determine the Host Adapter BIOS Address if the BIOS is enabled and
     save it in the Host Adapter structure.  The BIOS is disabled if the
     BIOS_Address is 0.
@@ -1180,12 +1188,12 @@
   if (HostAdapter->BusType == BusLogic_ISA_Bus && high_memory > MAX_DMA_ADDRESS)
     HostAdapter->BounceBuffersRequired = true;
   /*
-    BusLogic BT-445S Host Adapters prior to board revision E have a hardware
-    bug whereby when the BIOS is enabled, transfers to/from the same address
-    range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
-    functioning BT-445S boards have firmware version 3.37, so we require that
-    ISA Bounce Buffers be used for the buggy BT-445S models if there is more
-    than 16MB memory.
+    BusLogic BT-445S Host Adapters prior to controller revision E have a
+    hardware bug whereby when the BIOS is enabled, transfers to/from the same
+    address range the BIOS occupies modulo 16MB are handled incorrectly.  Only
+    properly functioning BT-445S controllers have firmware version 3.37, so we
+    require that ISA Bounce Buffers be used for the buggy BT-445S models if
+    there is more than 16MB memory.
   */
   if (HostAdapter->BIOS_Address > 0 &&
       strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
@@ -1196,16 +1204,8 @@
     Determine the maximum number of Target IDs and Logical Units supported by
     this driver for Wide and Narrow Host Adapters.
   */
-  if (HostAdapter->HostWideSCSI)
-    {
-      HostAdapter->MaxTargetDevices = 16;
-      HostAdapter->MaxLogicalUnits = 64;
-    }
-  else
-    {
-      HostAdapter->MaxTargetDevices = 8;
-      HostAdapter->MaxLogicalUnits = 8;
-    }
+  HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
+  HostAdapter->MaxLogicalUnits = (HostAdapter->Host64LUNSupport ? 64 : 8);
   /*
     Select appropriate values for the Mailbox Count, Initial CCBs, and
     Incremental CCBs variables based on whether or not Strict Round Robin Mode
@@ -1231,14 +1231,14 @@
   */
   if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
     {
-      HostAdapter->StrictRoundRobinModeSupported = true;
+      HostAdapter->StrictRoundRobinModeSupport = true;
       HostAdapter->MailboxCount = 255;
       HostAdapter->InitialCCBs = 64;
       HostAdapter->IncrementalCCBs = 32;
     }
   else
     {
-      HostAdapter->StrictRoundRobinModeSupported = false;
+      HostAdapter->StrictRoundRobinModeSupport = false;
       HostAdapter->MailboxCount = 32;
       HostAdapter->InitialCCBs = 32;
       HostAdapter->IncrementalCCBs = 4;
@@ -1293,10 +1293,10 @@
 	      sizeof(HostAdapter->ErrorRecoveryStrategy));
   /*
     Tagged Queuing support is available and operates properly on all "W" Series
-    boards, on "C" Series boards with firmware version 4.22 and above, and on
-    "S" Series boards with firmware version 3.35 and above.  Tagged Queuing is
-    disabled by default when the Tagged Queue Depth is 1 since queuing multiple
-    commands is not possible.
+    controllers, on "C" Series controllers with firmware version 4.22 and
+    above, and on "S" Series controllers with firmware version 3.35 and above.
+    Tagged Queuing is disabled by default when the Tagged Queue Depth is 1
+    since queuing multiple commands is not possible.
   */
   TaggedQueuingPermittedDefault = 0;
   if (HostAdapter->TaggedQueueDepth != 1)
@@ -1479,7 +1479,8 @@
   */
   if (HostAdapter->DMA_Channel > 0)
     {
-      if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
+      if (request_dma(HostAdapter->DMA_Channel,
+		      HostAdapter->ControllerName) < 0)
 	{
 	  printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
 		 HostAdapter->HostNumber, HostAdapter->DMA_Channel);
@@ -1576,7 +1577,7 @@
 {
   BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
   BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
-  BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
+  BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
   BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
   int TargetID;
   /*
@@ -1623,7 +1624,7 @@
     Outgoing Mailboxes to find any that have new commands in them.  Strict
     Round Robin Mode is significantly more efficient.
   */
-  if (HostAdapter->StrictRoundRobinModeSupported)
+  if (HostAdapter->StrictRoundRobinModeSupport)
     {
       RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
       if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
@@ -1632,16 +1633,16 @@
 	return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
     }
   /*
-    For Wide SCSI Host Adapters, issue the Enable Wide Mode CCB command to
-    allow more than 8 Logical Units per Target Device to be supported.
+    For Host Adapters that support 64 LUN Format CCBs, issue the Set CCB Format
+    command to allow 64 Logical Units per Target Device.
   */
-  if (HostAdapter->HostWideSCSI)
+  if (HostAdapter->Host64LUNSupport)
     {
-      WideModeCCBRequest = BusLogic_WideModeCCB;
-      if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
-			   &WideModeCCBRequest,
-			   sizeof(WideModeCCBRequest), NULL, 0) < 0)
-	return BusLogic_Failure(HostAdapter, "ENABLE WIDE MODE CCB");
+      SetCCBFormatRequest = BusLogic_64LUNFormatCCB;
+      if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
+			   &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
+			   NULL, 0) < 0)
+	return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
     }
   /*
     For PCI Host Adapters being accessed through the PCI compliant I/O
@@ -1667,7 +1668,7 @@
     Announce Successful Initialization.
   */
   printk("scsi%d: *** %s Initialized Successfully ***\n",
-	 HostAdapter->HostNumber, HostAdapter->BoardName);
+	 HostAdapter->HostNumber, HostAdapter->ControllerName);
   /*
     Indicate the Host Adapter Initialization completed successfully.
   */
@@ -1676,12 +1677,12 @@
 
 
 /*
-  BusLogic_InquireTargetDevices inquires about the Target Devices accessible
+  BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
   through Host Adapter and reports on the results.
 */
 
-static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
-					     *HostAdapter)
+static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
+					    *HostAdapter)
 {
   BusLogic_InstalledDevices_T InstalledDevices;
   BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
@@ -1705,20 +1706,20 @@
       return true;
     }
   /*
-    Issue the Inquire Devices command for boards with firmware version 4.25 or
-    later, or the Inquire Installed Devices ID 0 to 7 command for older boards.
-    This is necessary to force Synchronous Transfer Negotiation so that the
-    Inquire Setup Information and Inquire Synchronous Period commands will
-    return valid data.  The Inquire Devices command is preferable to Inquire
-    Installed Devices ID 0 to 7 since it only probes Logical Unit 0 of each
-    Target Device.
+    Issue the Inquire Target Devices command for controllers with firmware
+    version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
+    for older controllers.  This is necessary to force Synchronous Transfer
+    Negotiation so that the Inquire Setup Information and Inquire Synchronous
+    Period commands will return valid data.  The Inquire Target Devices command
+    is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
+    Logical Unit 0 of each Target Device.
   */
   if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
     {
-      if (BusLogic_Command(HostAdapter, BusLogic_InquireDevices, NULL, 0,
+      if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
 			   &InstalledDevices, sizeof(InstalledDevices))
 	  != sizeof(InstalledDevices))
-	return BusLogic_Failure(HostAdapter, "INQUIRE DEVICES");
+	return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
     }
   else
     {
@@ -1987,8 +1988,7 @@
 	Read the Host Adapter Configuration, Acquire the System Resources
 	necessary to use Host Adapter and initialize the fields in the SCSI
 	Host structure, then Test Interrupts, Create the Mailboxes and CCBs,
-	Initialize the Host Adapter, and finally Inquire about the Target
-	Devices.
+	Initialize the Host Adapter, and finally perform Target Device Inquiry.
       */
       if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
 	  BusLogic_AcquireResources(HostAdapter) &&
@@ -1996,7 +1996,7 @@
 	  BusLogic_CreateMailboxes(HostAdapter) &&
 	  BusLogic_CreateCCBs(HostAdapter) &&
 	  BusLogic_InitializeHostAdapter(HostAdapter) &&
-	  BusLogic_InquireTargetDevices(HostAdapter))
+	  BusLogic_TargetDeviceInquiry(HostAdapter))
 	{
 	  /*
 	    Initialization has been completed successfully.  Release and
@@ -2006,7 +2006,7 @@
 	  */
 	  release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
 	  request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
-			 HostAdapter->BoardName);
+			 HostAdapter->ControllerName);
 	  BusLogic_InitializeHostStructure(HostAdapter, Host);
 	  BusLogicHostAdapterCount++;
 	}
@@ -2108,7 +2108,7 @@
       HostStatus = DID_RESET;
       break;
     default:
-      printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
+      printk("BusLogic: Unknown Host Adapter Status 0x%02X\n",
 	     HostAdapterStatus);
       HostStatus = DID_ERROR;
       break;
@@ -2512,14 +2512,14 @@
   CCB->TargetID = TargetID;
   CCB->LogicalUnit = LogicalUnit;
   /*
-    For Wide SCSI Host Adapters, Wide Mode CCBs are used to support more than
-    8 Logical Units per Target, and this requires setting the overloaded
+    For Host Adapters that support it, 64 LUN Format CCBs are used to allow
+    64 Logical Units per Target, and this requires setting the overloaded
     TagEnable field to Logical Unit bit 5.
   */
-  if (HostAdapter->HostWideSCSI)
+  if (HostAdapter->Host64LUNSupport)
     {
       CCB->TagEnable = LogicalUnit >> 5;
-      CCB->WideModeTagEnable = false;
+      CCB->TagEnable64LUN = false;
     }
   else CCB->TagEnable = false;
   /*
@@ -2527,14 +2527,19 @@
     are sent to a Target Device be sent in a non Tagged Queue fashion so that
     the Host Adapter and Target Device can establish Synchronous and Wide
     Transfer before Queue Tag messages can interfere with the Synchronous and
-    Wide Negotiation message.  By waiting to enable Tagged Queuing until after
-    the first 2*BusLogic_PreferredQueueDepth commands have been sent, it is
-    assured that after a Reset any pending commands are resent before Tagged
+    Wide Negotiation messages.  By waiting to enable Tagged Queuing until after
+    the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
+    assured that after a Reset any pending commands are requeued before Tagged
     Queuing is enabled and that the Tagged Queuing message will not occur while
-    the partition table is being printed.
-  */
-  if (HostAdapter->TotalCommandCount[TargetID]++ ==
-        2*BusLogic_PreferredTaggedQueueDepth &&
+    the partition table is being printed.  In addition, some devices do not
+    properly handle the transition from non-tagged to tagged commands, so it is
+    necessary to wait until there are no pending commands for a target device
+    before queuing tagged commands.
+  */
+  if (HostAdapter->TotalCommandCount[TargetID]++ >=
+        BusLogic_MaxTaggedQueueDepth &&
+      !HostAdapter->TaggedQueuingActive[TargetID] &&
+      HostAdapter->ActiveCommandCount[TargetID] == 0 &&
       (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
       Command->device->tagged_supported)
     {
@@ -2552,11 +2557,11 @@
 	write nearer the head position continue to arrive without interruption.
 	Therefore, for each Target Device this driver keeps track of the last
 	time either the queue was empty or an Ordered Queue Tag was issued.  If
-	more than 5 seconds (half the 10 second disk timeout) have elapsed
-	since this last sequence point, this command will be issued with an
-	Ordered Queue Tag rather than a Simple Queue Tag, which forces the
-	Target Device to complete all previously queued commands before this
-	command may be executed.
+	more than 5 seconds (one third of the 15 second disk timeout) have
+	elapsed since this last sequence point, this command will be issued
+	with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
+	the Target Device to complete all previously queued commands before
+	this command may be executed.
       */
       if (HostAdapter->ActiveCommandCount[TargetID] == 0)
 	HostAdapter->LastSequencePoint[TargetID] = jiffies;
@@ -2565,10 +2570,10 @@
 	  HostAdapter->LastSequencePoint[TargetID] = jiffies;
 	  QueueTag = BusLogic_OrderedQueueTag;
 	}
-      if (HostAdapter->HostWideSCSI)
+      if (HostAdapter->Host64LUNSupport)
 	{
-	  CCB->WideModeTagEnable = true;
-	  CCB->WideModeQueueTag = QueueTag;
+	  CCB->TagEnable64LUN = true;
+	  CCB->QueueTag64LUN = QueueTag;
 	}
       else
 	{
@@ -2765,9 +2770,10 @@
     }
   if (Command == NULL)
     printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
-	   HostAdapter->HostNumber, HostAdapter->BoardName);
+	   HostAdapter->HostNumber, HostAdapter->ControllerName);
   else printk("scsi%d: Resetting %s due to Target %d\n",
-	      HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
+	      HostAdapter->HostNumber, HostAdapter->ControllerName,
+	      Command->target);
   /*
     Attempt to Reset and Reinitialize the Host Adapter.
   */
@@ -2775,7 +2781,7 @@
 	BusLogic_InitializeHostAdapter(HostAdapter)))
     {
       printk("scsi%d: Resetting %s Failed\n",
-	      HostAdapter->HostNumber, HostAdapter->BoardName);
+	      HostAdapter->HostNumber, HostAdapter->ControllerName);
       Result = SCSI_RESET_ERROR;
       goto Done;
     }
@@ -3047,18 +3053,18 @@
 
 /*
   BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
-  Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors,
-  and the appropriate number of cylinders so as not to exceed drive capacity.
-  In order for disks equal to or larger than 1 GB to be addressable by the
-  BIOS without exceeding the BIOS limitation of 1024 cylinders, Extended
-  Translation may be enabled in AutoSCSI on "W" and "C" Series boards or by a
-  dip switch setting on older boards.  With Extended Translation enabled,
-  drives between 1 GB inclusive and 2 GB exclusive are given a disk geometry
-  of 128 heads and 32 sectors, and drives above 2 GB inclusive are given a
-  disk geometry of 255 heads and 63 sectors.  However, if the BIOS detects
-  that the Extended Translation setting does not match the geometry in the
-  partition table, then the translation inferred from the partition table
-  will be used by the BIOS, and a warning may be displayed.
+  Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
+  the appropriate number of cylinders so as not to exceed drive capacity.  In
+  order for disks equal to or larger than 1 GB to be addressable by the BIOS
+  without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
+  may be enabled in AutoSCSI on "W" and "C" Series controllers or by a dip
+  switch setting on older controllers.  With Extended Translation enabled,
+  drives between 1 GB inclusive and 2 GB exclusive are given a disk geometry of
+  128 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
+  geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
+  Extended Translation setting does not match the geometry in the partition
+  table, then the translation inferred from the partition table will be used by
+  the BIOS, and a warning may be displayed.
 */
 
 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
diff -u --recursive --new-file v2.0.7/linux/drivers/scsi/BusLogic.h linux/drivers/scsi/BusLogic.h
--- v2.0.7/linux/drivers/scsi/BusLogic.h	Thu Jun  6 17:42:36 1996
+++ linux/drivers/scsi/BusLogic.h	Wed Jul 17 21:22:13 1996
@@ -141,19 +141,19 @@
 
 
 /*
-  Define the possible Local Options.
+  Define the possible Probe Options.
 */
 
-#define BusLogic_InhibitTargetInquiry		1
+#define BusLogic_NoProbe			1
+#define BusLogic_NoProbeISA			2
+#define BusLogic_NoSortPCI			4
 
 
 /*
-  Define the possible Probe Options.
+  Define the possible Local Options.
 */
 
-#define BusLogic_NoProbe			1
-#define BusLogic_NoProbeISA			2
-#define BusLogic_NoSortPCI			4
+#define BusLogic_InhibitTargetInquiry		1
 
 
 /*
@@ -209,7 +209,7 @@
 #define BusLogic_CommandParameterRegister	1	/* WO register */
 #define BusLogic_DataInRegister			1	/* RO register */
 #define BusLogic_InterruptRegister		2	/* RO register */
-#define BusLogic_GeometryRegister		3	/* RO, undocumented */
+#define BusLogic_GeometryRegister		3	/* RO register */
 
 
 /*
@@ -250,7 +250,7 @@
 
 
 /*
-  Define the bits in the undocumented read-only Geometry Register.
+  Define the bits in the read-only Geometry Register.
 */
 
 #define BusLogic_Drive0Geometry			0x03
@@ -265,40 +265,50 @@
 
 typedef enum
 {
-  BusLogic_TestCommandCompleteInterrupt =	0x00,	/* documented */
-  BusLogic_InitializeMailbox =			0x01,	/* documented */
-  BusLogic_ExecuteMailboxCommand =		0x02,	/* documented */
-  BusLogic_ExecuteBIOSCommand =			0x03,	/* documented */
-  BusLogic_InquireBoardID =			0x04,	/* documented */
-  BusLogic_EnableOutgoingMailboxAvailableInt =	0x05,	/* documented */
-  BusLogic_SetSCSISelectionTimeout =		0x06,	/* documented */
-  BusLogic_SetPreemptTimeOnBus =		0x07,	/* documented */
-  BusLogic_SetTimeOffBus =			0x08,	/* ISA Bus only */
-  BusLogic_SetBusTransferRate =			0x09,	/* ISA Bus only */
-  BusLogic_InquireInstalledDevicesID0to7 =	0x0A,	/* documented */
-  BusLogic_InquireConfiguration =		0x0B,	/* documented */
-  BusLogic_SetTargetMode =			0x0C,	/* now undocumented */
-  BusLogic_InquireSetupInformation =		0x0D,	/* documented */
-  BusLogic_WriteAdapterLocalRAM =		0x1A,	/* documented */
-  BusLogic_ReadAdapterLocalRAM =		0x1B,	/* documented */
-  BusLogic_WriteBusMasterChipFIFO =		0x1C,	/* documented */
-  BusLogic_ReadBusMasterChipFIFO =		0x1D,	/* documented */
-  BusLogic_EchoCommandData =			0x1F,	/* documented */
-  BusLogic_HostAdapterDiagnostic =		0x20,	/* documented */
-  BusLogic_SetAdapterOptions =			0x21,	/* documented */
-  BusLogic_InquireInstalledDevicesID8to15 =	0x23,	/* Wide only */
-  BusLogic_InquireDevices =			0x24,	/* "W" and "C" only */
-  BusLogic_InitializeExtendedMailbox =		0x81,	/* documented */
-  BusLogic_InquireFirmwareVersion3rdDigit =	0x84,	/* undocumented */
-  BusLogic_InquireFirmwareVersionLetter =	0x85,	/* undocumented */
-  BusLogic_InquireGenericIOPortInformation =	0x86,	/* PCI only */
-  BusLogic_InquireBoardModelNumber	 =	0x8B,	/* undocumented */
-  BusLogic_InquireSynchronousPeriod =		0x8C,	/* undocumented */
-  BusLogic_InquireExtendedSetupInformation =	0x8D,	/* documented */
-  BusLogic_EnableStrictRoundRobinMode =		0x8F,	/* documented */
-  BusLogic_FetchHostAdapterLocalRAM =		0x91,	/* undocumented */
-  BusLogic_ModifyIOAddress =			0x95,	/* PCI only */
-  BusLogic_EnableWideModeCCB =			0x96	/* Wide only */
+  BusLogic_TestCommandCompleteInterrupt =	0x00,
+  BusLogic_InitializeMailbox =			0x01,
+  BusLogic_ExecuteMailboxCommand =		0x02,
+  BusLogic_ExecuteBIOSCommand =			0x03,
+  BusLogic_InquireBoardID =			0x04,
+  BusLogic_EnableOutgoingMailboxAvailableInt =	0x05,
+  BusLogic_SetSCSISelectionTimeout =		0x06,
+  BusLogic_SetPreemptTimeOnBus =		0x07,
+  BusLogic_SetTimeOffBus =			0x08,
+  BusLogic_SetBusTransferRate =			0x09,
+  BusLogic_InquireInstalledDevicesID0to7 =	0x0A,
+  BusLogic_InquireConfiguration =		0x0B,
+  BusLogic_EnableTargetMode =			0x0C,
+  BusLogic_InquireSetupInformation =		0x0D,
+  BusLogic_WriteAdapterLocalRAM =		0x1A,
+  BusLogic_ReadAdapterLocalRAM =		0x1B,
+  BusLogic_WriteBusMasterChipFIFO =		0x1C,
+  BusLogic_ReadBusMasterChipFIFO =		0x1D,
+  BusLogic_EchoCommandData =			0x1F,
+  BusLogic_HostAdapterDiagnostic =		0x20,
+  BusLogic_SetAdapterOptions =			0x21,
+  BusLogic_InquireInstalledDevicesID8to15 =	0x23,
+  BusLogic_InquireTargetDevices =		0x24,
+  BusLogic_DisableHostAdapterInterrupt =	0x25,
+  BusLogic_InitializeExtendedMailbox =		0x81,
+  BusLogic_ExecuteSCSICommand =			0x83,
+  BusLogic_InquireFirmwareVersion3rdDigit =	0x84,
+  BusLogic_InquireFirmwareVersionLetter =	0x85,
+  BusLogic_InquireGenericIOPortInformation =	0x86,
+  BusLogic_InquireControllerModelNumber =	0x8B,
+  BusLogic_InquireSynchronousPeriod =		0x8C,
+  BusLogic_InquireExtendedSetupInformation =	0x8D,
+  BusLogic_EnableStrictRoundRobinMode =		0x8F,
+  BusLogic_StoreHostAdapterLocalRAM =		0x90,
+  BusLogic_FetchHostAdapterLocalRAM =		0x91,
+  BusLogic_StoreLocalDataInEEPROM =		0x92,
+  BusLogic_UploadAutoSCSICode =			0x94,
+  BusLogic_ModifyIOAddress =			0x95,
+  BusLogic_SetCCBFormat =			0x96,
+  BusLogic_WriteInquiryBuffer =			0x9A,
+  BusLogic_ReadInquiryBuffer =			0x9B,
+  BusLogic_FlashROMUploadDownload =		0xA7,
+  BusLogic_ReadSCAMData =			0xA8,
+  BusLogic_WriteSCAMData =			0xA9
 }
 BusLogic_OperationCode_T;
 
@@ -328,10 +338,10 @@
 
 
 /*
-  Define the Inquire Devices reply type.  Inquire Devices only tests Logical
-  Unit 0 of each Target Device unlike Inquire Installed Devices which tests
-  Logical Units 0 - 7.  Two bytes are returned, where bit 0 set indicates
-  that Target Device 0 exists, and so on.
+  Define the Inquire Target Devices reply type.  Inquire Target Devices only
+  tests Logical Unit 0 of each Target Device unlike the Inquire Installed
+  Devices commands which test Logical Units 0 - 7.  Two bytes are returned,
+  where bit 0 set indicates that Target Device 0 exists, and so on.
 */
 
 typedef unsigned short BusLogic_InstalledDevices_T;
@@ -393,7 +403,7 @@
   unsigned char DisconnectPermittedID0to7;		/* Byte 16 */
   unsigned char Signature;				/* Byte 17 */
   unsigned char CharacterD;				/* Byte 18 */
-  unsigned char BusLetter;				/* Byte 19 */
+  unsigned char HostBusType;				/* Byte 19 */
   unsigned char :8;					/* Byte 20 */
   unsigned char :8;					/* Byte 21 */
   BusLogic_SynchronousValues8_T SynchronousValuesID8to15; /* Bytes 22-29 */
@@ -449,10 +459,10 @@
 
 
 /*
-  Define the Inquire Board Model Number reply type.
+  Define the Inquire Controller Model Number reply type.
 */
 
-typedef unsigned char BusLogic_BoardModelNumber_T[5];
+typedef unsigned char BusLogic_ControllerModelNumber_T[5];
 
 
 /*
@@ -483,7 +493,8 @@
   boolean HostDifferentialSCSI:1;			/* Byte 13 Bit 1 */
   boolean HostAutomaticConfiguration:1;			/* Byte 13 Bit 2 */
   boolean HostUltraSCSI:1;				/* Byte 13 Bit 3 */
-  unsigned char :4;					/* Byte 13 Bits 4-7 */
+  boolean HostSmartTermination:1;			/* Byte 13 Bit 4 */
+  unsigned char :3;					/* Byte 13 Bits 5-7 */
 }
 BusLogic_ExtendedSetupInformation_T;
 
@@ -559,20 +570,21 @@
 
 
 /*
-  Define the Enable Wide Mode SCSI CCB request type.  Wide Mode CCBs are
-  necessary to support more than 8 Logical Units per Target Device.
+  Define the Set CCB Format request type.  64 LUN Format CCBs are necessary to
+  support 64 Logical Units per Target Device.  8 LUN Format CCBs only support 8
+  Logical Units per Target Device.
 */
 
-#define BusLogic_NormalModeCCB			0x00
-#define BusLogic_WideModeCCB			0x01
+#define BusLogic_8LUNFormatCCB			0x00
+#define BusLogic_64LUNFormatCCB			0x01
 
-typedef unsigned char BusLogic_WideModeCCBRequest_T;
+typedef unsigned char BusLogic_SetCCBFormatRequest_T;
 
 
 /*
   Define the Requested Reply Length type used by the Inquire Setup Information,
-  Inquire Board Model Number, Inquire Synchronous Period, and Inquire Extended
-  Setup Information commands.
+  Inquire Controller Model Number, Inquire Synchronous Period, and Inquire
+  Extended Setup Information commands.
 */
 
 typedef unsigned char BusLogic_RequestedReplyLength_T;
@@ -732,13 +744,13 @@
 /*
   Define the 32 Bit Mode Command Control Block (CCB) structure.  The first 40
   bytes are defined by the Host Adapter Firmware Interface.  The remaining
-  components are defined by the Linux BusLogic Driver.  Wide Mode CCBs differ
-  from standard 32 Bit Mode CCBs only in having the TagEnable and QueueTag
-  fields moved from byte 17 to byte 1, and the Logical Unit field in byte 17
-  expanded to 6 bits; unfortunately, using a union of structs containing
-  enumeration type bitfields to provide both definitions leads to packing
-  problems, so the following definition is used which requires setting
-  TagEnable to Logical Unit bit 5 in Wide Mode CCBs.
+  components are defined by the Linux BusLogic Driver.  64 LUN Format CCBs
+  differ from standard 8 LUN Format 32 Bit Mode CCBs only in having the
+  TagEnable and QueueTag fields moved from byte 17 to byte 1, and the Logical
+  Unit field in byte 17 expanded to 6 bits; unfortunately, using a union of
+  structs containing enumeration type bitfields to provide both definitions
+  leads to packing problems, so the following definition is used which requires
+  setting TagEnable to Logical Unit bit 5 in 64 LUN Format CCBs.
 */
 
 typedef struct BusLogic_CCB
@@ -749,8 +761,8 @@
   BusLogic_CCB_Opcode_T Opcode:8;			/* Byte 0 */
   unsigned char :3;					/* Byte 1 Bits 0-2 */
   BusLogic_DataDirection_T DataDirection:2;		/* Byte 1 Bits 3-4 */
-  boolean WideModeTagEnable:1;				/* Byte 1 Bit 5 */
-  BusLogic_QueueTag_T WideModeQueueTag:2;		/* Byte 1 Bits 6-7 */
+  boolean TagEnable64LUN:1;				/* Byte 1 Bit 5 */
+  BusLogic_QueueTag_T QueueTag64LUN:2;			/* Byte 1 Bits 6-7 */
   unsigned char CDB_Length;				/* Byte 2 */
   unsigned char SenseDataLength;			/* Byte 3 */
   unsigned int DataLength;				/* Bytes 4-7 */
@@ -863,7 +875,7 @@
   unsigned char HostNumber;
   unsigned char ModelName[9];
   unsigned char FirmwareVersion[6];
-  unsigned char BoardName[18];
+  unsigned char ControllerName[18];
   unsigned char InterruptLabel[62];
   unsigned char IRQ_Channel;
   unsigned char DMA_Channel;
@@ -883,7 +895,8 @@
   boolean LowByteTerminated:1;
   boolean HighByteTerminated:1;
   boolean BounceBuffersRequired:1;
-  boolean StrictRoundRobinModeSupported:1;
+  boolean StrictRoundRobinModeSupport:1;
+  boolean Host64LUNSupport:1;
   boolean HostAdapterResetRequested:1;
   volatile boolean HostAdapterCommandCompleted:1;
   unsigned short HostAdapterScatterGatherLimit;
@@ -1057,7 +1070,7 @@
   unsigned long ProcessorFlags;
   save_flags(ProcessorFlags);
   sti();
-  while (jiffies < TimeoutJiffies) ;
+  while (jiffies < TimeoutJiffies) barrier();
   restore_flags(ProcessorFlags);
 }
 
diff -u --recursive --new-file v2.0.7/linux/drivers/scsi/README.BusLogic linux/drivers/scsi/README.BusLogic
--- v2.0.7/linux/drivers/scsi/README.BusLogic	Mon Jul  8 16:09:54 1996
+++ linux/drivers/scsi/README.BusLogic	Wed Jul 17 21:22:13 1996
@@ -1,9 +1,9 @@
 		  BusLogic MultiMaster SCSI Driver for Linux
 
-		       Version 1.2.5 for Linux 1.2.13
-		       Version 2.0.5 for Linux 2.0.4
+		       Version 1.2.6 for Linux 1.2.13
+		       Version 2.0.6 for Linux 2.0.4
 
-				  7 July 1996
+				 17 July 1996
 
 			       Leonard N. Zubkoff
 			       Dandelion Digital
@@ -296,9 +296,9 @@
     during installation on a system with a flaky SCSI configuration.  In cases
     of a marginal SCSI configuration it may also be beneficial to disable fast
     transfers and/or synchronous negotiation using AutoSCSI on "W" and "C"
-    series boards.  Disconnect/reconnect may also be disabled for fast devices
-    such as disk drives, but should not be disabled for tape drives or other
-    devices where a single command may take over a second to execute.
+    series controllers.  Disconnect/reconnect may also be disabled for fast
+    devices such as disk drives, but should not be disabled for tape drives or
+    other devices where a single command may take over a second to execute.
 
   "BusLogic=0,0,30"
 
@@ -326,7 +326,7 @@
 				 INSTALLATION
 
 This distribution was prepared for Linux kernel version 1.2.13
-(BusLogic-1.2.5.tar.gz) or Linux kernel version 2.0.4 (BusLogic-2.0.5.tar.gz).
+(BusLogic-1.2.6.tar.gz) or Linux kernel version 2.0.4 (BusLogic-2.0.6.tar.gz).
 Installation in later versions will probably be successful as well, though
 BusLogic.patch may not be required.  Installation in earlier versions is not
 recommended.
@@ -336,7 +336,7 @@
 (substitute "1.2" or "2.0" for "x.y" in the tar command as appropriate):
 
   cd /usr/src
-  tar -xvzf BusLogic-x.y.5.tar.gz
+  tar -xvzf BusLogic-x.y.6.tar.gz
   mv README.* BusLogic.[ch] linux/drivers/scsi
   patch -p < BusLogic.patch	    (on Linux 1.2.13 only)
   patch -p < BusLogic.elf_patch	    (on Linux 1.2.13 ELF systems only)
diff -u --recursive --new-file v2.0.7/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.0.7/linux/drivers/scsi/sd.c	Wed Jul 10 15:20:27 1996
+++ linux/drivers/scsi/sd.c	Thu Jul 18 14:28:48 1996
@@ -729,9 +729,9 @@
 	   ((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
 #endif
 	SCpnt->use_sg = count;  /* Number of chains */
-	count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes */
-	while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
-	    count = count << 1;
+	/* scsi_malloc can only allocate in chunks of 512 bytes */
+	count  = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511;
+
 	SCpnt->sglist_len = count;
 	max_sg = count / sizeof(struct scatterlist);
 	if(SCpnt->host->sg_tablesize < max_sg) 
diff -u --recursive --new-file v2.0.7/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.0.7/linux/drivers/scsi/sr.c	Thu Jun  6 22:35:44 1996
+++ linux/drivers/scsi/sr.c	Thu Jul 18 14:28:48 1996
@@ -822,9 +822,9 @@
 	    };
 	};
 	SCpnt->use_sg = count;  /* Number of chains */
-	count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
-	while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
-	    count = count << 1;
+	/* scsi_malloc can only allocate in chunks of 512 bytes */
+	count  = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511;
+
 	SCpnt->sglist_len = count;
 	sgpnt = (struct scatterlist * ) scsi_malloc(count);
 	if (!sgpnt) {
diff -u --recursive --new-file v2.0.7/linux/drivers/sound/configure.c linux/drivers/sound/configure.c
--- v2.0.7/linux/drivers/sound/configure.c	Sat Jul  6 14:51:26 1996
+++ linux/drivers/sound/configure.c	Sat Jul 20 08:56:20 1996
@@ -77,7 +77,7 @@
 #define AD1848_DEVS (B(OPT_GUS16)|B(OPT_MSS)|B(OPT_PSS)|B(OPT_GUSMAX)|\
 		     B(OPT_SSCAPE)|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_CS4232)|\
 		     B(OPT_SPNP))
-#define SBDSP_DEVS (B(OPT_SB)|B(OPT_SPNP)|B(OPT_MAD16))
+#define SBDSP_DEVS (B(OPT_SB)|B(OPT_SPNP)|B(OPT_MAD16)|B(OPT_TRIX))
 #define SEQUENCER_DEVS (OPT_MIDI|OPT_YM3812|OPT_ADLIB|OPT_GUS|OPT_MAUI|MIDI_CARDS)
 /*
  * Options that have been disabled for some reason (incompletely implemented
diff -u --recursive --new-file v2.0.7/linux/drivers/sound/trix.c linux/drivers/sound/trix.c
--- v2.0.7/linux/drivers/sound/trix.c	Sat Jul  6 14:51:28 1996
+++ linux/drivers/sound/trix.c	Sat Jul 20 08:56:29 1996
@@ -442,7 +442,9 @@
 void
 unload_trix_sb (struct address_info *hw_config)
 {
+#ifdef CONFIG_SBDSP
   unload_sb (hw_config);
+#endif
 }
 
 
diff -u --recursive --new-file v2.0.7/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- v2.0.7/linux/fs/ncpfs/dir.c	Wed Jul  3 22:05:18 1996
+++ linux/fs/ncpfs/dir.c	Thu Jul 18 15:52:00 1996
@@ -92,6 +92,20 @@
 	}
 }
 
+static inline int
+ncp_namespace(struct inode *i)
+{
+	struct ncp_server *server   = NCP_SERVER(i);
+	struct nw_info_struct *info = NCP_ISTRUCT(i);
+	return server->name_space[info->volNumber];
+}
+
+static inline int
+ncp_preserve_case(struct inode *i)
+{
+	return (ncp_namespace(i) == NW_NS_OS2);
+}
+
 static struct file_operations ncp_dir_operations = {
         NULL,			/* lseek - default */
 	ncp_dir_read,		/* read - bad */
@@ -128,7 +142,7 @@
 /* Here we encapsulate the inode number handling that depends upon the
  * mount mode: When we mount a complete server, the memory address of
  * the ncp_inode_info is used as the inode number. When only a single
- * volume is mounted, then the DosDirNum is used as the inode
+ * volume is mounted, then the dirEntNum is used as the inode
  * number. As this is unique for the complete volume, this should
  * enable the NFS exportability of a ncpfs-mounted volume.
  */
@@ -143,7 +157,7 @@
 ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info)
 {
 	return ncp_single_volume(server)
-		? info->finfo.i.DosDirNum : (ino_t)info;
+		? info->finfo.i.dirEntNum : (ino_t)info;
 }
 
 static inline int
@@ -177,8 +191,6 @@
 	return NULL;
 }
 	
-
-
 static int 
 ncp_dir_read(struct inode *inode, struct file *filp, char *buf, int count)
 {
@@ -326,9 +338,12 @@
                         c_last_returned_index = 0;
                         index = 0;
 
-			for (i = 0; i < c_size; i++)
+			if (!ncp_preserve_case(inode))
 			{
-				str_lower(c_entry[i].i.entryName);
+				for (i = 0; i < c_size; i++)
+				{
+					str_lower(c_entry[i].i.entryName);
+				}
 			}
 		}
 	}
@@ -345,7 +360,7 @@
 
 		if (ncp_single_volume(server))
 		{
-			ino = (ino_t)(entry->i.DosDirNum);
+			ino = (ino_t)(entry->i.dirEntNum);
 		}
 		else
 		{
@@ -652,7 +667,7 @@
         root->finfo.opened = 0;
 	i->attributes  = aDIR;
 	i->dataStreamSize = 1024;
-	i->DosDirNum = 0;
+	i->dirEntNum = i->DosDirNum = 0;
 	i->volNumber = NCP_NUMBER_OF_VOLUMES+1;	/* illegal volnum */
 	ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
 	ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));
@@ -729,7 +744,7 @@
 
         do
 	{
-		if (   (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
+		if (   (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum)
 		    && (result->dir->finfo.i.volNumber == dir_info->volNumber)
 		    && (strcmp(result->finfo.i.entryName, name) == 0)
 		    /* The root dir is never looked up using this
@@ -757,6 +772,7 @@
 	struct ncp_server *server;
 	struct ncp_inode_info *result_info;
 	int found_in_cache;
+	int down_case = 0;
 	char name[len+1];
 
 	*result = NULL;
@@ -867,20 +883,26 @@
         if (found_in_cache == 0)
 	{
 		int res;
-		str_upper(name);
 
 		DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
 			 NCP_ISTRUCT(dir)->entryName, name);
 
 		if (ncp_is_server_root(dir))
 		{
+			str_upper(name);
+			down_case = 1;
 			res = ncp_lookup_volume(server, name, &(finfo.i));
 		}
 		else
 		{
+			if (!ncp_preserve_case(dir))
+			{
+				str_upper(name);
+				down_case = 1;
+			}
 			res = ncp_obtain_info(server,
 					      NCP_ISTRUCT(dir)->volNumber,
-					      NCP_ISTRUCT(dir)->DosDirNum,
+					      NCP_ISTRUCT(dir)->dirEntNum,
 					      name, &(finfo.i));
 		}
 		if (res != 0)
@@ -892,7 +914,11 @@
         }
 
 	finfo.opened = 0;
-	str_lower(finfo.i.entryName);
+
+	if (down_case != 0)
+	{
+		str_lower(finfo.i.entryName);
+	}
 
 	if (!(*result = ncp_iget(dir, &finfo)))
 	{
@@ -929,7 +955,11 @@
 
 	strncpy(_name, name, len);
 	_name[len] = '\0';
-	str_upper(_name);
+
+	if (!ncp_preserve_case(dir))
+	{
+		str_upper(_name);
+	}
 
 	lock_super(dir->i_sb);
 	if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
@@ -946,7 +976,11 @@
 
 	ncp_invalid_dir_cache(dir);
 
-	str_lower(finfo.i.entryName);
+	if (!ncp_preserve_case(dir))
+	{
+		str_lower(finfo.i.entryName);
+	}
+
 	finfo.access = O_RDWR;
 
 	if (!(*result = ncp_iget(dir, &finfo)) < 0)
@@ -980,7 +1014,11 @@
 
 	strncpy(_name, name, len);
 	_name[len] = '\0';
-	str_upper(_name);
+
+	if (!ncp_preserve_case(dir))
+	{
+		str_upper(_name);
+	}
 
 	if (!dir || !S_ISDIR(dir->i_mode))
 	{
@@ -1038,7 +1076,11 @@
 
 		strncpy(_name, name, len);
 		_name[len] = '\0';
-		str_upper(_name);
+
+		if (!ncp_preserve_case(dir))
+		{
+			str_upper(_name);
+		}
 
                 if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
 						    NCP_ISTRUCT(dir),
@@ -1081,7 +1123,11 @@
 	{
 		strncpy(_name, name, len);
 		_name[len] = '\0';
-		str_upper(_name);
+
+		if (!ncp_preserve_case(dir))
+		{
+			str_upper(_name);
+		}
 
                 if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
 						    NCP_ISTRUCT(dir),
@@ -1136,11 +1182,19 @@
 
 	strncpy(_old_name, old_name, old_len);
 	_old_name[old_len] = '\0';
-	str_upper(_old_name);
+
+	if (!ncp_preserve_case(old_dir))
+	{
+		str_upper(_old_name);
+	}
 
 	strncpy(_new_name, new_name, new_len);
 	_new_name[new_len] = '\0';
-	str_upper(_new_name);
+
+	if (!ncp_preserve_case(new_dir))
+	{
+		str_upper(_new_name);
+	}
 
 	res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
 					    NCP_ISTRUCT(old_dir), _old_name,
diff -u --recursive --new-file v2.0.7/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
--- v2.0.7/linux/fs/ncpfs/ncplib_kernel.c	Fri Mar 22 12:58:41 1996
+++ linux/fs/ncpfs/ncplib_kernel.c	Thu Jul 18 15:52:00 1996
@@ -190,25 +190,6 @@
 }
 
 int
-ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
-{
-	int result;
-
-	ncp_init_request_s(server, 5);
-	ncp_add_pstring(server, name);
-
-	if ((result = ncp_request(server, 22)) != 0)
-	{
-		ncp_unlock_server(server);
-		return result;
-	}
-
-	*target = ncp_reply_byte(server, 0);
-	ncp_unlock_server(server);
-	return 0;
-}
-
-int
 ncp_close_file(struct ncp_server *server, const char *file_id)
 {
 	int result;
@@ -278,8 +259,8 @@
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 6); /* subfunction */
-	ncp_add_byte(server, 0); /* dos name space */
-	ncp_add_byte(server, 0); /* dos name space as dest */
+	ncp_add_byte(server, server->name_space[vol_num]);
+	ncp_add_byte(server, server->name_space[vol_num]);
 	ncp_add_word(server, 0xff); /* get all */
 	ncp_add_dword(server, RIM_ALL);
 	ncp_add_handle_path(server, vol_num, dir_base, 1, path);
@@ -295,20 +276,57 @@
 	return 0;
 }
 
+static inline int
+ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
+{
+	int result;
+	__u8 *namespace;
+	__u16 no_namespaces;
+
+	ncp_init_request(server);
+	ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
+	ncp_add_word(server, 0);
+	ncp_add_byte(server, volume);
+
+	if ((result = ncp_request(server, 87)) != 0)
+	{
+		ncp_unlock_server(server);
+		return 0;
+	}
+
+	no_namespaces = ncp_reply_word(server, 0);
+	namespace = ncp_reply_data(server, 2);
+
+	while (no_namespaces > 0)
+	{
+		DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
+
+		if (*namespace == 4)
+		{
+			DPRINTK("get_namespaces: found OS2\n");
+			ncp_unlock_server(server);
+			return 1;
+		}
+		namespace += 1;
+		no_namespaces -= 1;
+	}
+	ncp_unlock_server(server);
+	return 0;
+}
+
 int
 ncp_lookup_volume(struct ncp_server *server,
 		  char *volname,
 		  struct nw_info_struct *target)
 {
 	int result;
-	__u8  vol_num;
-	__u32 dir_base;
+	int volnum;
 
 	DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
-	ncp_add_byte(server, 0); /* DOS name space */
+	ncp_add_byte(server, 0); /* DOS namespace */
 	ncp_add_byte(server, 0); /* reserved */
 	ncp_add_byte(server, 0); /* reserved */
 	ncp_add_byte(server, 0); /* reserved */
@@ -325,20 +343,19 @@
 		return result;
 	}
 
-	dir_base = ncp_reply_dword(server, 4);
-	vol_num  = ncp_reply_byte(server, 8);
+	memset(target, 0, sizeof(*target));
+	target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
+	target->volNumber = volnum = ncp_reply_byte(server, 8);
 	ncp_unlock_server(server);
 
-	if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL,
-				      target)) != 0)
-	{
-		return result;
-	}
+	server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
 
-	DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes);
+	DPRINTK("lookup_vol: namespace[%d] = %d\n",
+		volnum, server->name_space[volnum]);
 
 	target->nameLen = strlen(volname);
 	strcpy(target->entryName, volname);
+	target->attributes = aDIR;
 	return 0;
 }
 
@@ -352,14 +369,14 @@
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 7); /* subfunction */
-	ncp_add_byte(server, 0); /* dos name space */
+	ncp_add_byte(server, server->name_space[file->volNumber]);
 	ncp_add_byte(server, 0); /* reserved */
 	ncp_add_word(server, 0x8006); /* search attribs: all */
 
 	ncp_add_dword(server, info_mask);
 	ncp_add_mem(server, info, sizeof(*info));
 	ncp_add_handle_path(server, file->volNumber,
-			    file->DosDirNum, 1, NULL);
+			    file->dirEntNum, 1, NULL);
 
 	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
@@ -374,11 +391,11 @@
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 8); /* subfunction */
-	ncp_add_byte(server, 0); /* dos name space */
+	ncp_add_byte(server, server->name_space[dir->volNumber]);
 	ncp_add_byte(server, 0); /* reserved */
 	ncp_add_word(server, 0x8006); /* search attribs: all */
 	ncp_add_handle_path(server, dir->volNumber,
-			    dir->DosDirNum, 1, name);
+			    dir->dirEntNum, 1, name);
 	
 	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
@@ -406,15 +423,16 @@
 {
 	int result;
 	__u16 search_attribs = 0x0006;
+	__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
 
 	if ((create_attributes & aDIR) != 0)
 	{
-		search_attribs |= 0x8000;
-	}
+		search_attribs |= 0x8000;	
+}
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 1); /* subfunction */
-	ncp_add_byte(server, 0); /* dos name space */
+	ncp_add_byte(server, server->name_space[volume]);
 	ncp_add_byte(server, open_create_mode);
 	ncp_add_word(server, search_attribs);
 	ncp_add_dword(server, RIM_ALL);
@@ -425,13 +443,11 @@
 
 	if (dir != NULL)
 	{
-		ncp_add_handle_path(server, dir->volNumber,
-				    dir->DosDirNum, 1, name);
+		ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
 	}
 	else
 	{
-		ncp_add_handle_path(server,
-				    target->i.volNumber, target->i.DosDirNum,
+		ncp_add_handle_path(server, volume, target->i.dirEntNum,
 				    1, NULL);
 	}	
 
@@ -467,9 +483,9 @@
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 2); /* subfunction */
-	ncp_add_byte(server, 0); /* dos name space */
+	ncp_add_byte(server, server->name_space[dir->volNumber]);
 	ncp_add_byte(server, 0); /* reserved */
-	ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
+	ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
 	
 	if ((result = ncp_request(server, 87)) != 0)
 	{
@@ -493,7 +509,7 @@
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 3); /* subfunction */
-	ncp_add_byte(server, 0); /* dos name space */
+	ncp_add_byte(server, server->name_space[seq->volNumber]);
 	ncp_add_byte(server, 0); /* data stream (???) */
 	ncp_add_word(server, 0xffff); /* Search attribs */
 	ncp_add_dword(server, RIM_ALL);	/* return info mask */
@@ -528,19 +544,19 @@
 	
 	ncp_init_request(server);
 	ncp_add_byte(server, 4); /* subfunction */
-	ncp_add_byte(server, 0); /* dos name space */
+	ncp_add_byte(server, server->name_space[old_dir->volNumber]);
 	ncp_add_byte(server, 1); /* rename flag */
 	ncp_add_word(server, 0x8006); /* search attributes */
 
 	/* source Handle Path */
 	ncp_add_byte(server, old_dir->volNumber);
-	ncp_add_dword(server, old_dir->DosDirNum);
+	ncp_add_dword(server, old_dir->dirEntNum);
 	ncp_add_byte(server, 1);
 	ncp_add_byte(server, 1); /* 1 source component */
 
 	/* dest Handle Path */
 	ncp_add_byte(server, new_dir->volNumber);
-	ncp_add_dword(server, new_dir->DosDirNum);
+	ncp_add_dword(server, new_dir->dirEntNum);
 	ncp_add_byte(server, 1);
 	ncp_add_byte(server, 1); /* 1 destination component */
 
diff -u --recursive --new-file v2.0.7/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
--- v2.0.7/linux/fs/nfs/dir.c	Wed Jul  3 22:05:19 1996
+++ linux/fs/nfs/dir.c	Sat Jul 20 09:25:25 1996
@@ -71,14 +71,17 @@
 {
 	struct nfs_fattr fattr;
 
-	if (jiffies - NFS_READTIME(dir) < server->acdirmax)
+	if (jiffies - NFS_READTIME(dir) < NFS_ATTRTIMEO(dir))
 		return;
 
 	NFS_READTIME(dir) = jiffies;
 	if (nfs_proc_getattr(server, NFS_FH(dir), &fattr) == 0) {
 		nfs_refresh_inode(dir, &fattr);
-		if (fattr.mtime.seconds == NFS_OLDMTIME(dir))
+		if (fattr.mtime.seconds == NFS_OLDMTIME(dir)) {
+			if ((NFS_ATTRTIMEO(dir) <<= 1) > server->acdirmax)
+				NFS_ATTRTIMEO(dir) = server->acdirmax;
 			return;
+		}
 		NFS_OLDMTIME(dir) = fattr.mtime.seconds;
 	}
 	/* invalidate directory cache here when we _really_ start caching */
@@ -697,6 +700,8 @@
 	/* Size changed from outside: invalidate caches on next read */
 	if (inode->i_size != fattr->size)
 		NFS_CACHEINV(inode);
+	if (NFS_OLDMTIME(inode) != fattr->mtime.seconds)
+		NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
 	inode->i_size = fattr->size;
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		inode->i_rdev = to_kdev_t(fattr->rdev);
diff -u --recursive --new-file v2.0.7/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v2.0.7/linux/fs/nfs/file.c	Wed Jul  3 22:05:19 1996
+++ linux/fs/nfs/file.c	Sat Jul 20 08:56:29 1996
@@ -70,14 +70,17 @@
 {
 	struct nfs_fattr fattr;
 
-	if (jiffies - NFS_READTIME(inode) < server->acregmax)
+	if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode))
 		return;
 
 	NFS_READTIME(inode) = jiffies;
 	if (nfs_proc_getattr(server, NFS_FH(inode), &fattr) == 0) {
 		nfs_refresh_inode(inode, &fattr);
-		if (fattr.mtime.seconds == NFS_OLDMTIME(inode))
+		if (fattr.mtime.seconds == NFS_OLDMTIME(inode)) {
+			if ((NFS_ATTRTIMEO(inode) <<= 1) > server->acregmax)
+				NFS_ATTRTIMEO(inode) = server->acregmax;
 			return;
+		}
 		NFS_OLDMTIME(inode) = fattr.mtime.seconds;
 	}
 	invalidate_inode_pages(inode);
diff -u --recursive --new-file v2.0.7/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h
--- v2.0.7/linux/include/asm-i386/pgtable.h	Wed Apr 24 17:00:42 1996
+++ linux/include/asm-i386/pgtable.h	Wed Jul 17 10:35:40 1996
@@ -293,14 +293,14 @@
 		__asm__ __volatile__("movl %0,%%cr3": :"r" (pgdir)); \
 } while (0)
 
-extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
-extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_PRESENT; }
-extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
-
-extern inline int pmd_none(pmd_t pmd)		{ return !pmd_val(pmd); }
-extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; }
-extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd) & _PAGE_PRESENT; }
-extern inline void pmd_clear(pmd_t * pmdp)	{ pmd_val(*pmdp) = 0; }
+#define pte_none(x)	(!pte_val(x))
+#define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(xp)	do { pte_val(*(xp)) = 0; } while (0)
+
+#define pmd_none(x)	(!pmd_val(x))
+#define	pmd_bad(x)	((pmd_val(x) & ~PAGE_MASK) != _PAGE_TABLE)
+#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+#define pmd_clear(xp)	do { pmd_val(*(xp)) = 0; } while (0)
 
 /*
  * The "pgd_xxx()" functions here are trivial for a folded two-level
@@ -421,25 +421,35 @@
 
 extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
 {
-	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-	if (pmd_none(*pmd)) {
-		pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
-		if (pmd_none(*pmd)) {
-			if (page) {
-				pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
-				return page + address;
-			}
-			pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
-			return NULL;
-		}
-		free_page((unsigned long) page);
-	}
-	if (pmd_bad(*pmd)) {
-		printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-		pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + address;
+	address = (address >> (PAGE_SHIFT-2)) & 4*(PTRS_PER_PTE - 1);
+
+repeat:
+	if (pmd_none(*pmd))
+		goto getnew;
+	if (pmd_bad(*pmd))
+		goto fix;
+	return (pte_t *) (pmd_page(*pmd) + address);
+	
+getnew:
+{
+	unsigned long page = __get_free_page(GFP_KERNEL);
+	if (!pmd_none(*pmd))
+		goto freenew;
+	if (!page)
+		goto oom;
+	memset((void *) page, 0, PAGE_SIZE);
+	pmd_val(*pmd) = _PAGE_TABLE | page;
+	return (pte_t *) (page + address);
+freenew:
+	free_page(page);
+	goto repeat;
+}
+
+fix:
+	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+oom:
+	pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+	return NULL;
 }
 
 /*
diff -u --recursive --new-file v2.0.7/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.0.7/linux/include/linux/mm.h	Wed Jul  3 22:05:20 1996
+++ linux/include/linux/mm.h	Sat Jul 20 09:19:57 1996
@@ -112,20 +112,19 @@
  * here (16 bytes or greater).  This ordering should be particularly
  * beneficial on 32-bit processors.
  *
- * The first line is data used in linear searches (eg. clock algorithm
- * scans).  The second line is data used in page searches through the
- * page-cache.  -- sct 
+ * The first line is data used in page cache lookup, the second line
+ * is used for linear searches (eg. clock algorithm scans). 
  */
 typedef struct page {
+	struct inode *inode;
+	unsigned long offset;
+	struct page *next_hash;
 	atomic_t count;
+	unsigned flags;	/* atomic flags, some possibly updated asynchronously */
 	unsigned dirty:16,
 		 age:8;
-	unsigned flags;	/* atomic flags, some possibly updated asynchronously */
 	struct wait_queue *wait;
 	struct page *next;
-	struct page *next_hash;
-	unsigned long offset;
-	struct inode *inode;
 	struct page *prev;
 	struct page *prev_hash;
 	struct buffer_head * buffers;
diff -u --recursive --new-file v2.0.7/linux/include/linux/ncp.h linux/include/linux/ncp.h
--- v2.0.7/linux/include/linux/ncp.h	Mon Mar 25 10:26:15 1996
+++ linux/include/linux/ncp.h	Thu Jul 18 15:52:00 1996
@@ -116,6 +116,12 @@
 	__u16   update_time;
 };
 
+/* Defines for Name Spaces */
+#define NW_NS_DOS     0
+#define NW_NS_MAC     1
+#define NW_NS_NFS     2
+#define NW_NS_FTAM    3
+#define NW_NS_OS2     4
 
 /*  Defines for ReturnInformationMask */
 #define RIM_NAME	      (0x0001L)
diff -u --recursive --new-file v2.0.7/linux/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h
--- v2.0.7/linux/include/linux/ncp_fs_sb.h	Mon Mar 25 10:26:16 1996
+++ linux/include/linux/ncp_fs_sb.h	Fri Jul 19 09:36:14 1996
@@ -21,6 +21,8 @@
 				    interest for us later, so we store
 				    it completely. */
 
+	__u8 name_space[NCP_NUMBER_OF_VOLUMES];
+
 	struct file *ncp_filp;	/* File pointer to ncp socket */
 	struct file *wdog_filp;	/* File pointer to wdog socket */
 	struct file *msg_filp;	/* File pointer to message socket */
diff -u --recursive --new-file v2.0.7/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- v2.0.7/linux/include/linux/nfs_fs.h	Wed Jul  3 22:05:20 1996
+++ linux/include/linux/nfs_fs.h	Sat Jul 20 08:56:43 1996
@@ -46,6 +46,10 @@
 #define NFS_RENAMED_DIR(inode)		((inode)->u.nfs_i.silly_rename_dir)
 #define NFS_READTIME(inode)		((inode)->u.nfs_i.read_cache_jiffies)
 #define NFS_OLDMTIME(inode)		((inode)->u.nfs_i.read_cache_mtime)
+#define NFS_ATTRTIMEO(inode)		((inode)->u.nfs_i.attrtimeo)
+#define NFS_MINATTRTIMEO(inode)		(S_ISREG((inode)->i_mode)?	\
+						NFS_SERVER(inode)->acregmin : \
+						NFS_SERVER(inode)->acdirmin)
 #define NFS_CACHEINV(inode) \
 do { \
 	NFS_READTIME(inode) = jiffies - 1000000; \
diff -u --recursive --new-file v2.0.7/linux/include/linux/nfs_fs_i.h linux/include/linux/nfs_fs_i.h
--- v2.0.7/linux/include/linux/nfs_fs_i.h	Fri Apr 12 15:52:08 1996
+++ linux/include/linux/nfs_fs_i.h	Sat Jul 20 08:56:51 1996
@@ -28,6 +28,10 @@
 	 * NFS FH, but that requires a kmalloc.
 	 */
 	struct inode *silly_rename_dir;
+	/*
+	 * attrtimeo defines for how long the cached attributes are valid
+	 */
+	unsigned long attrtimeo;
 };
 
 #endif
diff -u --recursive --new-file v2.0.7/linux/include/linux/pagemap.h linux/include/linux/pagemap.h
--- v2.0.7/linux/include/linux/pagemap.h	Wed Apr 17 09:06:32 1996
+++ linux/include/linux/pagemap.h	Sat Jul 20 09:19:57 1996
@@ -17,7 +17,7 @@
 	return PAGE_OFFSET + PAGE_SIZE * page->map_nr;
 }
 
-#define PAGE_HASH_BITS 10
+#define PAGE_HASH_BITS 11
 #define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS)
 
 #define PAGE_AGE_VALUE 16
@@ -48,16 +48,22 @@
 {
 	struct page *page;
 
-	for (page = page_hash(inode, offset); page ; page = page->next_hash) {
+	page = page_hash(inode, offset);
+	goto inside;
+	for (;;) {
+		page = page->next_hash;
+inside:
+		if (!page)
+			goto not_found;
 		if (page->inode != inode)
 			continue;
-		if (page->offset != offset)
-			continue;
-		/* Found the page. */
-		atomic_inc(&page->count);
-		set_bit(PG_referenced, &page->flags);
-		break;
+		if (page->offset == offset)
+			break;
 	}
+	/* Found the page. */
+	atomic_inc(&page->count);
+	set_bit(PG_referenced, &page->flags);
+not_found:
 	return page;
 }
 
diff -u --recursive --new-file v2.0.7/linux/include/net/ip_forward.h linux/include/net/ip_forward.h
--- v2.0.7/linux/include/net/ip_forward.h	Wed Feb  7 08:55:42 1996
+++ linux/include/net/ip_forward.h	Fri Jul 19 08:24:05 1996
@@ -5,6 +5,7 @@
 #define IPFWD_LASTFRAG		2
 #define IPFWD_MASQUERADED	4
 #define IPFWD_MULTICASTING	8
-#define IPFWD_MULTITUNNEL	16
+#define IPFWD_MULTITUNNEL	0x10
+#define IPFWD_NOTTLDEC		0x20
 
 #endif
diff -u --recursive --new-file v2.0.7/linux/include/net/netlink.h linux/include/net/netlink.h
--- v2.0.7/linux/include/net/netlink.h	Fri May 17 15:32:19 1996
+++ linux/include/net/netlink.h	Sat Jul 20 09:26:56 1996
@@ -2,8 +2,9 @@
 #define __NET_NETLINK_H
 
 #define NET_MAJOR 36		/* Major 18 is reserved for networking 						*/
-#define MAX_LINKS 10		/* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved 	*/
+#define MAX_LINKS 11		/* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved 	*/
 				/* 4-7 are psi0-psi3  8 is arpd 9 is ppp */
+				/* 10 is for IPSEC <John Ioannidis> */
 #define MAX_QBYTES 32768	/* Maximum bytes in the queue 							*/
 
 #include <linux/config.h>
@@ -21,6 +22,7 @@
 #define NETLINK_PSI		4	/* PSI devices - 4 to 7 */
 #define NETLINK_ARPD		8
 #define NETLINK_NET_PPP		9	/* Non tty PPP devices */
+#define NETLINK_IPSEC		10	/* IPSEC */
 
 #ifdef CONFIG_RTNETLINK
 extern void ip_netlink_msg(unsigned long, __u32, __u32, __u32, short, short, char *);
diff -u --recursive --new-file v2.0.7/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.0.7/linux/kernel/ksyms.c	Mon Jul  8 16:09:57 1996
+++ linux/kernel/ksyms.c	Thu Jul 18 14:28:48 1996
@@ -45,6 +45,7 @@
 #include <linux/skbuff.h>
 #include <linux/genhd.h>
 #include <linux/swap.h>
+#include <linux/ctype.h>
 
 extern unsigned char aux_device_present, kbd_read_mask;
 
@@ -297,6 +298,7 @@
 	X(system_utsname),
 	X(sys_call_table),
 	X(hard_reset_now),
+	X(_ctype),
 
 	/* Signal interfaces */
 	X(send_sig),
diff -u --recursive --new-file v2.0.7/linux/kernel/sched.c linux/kernel/sched.c
--- v2.0.7/linux/kernel/sched.c	Wed Jul  3 22:05:23 1996
+++ linux/kernel/sched.c	Wed Jul 17 14:43:32 1996
@@ -1117,7 +1117,7 @@
 	if (increase)
 		increment = -increment;
 	newprio = current->priority - increment;
-	if (newprio < 1)
+	if ((signed) newprio < 1)
 		newprio = 1;
 	if (newprio > DEF_PRIORITY*2)
 		newprio = DEF_PRIORITY*2;
diff -u --recursive --new-file v2.0.7/linux/kernel/sys.c linux/kernel/sys.c
--- v2.0.7/linux/kernel/sys.c	Wed Jul 17 08:12:17 1996
+++ linux/kernel/sys.c	Wed Jul 17 08:16:54 1996
@@ -636,11 +636,8 @@
 {
 	struct task_struct * p;
 
-	if (current->leader)
-		return -EPERM;
-
 	for_each_task(p) {
-		if (p != current && p->pgrp == current->pid)
+		if (p->pgrp == current->pid)
 		        return -EPERM;
 	}
 
diff -u --recursive --new-file v2.0.7/linux/mm/filemap.c linux/mm/filemap.c
--- v2.0.7/linux/mm/filemap.c	Sat Jun  1 20:11:36 1996
+++ linux/mm/filemap.c	Wed Jul 17 11:41:51 1996
@@ -782,7 +782,8 @@
 	 * Ok, found a page in the page cache, now we need to check
 	 * that it's up-to-date
 	 */
-	wait_on_page(page);
+	if (PageLocked(page))
+		goto page_locked_wait;
 	if (!PageUptodate(page))
 		goto page_read_error;
 
@@ -849,6 +850,11 @@
 		new_page = try_to_read_ahead(inode, offset + PAGE_SIZE, 0);
 	goto found_page;
 
+page_locked_wait:
+	__wait_on_page(page);
+	if (PageUptodate(page))
+		goto success;
+	
 page_read_error:
 	/*
 	 * Umm, take care of errors if the page isn't up-to-date.
diff -u --recursive --new-file v2.0.7/linux/mm/memory.c linux/mm/memory.c
--- v2.0.7/linux/mm/memory.c	Mon Jul 15 11:20:24 1996
+++ linux/mm/memory.c	Wed Jul 17 13:20:37 1996
@@ -855,28 +855,6 @@
 	} while ((mpnt = mpnt->vm_next_share) != inode->i_mmap);
 }
 
-/*
- * fill in an empty page-table if none exists.
- */
-static inline pte_t * get_empty_pgtable(struct task_struct * tsk,unsigned long address)
-{
-	pgd_t *pgd;
-	pmd_t *pmd;
-	pte_t *pte;
-
-	pgd = pgd_offset(tsk->mm, address);
-	pmd = pmd_alloc(pgd, address);
-	if (!pmd) {
-		oom(tsk);
-		return NULL;
-	}
-	pte = pte_alloc(pmd, address);
-	if (!pte) {
-		oom(tsk);
-		return NULL;
-	}
-	return pte;
-}
 
 static inline void do_swap_page(struct task_struct * tsk, 
 	struct vm_area_struct * vma, unsigned long address,
@@ -912,41 +890,38 @@
 void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma,
 	unsigned long address, int write_access)
 {
+	pgd_t * pgd;
+	pmd_t * pmd;
 	pte_t * page_table;
 	pte_t entry;
 	unsigned long page;
 
-	page_table = get_empty_pgtable(tsk, address);
+	pgd = pgd_offset(tsk->mm, address);
+	pmd = pmd_alloc(pgd, address);
+	if (!pmd)
+		goto no_memory;
+	page_table = pte_alloc(pmd, address);
 	if (!page_table)
-		return;
+		goto no_memory;
 	entry = *page_table;
 	if (pte_present(entry))
-		return;
-	if (!pte_none(entry)) {
-		do_swap_page(tsk, vma, address, page_table, entry, write_access);
-		return;
-	}
+		goto is_present;
+	if (!pte_none(entry))
+		goto swap_page;
 	address &= PAGE_MASK;
-	if (!vma->vm_ops || !vma->vm_ops->nopage) {
-		flush_cache_page(vma, address);
-		get_empty_page(tsk, vma, page_table, write_access);
-		return;
-	}
-	++tsk->maj_flt;
-	++vma->vm_mm->rss;
+	if (!vma->vm_ops || !vma->vm_ops->nopage)
+		goto anonymous_page;
 	/*
 	 * The third argument is "no_share", which tells the low-level code
 	 * to copy, not share the page even if sharing is possible.  It's
 	 * essentially an early COW detection 
 	 */
-	page = vma->vm_ops->nopage(vma, address, write_access && !(vma->vm_flags & VM_SHARED));
-	if (!page) {
-		force_sig(SIGBUS, current);
-		flush_cache_page(vma, address);
-		put_page(page_table, BAD_PAGE);
-		/* no need to invalidate, wasn't present */
-		return;
-	}
+	page = vma->vm_ops->nopage(vma, address, 
+		(vma->vm_flags & VM_SHARED)?0:write_access);
+	if (!page)
+		goto sigbus;
+	++tsk->maj_flt;
+	++vma->vm_mm->rss;
 	/*
 	 * This silly early PAGE_DIRTY setting removes a race
 	 * due to the bad i386 page protection. But it's valid
@@ -966,6 +941,28 @@
 	flush_cache_page(vma, address);
 	put_page(page_table, entry);
 	/* no need to invalidate: a not-present page shouldn't be cached */
+	return;
+
+sigbus:
+	force_sig(SIGBUS, current);
+	flush_cache_page(vma, address);
+	put_page(page_table, BAD_PAGE);
+	/* no need to invalidate, wasn't present */
+	return;
+
+anonymous_page:
+	flush_cache_page(vma, address);
+	get_empty_page(tsk, vma, page_table, write_access);
+	return;
+
+swap_page:
+	do_swap_page(tsk, vma, address, page_table, entry, write_access);
+	return;
+
+no_memory:
+	oom(tsk);
+is_present:
+	return;
 }
 
 /*
diff -u --recursive --new-file v2.0.7/linux/net/bridge/br.c linux/net/bridge/br.c
--- v2.0.7/linux/net/bridge/br.c	Mon Jul  8 16:09:57 1996
+++ linux/net/bridge/br.c	Fri Jul 19 08:24:05 1996
@@ -1307,7 +1307,7 @@
 		/*
 		 *	Sending
 		 */
-		if (port_info[f->port].state == Forwarding) {
+		if (f->port!=port && port_info[f->port].state == Forwarding) {
 			/* has entry expired? */
 			if (f->timer + fdb_aging_time < CURRENT_TIME) {
 				/* timer expired, invalidate entry */
diff -u --recursive --new-file v2.0.7/linux/net/ipv4/Config.in linux/net/ipv4/Config.in
--- v2.0.7/linux/net/ipv4/Config.in	Thu Jun  6 17:42:38 1996
+++ linux/net/ipv4/Config.in	Fri Jul 19 08:24:05 1996
@@ -7,7 +7,7 @@
   bool 'IP: firewalling' CONFIG_IP_FIREWALL
   if [ "$CONFIG_IP_FIREWALL" = "y" ]; then
     bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+    if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_IP_FORWARD" = "y" ]; then
       bool 'IP: masquerading (EXPERIMENTAL)' CONFIG_IP_MASQUERADE
       if [ "$CONFIG_IP_MASQUERADE" != "n" ]; then
         comment 'Protocol-specific masquerading support will be built as modules.'
diff -u --recursive --new-file v2.0.7/linux/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c
--- v2.0.7/linux/net/ipv4/ip_forward.c	Wed Jul  3 22:05:23 1996
+++ linux/net/ipv4/ip_forward.c	Fri Jul 19 19:48:43 1996
@@ -39,7 +39,7 @@
 #include <net/checksum.h>
 #include <linux/route.h>
 #include <net/route.h>
- 
+
 #ifdef CONFIG_IP_FORWARD
 #ifdef CONFIG_IP_MROUTE
 
@@ -57,8 +57,11 @@
 	 *	Firstly push down and install the IPIP header.
 	 */
 	struct iphdr *iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr));
+
 	if(len>65515)
 		len=65515;
+
+
 	iph->version	= 	4;
 	iph->tos	=	skb->ip_hdr->tos;
 	iph->ttl	=	skb->ip_hdr->ttl;
@@ -67,17 +70,26 @@
 	iph->saddr	=	out->pa_addr;
 	iph->protocol	=	IPPROTO_IPIP;
 	iph->ihl	=	5;
-	iph->tot_len	=	htons(skb->len);
+	iph->tot_len	=	htons(skb->len + len);  /* Anand, ernet */
 	iph->id		=	htons(ip_id_count++);
 	ip_send_check(iph);
 
 	skb->dev = out;
 	skb->arp = 1;
-	skb->raddr=daddr;
+	skb->raddr=daddr;  /* Router address is not destination address. The
+			    * correct value is given eventually. I have not
+			    * removed this statement. But could have. 
+			    * Anand, ernet.
+			    */ 
 	/*
 	 *	Now add the physical header (driver will push it down).
 	 */
-	if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL, len)<0)
+
+	/* The last parameter of out->hard_header() needed skb->len + len.
+ 	 * Anand, ernet.
+	 */
+	if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL, 
+	skb->len + len)<0)
 			skb->arp=0;
 	/*
 	 *	Read to queue for transmission.
@@ -121,18 +133,22 @@
 	 */
 
 	iph = skb->h.iph;
-	iph->ttl--;
+	if (!(is_frag&IPFWD_NOTTLDEC))
+	{
+		unsigned long checksum = iph->check;
+		iph->ttl--;
 
 	/*
 	 *	Re-compute the IP header checksum.
-	 *	This is inefficient. We know what has happened to the header
-	 *	and could thus adjust the checksum as Phil Karn does in KA9Q
+	 *	This is efficient. We know what has happened to the header
+	 *	and can thus adjust the checksum as Phil Karn does in KA9Q
+	 *	except we do this in "network byte order".
 	 */
-
-	iph->check = ntohs(iph->check) + 0x0100;
-	if ((iph->check & 0xFF00) == 0)
-		iph->check++;		/* carry overflow */
-	iph->check = htons(iph->check);
+		checksum += htons(0x0100);
+		/* carry overflow? */
+		checksum += checksum >> 16;
+		iph->check = checksum;
+	}
 
 	if (iph->ttl <= 0)
 	{
@@ -141,8 +157,14 @@
 		return -1;
 	}
 
+	/* If IPFWD_MULTITUNNEL flag is set, then we have to perform routing
+	 * decision so as to reach the other end of the tunnel. This condition
+	 * also means that we are dealing with a unicast IP packet "in a way". 
+	 * Anand, ernet.
+	 */
+
 #ifdef CONFIG_IP_MROUTE
-	if(!(is_frag&IPFWD_MULTICASTING))
+	if(!(is_frag&IPFWD_MULTICASTING) || (is_frag&IPFWD_MULTITUNNEL))
 	{
 #endif	
 		/*
@@ -205,6 +227,12 @@
 				icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
 #endif
 #ifdef CONFIG_IP_MROUTE
+
+		/* This is for ip encap. Anand, ernet.*/
+
+		if (is_frag&IPFWD_MULTITUNNEL) {
+			encap=20;
+				}
 	}
 	else
 	{
@@ -327,7 +355,20 @@
 			if(is_frag&IPFWD_MULTITUNNEL)
 			{
 				skb_reserve(skb2,(encap+dev2->hard_header_len+15)&~15);	/* 16 byte aligned IP headers are good */
-				ip_encap(skb2,skb->len, dev2, raddr);
+
+/* We need to pass on IP information of the incoming packet to ip_encap() 
+ * to fillin ttl, and tos fields.The destination should be target_addr. 
+ *  Anand, ernet. 
+ */
+
+				skb2->ip_hdr = skb->ip_hdr; 
+
+				ip_encap(skb2,skb->len, dev2, target_addr);
+
+/*  The router address is got earlier that to take us to the remote tunnel
+ *  Anand, ernet.
+ */
+				skb2->raddr = rt->rt_gateway;
 			}
 			else
 #endif			
@@ -341,7 +382,6 @@
 			ptr = skb_put(skb2,skb->len);
 			skb2->free = 1;
 			skb2->h.raw = ptr;
-
 			/*
 			 *	Copy the packet data into the new buffer.
 			 */
@@ -517,3 +557,6 @@
 
 
 #endif
+
+
+
diff -u --recursive --new-file v2.0.7/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c
--- v2.0.7/linux/net/ipv4/ip_fragment.c	Mon May 13 23:02:53 1996
+++ linux/net/ipv4/ip_fragment.c	Sat Jul 20 08:58:28 1996
@@ -610,6 +610,8 @@
 	struct sk_buff *skb2;
 	int left, mtu, hlen, len;
 	int offset;
+	
+	unsigned short true_hard_header_len;
 
 	/*
 	 *	Point into the IP datagram header.
@@ -624,12 +626,18 @@
 #endif
 
 	/*
+	 * Calculate the length of the link-layer header appended to
+	 * the IP-packet.
+	 */
+	true_hard_header_len = ((unsigned char *)iph) - raw;
+
+	/*
 	 *	Setup starting values.
 	 */
 
 	hlen = iph->ihl * 4;
 	left = ntohs(iph->tot_len) - hlen;	/* Space per frame */
-	hlen += dev->hard_header_len;		/* Total header size */
+	hlen += true_hard_header_len;
 	mtu = (dev->mtu - hlen);		/* Size of data space */
 	ptr = (raw + hlen);			/* Where to start from */
 
@@ -706,8 +714,11 @@
 		 */
 
 		skb2->arp = skb->arp;
+		skb2->protocol = htons(ETH_P_IP); /* Atleast PPP needs this */
+#if 0		
 		if(skb->free==0)
 			printk(KERN_ERR "IP fragmenter: BUG free!=1 in fragmenter\n");
+#endif			
 		skb2->free = 1;
 		skb_put(skb2,len + hlen);
 		skb2->h.raw=(char *) skb2->data;
@@ -735,7 +746,7 @@
 		memcpy(skb2->h.raw + hlen, ptr, len);
 		left -= len;
 
-		skb2->h.raw+=dev->hard_header_len;
+		skb2->h.raw+=true_hard_header_len;
 
 		/*
 		 *	Fill in the new header fields.
diff -u --recursive --new-file v2.0.7/linux/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c
--- v2.0.7/linux/net/ipv4/ipmr.c	Sat Jun  1 20:11:37 1996
+++ linux/net/ipv4/ipmr.c	Fri Jul 19 08:24:05 1996
@@ -1,5 +1,5 @@
 /*
- *	IP multicast routing support for mrouted 3.6
+ *	IP multicast routing support for mrouted 3.6/3.8
  *
  *		(c) 1995 Alan Cox, <alan@cymru.net>
  *	  Linux Consultancy and Custom Driver Development
@@ -12,8 +12,11 @@
  *
  *	Fixes:
  *	Michael Chastain	:	Incorrect size of copying.
- *	Alan Cox		:	Added the cache manager code
+ *	Alan Cox		:	Added the cache manager code.
  *	Alan Cox		:	Fixed the clone/copy bug and device race.
+ *	Malcolm Beattie		:	Buffer handling fixes.
+ *	Alexey Kuznetsov	:	Double buffer free and other fixes.
+ *	SVR Anand		:	Fixed several multicast bugs and problems.
  *
  *	Status:
  *		Cache manager under test. Forwarding in vague test mode
@@ -736,7 +739,14 @@
 		kfree_skb(skb, FREE_WRITE);
 		return;
 	}
+
+	/*
+	 *	Without the following addition, skb->h.iph points to something
+	 *	different that is not the ip header.
+	 */
 	
+	skb->h.iph = skb->ip_hdr;  /* Anand, ernet.  */
+
 	vif_table[vif].pkt_in++;
 	vif_table[vif].bytes_in+=skb->len;
 	
@@ -909,7 +919,7 @@
  
 void ip_mr_init(void)
 {
-	printk(KERN_INFO "Linux IP multicast router 0.05.\n");
+	printk(KERN_INFO "Linux IP multicast router 0.06.\n");
 	register_netdevice_notifier(&ip_mr_notifier);
 #ifdef CONFIG_PROC_FS	
 	proc_net_register(&(struct proc_dir_entry) {
diff -u --recursive --new-file v2.0.7/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v2.0.7/linux/net/ipx/af_ipx.c	Sat Jun  1 20:11:37 1996
+++ linux/net/ipx/af_ipx.c	Fri Jul 19 08:24:05 1996
@@ -1267,7 +1267,7 @@
  *	Route an outgoing frame from a socket.
  */
 
-static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len)
+static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock)
 {
 	struct sk_buff *skb;
 	ipx_interface *intrfc;
@@ -1296,7 +1296,7 @@
 	size=sizeof(ipx_packet)+len;
 	size += ipx_offset;
 
-	skb=sock_alloc_send_skb(sk, size, 0, 0, &err);
+	skb=sock_alloc_send_skb(sk, size, 0, noblock, &err);
 	if(skb==NULL)
 		return err;
 
@@ -2133,7 +2133,7 @@
 		memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
 	}
 	
-	retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len);
+	retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, noblock);
 	if (retval < 0) 
 		return retval;
 
diff -u --recursive --new-file v2.0.7/linux/net/netsyms.c linux/net/netsyms.c
--- v2.0.7/linux/net/netsyms.c	Thu Jun  6 17:42:39 1996
+++ linux/net/netsyms.c	Fri Jul 19 08:24:05 1996
@@ -159,6 +159,7 @@
 	X(skb_clone),
 	X(dev_alloc_skb),
 	X(dev_kfree_skb),
+	X(skb_device_unlock),
 	X(netif_rx),
 	X(dev_tint),
 	X(irq2dev_map),
