diff -u --recursive --new-file v2.1.125/linux/CREDITS linux/CREDITS
--- v2.1.125/linux/CREDITS	Fri Oct  9 13:27:04 1998
+++ linux/CREDITS	Tue Oct 20 14:17:45 1998
@@ -210,9 +210,11 @@
 S: Australia
 
 N: Philip Blundell
-E: Philip.Blundell@pobox.com
-D: Device driver hacking 
-D: Some Linux/ARM stuff
+E: philb@gnu.org
+D: Linux/ARM hacker
+D: Device driver hacker (eexpress, 3c505, c-qcam, ...)
+D: m68k port to HP9000/300
+D: AUN network protocols
 D: Co-architect of the parallel port sharing system
 S: Nexus Electronics Ltd
 S: 10 St Barnabas Road, Cambridge CB1 2BY
@@ -1304,7 +1306,7 @@
 S: USA
 
 N: Johan Myreen
-E: jem@vipunen.hut.fi
+E: jem@iki.fi
 D: PS/2 mouse driver writer etc.
 S: Dragonvagen 1 A 13
 S: FIN-00330 Helsingfors
@@ -1852,6 +1854,18 @@
 S: 90491 Nuernberg
 S: Germany
 
+N: Geert Uytterhoeven
+E: geert@linux-m68k.org
+W: http://www.cs.kuleuven.ac.be/~geert/
+P: 1024/EC4A1EE1 8B 88 38 35 88 1E 95 A1  CD 9E AE DC 4B 4A 2F 41
+D: m68k/Amiga and PPC/CHRP Longtrail coordinator
+D: Frame buffer device and XF68_FBDev maintainer
+D: m68k IDE maintainer
+D: Amiga Zorro maintainer
+S: C. Huysmansstraat 12
+S: B-3128 Baal
+S: Belgium
+
 N: Petr Vandrovec
 E: vandrove@vc.cvut.cz
 D: Small contributions to ncpfs
@@ -1991,14 +2005,15 @@
 S: The Netherlands
 
 N: David Woodhouse
+E: Dave@mvhi.com
 E: Dave@imladris.demon.co.uk
 D: Extensive ARCnet rewrite
 D: ARCnet COM20020, COM90xx IO-MAP drivers
 D: SO_BINDTODEVICE in 2.1.x (from Elliot Poger's code in 2.0.31)
 D: Contributed to NCPFS rewrite for 2.1.x dcache
 D: Alpha platforms: SX164, LX164 and Ruffian ported to 2.1.x
-S: Robinson College, Grange Road
-S: Cambridge. CB3 9AN
+S: 29, David Bull Way
+S: Milton, Cambridge. CB4 6DP
 S: England
 
 N: Frank Xia
diff -u --recursive --new-file v2.1.125/linux/Documentation/Changes linux/Documentation/Changes
--- v2.1.125/linux/Documentation/Changes	Mon Oct  5 13:13:34 1998
+++ linux/Documentation/Changes	Tue Oct 20 13:18:23 1998
@@ -33,7 +33,7 @@
    Also, don't forget http://www.linuxhq.com/ for all your Linux kernel
 needs.
 
-Last updated: September 3, 1998
+Last updated: October 9, 1998
 Current Author: Chris Ricker (kaboom@gatech.edu or chris.ricker@m.cc.utah.edu).
 
 Current Minimal Requirements
@@ -43,13 +43,14 @@
 encountered a bug!  If you're unsure what version you're currently
 running, the suggested command should tell you.
 
-- Kernel modules	 2.1.85                  ; insmod -V
+- Kernel modules	 2.1.121                 ; insmod -V
 - Gnu C 		 2.7.2.3                 ; gcc --version
 - Binutils		 2.8.1.0.23              ; ld -v
-- Linux C Library	 5.4.46                  ; ls -l /lib/libc.so.*
+- Linux libc5 C Library	 5.4.46                  ; ls -l /lib/libc.so.*
+- Linux libc6 C Library  2.0.7pre6               ; ls -l /lib/libc.so.*
 - Dynamic Linker (ld.so) 1.9.9                   ; ldd --version or ldd -v
 - Linux C++ Library	 2.7.2.8                 ; ls -l /usr/lib/libg++.so.*
-- Procps		 1.2.8                   ; ps --version
+- Procps		 1.2.9                   ; ps --version
 - Procinfo               14                      ; procinfo -v
 - Psmisc		 17			 ; pstree -V
 - Mount                  2.7l                    ; mount --version
@@ -57,11 +58,12 @@
 - Loadlin                1.6a
 - Sh-utils               1.16                    ; basename --v
 - Autofs                 0.3.11                  ; automount --version
-- NFS                    0.4.21                  ; showmount --version
+- NFS                    2.2beta37               ; showmount --version
 - Bash                   1.14.7                  ; bash -version
 - Ncpfs                  2.2.0                   ; ncpmount -v
 - Pcmcia-cs              3.0.5                   ; cardmgr -V
 - PPP                    2.3.5                   ; pppd -v
+- PCI Utilities          1.08                    ; lspci --version
 
 Upgrade notes
 *************
@@ -114,8 +116,8 @@
 more information, see the files in Documentation/fb/ ; you may also
 need to download the fbset utilities.
 
-Libc
-====
+Libc (libc5)
+============
 
    Linux-2.1.x is ELF-only.  You can still compile a.out apps if you
 really want, but your kernel must be compiled ELF.  If you can't
@@ -144,11 +146,25 @@
 accompanying release notes.  The section about it breaking make is not
 a joke.
 
+GNU libc (libc6)
+================
+
+   Older versions of GNU libc (libc6) have a bug in the dynamic linker.
+/etc/ld.so.cache gets mapped into memory and is never unmapped.  If one
+of your boot scripts calls ldconfig, /etc/ld.so.cache is deleted.  Init,
+however, still references that file; as of 2.1.122, the kernel will
+consequently not be able to remount the root file system r/o at system
+shutdown.  To fix this, upgrade to at least the pre6 release of GNU
+libc 2.0.7.  As a temporary workaround, modify your boot scripts to do
+the following before calling ldconfig:
+
+   	ln -f /etc/ld.so.cache /etc/ld.so.cache.old
+
 Modules
 =======
 
-   You need to upgrade to modutils-2.1.85 for kernels 2.1.85 and later.
-This version will also work with 2.0.x kernels.
+   You need to upgrade to the latest version of modutils-2.1.x for
+development kernels.  This version will also work with 2.0.x kernels.
 
    As of 2.1.90-pre1, kerneld has been replaced by a kernel thread,
 kmod.  See Documentation/kmod.txt for more information.  The main
@@ -222,12 +238,12 @@
 features like IPv6.
 
    As of 2.1.102, the IP firewalling code has been replaced; ipfwadm
-will no longer work.  You need to optain "ipchains," available from
+will no longer work.  You need to obtain "ipchains," available from
 http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html, and use
 that instead of ipfwadm.
 
-   To use port forwarding and auto forwarding you will need 'ipmasqadm'
-tool, available from http://juanjox.home.ml.org. 
+   To use port forwarding and auto forwarding you will need to obtain
+"ipmasqadm," available from http://juanjox.home.ml.org/.
 
 Memory
 ======
@@ -281,6 +297,13 @@
 /dev/lp0 with the new Plug-and-Play driver.  If printing breaks with
 the new driver, try checking your lpd configuration.
 
+Setserial
+=========
+
+   If you experience random problems (stuck lines, lost characters,
+etc.) with serial lines under recent kernels, upgrading setserial
+should help.
+
 Syncookies
 ==========
 
@@ -351,35 +374,28 @@
 ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.8.1.0.23
 ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.8.1.0.23
 
-The 2.9.1.0.7 release:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7-glibc.x86.tar.gz
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7-libc5.x86.tar.gz
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7-glibc.x86.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7-libc5.x86.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7.tar.gz
+The 2.9.1.0.12 release:
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.12-glibc.x86.tar.gz
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.12-libc5.x86.tar.gz
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.12.tar.gz
+ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.12-glibc.x86.tar.gz
+ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.12-libc5.x86.tar.gz
+ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.12.tar.gz
 Installation notes:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.9.1.0.7
-ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.9.1.0.7
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.9.1.0.12
+ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.9.1.0.12
 
 Gnu C
 =====
 
-The 2.7.2.3 release:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/gcc-2.7.2.3.bin.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/GCC/gcc-2.7.2.3.bin.tar.gz
-Installation notes:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.gcc-2.7.2.3
-ftp://sunsite.unc.edu/pub/Linux/GCC/release.gcc-2.7.2.3
-
-The egcs-1.0.2 release:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.2-glibc.x86.tar.gz
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.2-libc5.x86.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.2-glibc.x86.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.2-libc5.x86.tar.gz
+The egcs-1.0.3 release:
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.3-glibc.x86.tar.bz2
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.3-libc5.x86.tar.bz2
+ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.3-glibc.x86.tar.bz2
+ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.3-libc5.x86.tar.bz2
 Installation notes:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.egcs-1.0.2
-ftp://sunsite.unc.edu/pub/Linux/GCC/release.egcs-1.0.2
+ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.egcs-1.0.3
+ftp://sunsite.unc.edu/pub/Linux/GCC/release.egcs-1.0.3
 
 Gnu C 2.7.2.3 source:
 ftp://prep.ai.mit.edu/pub/gnu/gcc-2.7.2.3.tar.gz
@@ -388,13 +404,17 @@
 Linux C Library
 ===============
 
-The 5.4.46 release:
+The (libc5) 5.4.46 release:
 ftp://tsx-11.mit.edu/pub/linux/packages/GCC/libc-5.4.46.bin.tar.gz
 ftp://sunsite.unc.edu/pub/Linux/GCC/libc-5.4.46.bin.tar.gz
 Installation notes for 5.4.46:
 ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.libc-5.4.46
 ftp://sunsite.unc.edu/pub/Linux/GCC/release.libc-5.4.46
 
+The (libc6) GNU libc 2.0.7pre6 release:
+ftp://ftp.kernel.org/pub/software/libs/glibc/glibc-2.0.7pre6.tar.gz
+ftp://ftp.kernel.org/pub/software/libs/glibc/glibc-2.0.7pre6.tar.bz2
+
 Linux C++ Library
 =================
 
@@ -415,15 +435,15 @@
 Modules utilities
 =================
 
-The 2.1.85 release:
-ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.85.tar.gz
+The 2.1.121 release:
+ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.121.tar.gz
 
 Procps utilities
 ================
 
 The 1.2 release:
-ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.8.tar.gz
-ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.8.tgz
+ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.9.tar.gz
+ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.9.tgz
 
 Procinfo utilities
 ==================
@@ -454,8 +474,9 @@
 DOSEMU
 ======
 
-The 0.66.7 release:
-ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu-0.66.7.tgz
+The 0.98.1 release:
+ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu-0.98.1.tgz
+ftp://ftp.dosemu.org/dosemu/dosemu-0.98.1.tgz
 
 Loadlin
 =======
@@ -486,12 +507,13 @@
 NFS
 ===
 
-The user-land 0.4.21 release:
-ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz
-ftp://linux.nrao.edu/mirrors/fb0429.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz
-
-The kernel-level 8/30/98 release:
-ftp://ftp.yggdrasil.com/private/hjl/knfsd-980830.tar.gz
+The user-land 2.2beta37 release:
+ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/nfs-server-2.2beta37.tar.gz
+ftp://linux.nrao.edu/mirrors/fb0429.mathematik.th-darmstadt.de/pub/linux/okir/nfs-server-2.2beta37.tar.gz
+
+The kernel-level 9/30/98 release:
+ftp://ftp.yggdrasil.com/private/hjl/knfsd-980930.tar.gz
+ftp://ftp.kernel.org/pub/linux/devel/gcc/knfsd-980930.tar.gz
 
 Net-tools
 =========
@@ -530,6 +552,13 @@
 The 3.0.5 release:
 ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs.3.0.5.tar.gz
 
+Setserial
+=========
+
+The 2.14 release:
+ftp://tsx-11.mit.edu/pub/linux/sources/sbin/setserial-2.14.tar.gz
+ftp://sunsite.unc.edu/pub/Linux/system/serial/setserial-2.14.tar.gz
+
 PPP
 ===
 
@@ -545,6 +574,7 @@
 
 IP Masq Adm
 ===========
+
 The 0.4.1 release:
 http://juanjox.home.ml.org/ipmasqadm-0.4.1.tar.gz
 
@@ -566,6 +596,13 @@
 The 7/13/98 release:
 http://www.cs.kuleuven.ac.be/~geert/bin/fbset-2.0-pre-19980713.tar.gz
 
+PCIutils
+========
+
+The 1.08 release:
+ftp://atrey.karlin.mff.cuni.cz/pub/linux/pci/pciutils-1.08.tar.gz
+ftp://sunsite.unc.edu/pub/Linux/hardware/pciutils-1.08.tar.gz
+
 Other Info
 ==========
 
@@ -581,12 +618,12 @@
 your favorite Red Hat mirror site before installing the non-RPM
 version.  Remember, you might need to use the -force option to get the
 upgrade to install.  ftp://ftp.redhat.com/pub/contrib/ will have almost
-everything you need, as does Red Hat 5.0.
+everything you need, and Red Hat 5.1 ships with most necessary software.
 
    Those of you running Debian (or a different distribution that
 supports .deb packages) can look in the "unstable" and
 "project/experimental" directories of your favorite Debian mirror.  The
-Debian 2.0 release should have most packages you need as well.
+Debian 2.0 release ships with most packages you need as well.
 
    For others, David Bourgin has put together a package of everything
 necessary to quickly and easily upgrade to 2.1.x.  See
diff -u --recursive --new-file v2.1.125/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.125/linux/Documentation/Configure.help	Fri Oct  9 13:27:04 1998
+++ linux/Documentation/Configure.help	Wed Oct 21 15:31:04 1998
@@ -850,6 +850,26 @@
   here and read Documentation/modules.txt. The module will be called
   raid0.o. If unsure, say Y.
 
+Are you using a crosscompiler
+CONFIG_CROSSCOMPILE
+  Set this if you are using another architecture to compile the
+  kernel for your MIPS machine.
+
+Support for Acer PICA 1 chipset
+CONFIG_ACER_PICA_61
+  This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux on
+  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to have access to
+  a machine on the Internet that has a program like lynx or
+  netscape).
+
+Support for Algorithmics P4032
+CONFIG_ALGOR_P4032
+  This is an evaluation board of the British company Algorithmics.  The
+  board uses the R4300 and a R5230 CPUs.  For more information about
+  this board see www.algor.co.uk.
+
 RAID-1 (mirroring) mode
 CONFIG_MD_MIRRORING
   A RAID-1 set consists of several disk drives which are exact copies
@@ -871,6 +891,11 @@
   want to compile it as a module, say M here and read
   Documentation/modules.txt. If unsure, say Y.
 
+Boot support (linear, striped)
+CONFIG_MD_BOOT
+  To boot with an initial linear or striped md device you have to say
+  Y here. For lilo and loadlin options see Documentation/md.txt.
+
 RAID-4/RAID-5 mode
 CONFIG_MD_RAID5
   A RAID-5 set of N drives with a capacity of C MB per drive provides
@@ -892,28 +917,6 @@
   want to compile it as a module, say M here and read
   Documentation/modules.txt. If unsure, say Y.
 
-Boot support (linear, striped)
-CONFIG_MD_BOOT
-  To boot with an initial linear or striped md device you have to say
-  Y here. For lilo and loadlin options see Documentation/md.txt.
-
-Support for Deskstation RPC44 
-CONFIG_DESKSTATION_RPC44
-  This is a machine with a R4400 100 MHz CPU. To compile a Linux
-  kernel that runs on these, say Y here. For details about Linux
-  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  http://lena.fnet.fr/ (To browse the WWW, you need to
-  have access to a machine on the Internet that has a program like
-  lynx or netscape).
-
-Support for Mips Magnum 3000 
-CONFIG_MIPS_MAGNUM_3000
-  To compile a Linux kernel that runs on these machines, say Y here.
-  For details about Linux on the MIPS architecture, check out the
-  Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse the
-  WWW, you need to have access to a machine on the Internet that has a
-  program like lynx or netscape).
-
 Support for Mips Magnum 4000
 CONFIG_MIPS_MAGNUM_4000
   This is a machine with a R4000 100 MHz CPU. To compile a Linux
@@ -930,39 +933,29 @@
   http://lena.fnet.fr/ (To browse the WWW, you need to have access to
   a machine on the Internet that has a program like lynx or netscape).
 
-Support for Deskstation Tyne
-CONFIG_DESKSTATION_TYNE
-  This is a machine with a R4600 134 MHz CPU. The Linux port for this
-  system is idle right now because of hardware or documentation
-  problems. For details about Linux on the MIPS architecture, check
-  out the Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse
-  the WWW, you need to have access to a machine on the Internet that
-  has a program like lynx or netscape).
-
-Support for Acer PICA 1 chipset
-CONFIG_ACER_PICA_61
-  This is a machine with a R4400 134/150 MHz CPU. To compile a Linux
-  kernel that runs on these, say Y here. For details about Linux on
-  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  http://lena.fnet.fr/ (To browse the WWW, you need to have access to
-  a machine on the Internet that has a program like lynx or
-  netscape).
-
-Support for DECstation
-CONFIG_DECSTATION
-  The DECstation 3100 (with a MIPS R2000 series CPU) and DECstation
-  5000/xxx (MIPS R3000 series CPU) are also sometimes labeled
-  PMAX. They often run the Ultrix operating system. To compile a Linux
-  kernel that runs on these, say Y here. For details about Linux on
-  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  http://lena.fnet.fr/ (To browse the WWW, you need to have access to
-  a machine on the Internet that has a program like lynx or netscape).
-
 CPU type
 CONFIG_CPU_R3000
   Give the type of your machine's MIPS CPU. For this question,
   it suffices to give a unique prefix of the option you want to
-  choose. 
+  choose.  In case of doubt select the R3000 CPU.  This kernel will
+  run on other MIPS machines but with slightly reduced performance.
+
+Compile the kernel into the ECOFF object format
+CONFIG_ECOFF_KERNEL
+  Some machines require a kernel in the ECOFF format.  You will have to
+  Choose this option for example if you want to a Mips Magnum 3000 or a
+  DECstation over network.
+
+Generate little endian code
+CONFIG_CPU_LITTLE_ENDIAN
+  Some MIPS machines can be configured for either little or big endian
+  byte order.  Both modes require different kernels.  Say yes if your
+  machine is little endian, no if it's a big endian machine.
+
+Kernel support for IRIX binaries
+CONFIG_BINFMT_IRIX
+  This option enables the kernel support for IRIX binaries.  Running
+  IRIX binaries additionally requires IRIX libraries.
 
 Networking support
 CONFIG_NET
@@ -1191,20 +1184,29 @@
   servicing.  Say Y here to enable the serial driver to take advantage
   of those special I/O ports.
 
+SGI Zilog85C30 serial support
+CONFIG_SGI_SERIAL
+  If you want to use your SGI's built-in serial ports under Linux, say Y.
+
+SGI graphics support
+CONFIG_SGI_GRAPHICS
+  If you have an SGI machine and you want to compile the graphic drivers
+  select this option.  This will include the code for the /dev/graphics
+  and /dev/gfx drivers into the kernel for supporting the virtualized
+  access to your graphics hardware.
+
+Remote GDB kernel debugging
+CONFIG_REMOTE_DEBUG
+  This enables remote debugging support for the MIPS kernel.  Enabling
+  this option enlarges you kernel image disk size by several megabytes
+  and requires a machine with more than 16mb, better 32mb RAM to avoid
+  excessive linking time.
+
 Support the Bell Technologies HUB6 card
 CONFIG_HUB6
   Say Y here to enable support in the dumb serial driver to support
   the HUB6 card.
 
-TGA Console Support
-CONFIG_TGA_CONSOLE
-  Many Alpha systems (e.g the Multia) are shipped with a graphics card
-  that implements the TGA interface (much like the VGA standard, but
-  older TGA adapters are *not* VGA compatible).  On such systems, you
-  should say Y here so that the TGA driver rather than the standard
-  VGA driver is used.  Note that, at this time, there is no X server
-  for these systems. If unsure, try N.
-
 PCI support
 CONFIG_PCI
   Find out whether you have a PCI motherboard. PCI is the name of a
@@ -1866,6 +1868,12 @@
   be necessary to run older Mips systems, such as the Sony News and
   MIPS RC3xxx, in big endian mode.
 
+Build fp execption handler module
+CONFIG_MIPS_FPE_MODULE
+  Build the floating point exception handler module.  This option is only
+  useful for people working on the floating point exception handler.  If
+  you don't, say n.
+
 Plug and Play support
 CONFIG_PNP
   Plug and Play support allows the kernel to automatically configure
@@ -3217,6 +3225,16 @@
   This is a backward compatibility option, choose Y for now.
   This option will be removed soon.
 
+HIgh Performance Parallel Interface support (EXPERIMENTAL)
+CONFIG_HIPPI
+  HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and
+  1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI
+  can run over copper (25m) or fiber (300m on multi-mode or 10km on
+  single-mode). If you are connected to a HIPPI network, and want
+  to enable HIPPI support in the kernel, say Y here (you must also
+  remember to enable the driver for your HIPPI card below). Most
+  people will say N here.
+
 SCSI support?
 CONFIG_SCSI
   If you want to use a SCSI hard disk, SCSI tape drive, SCSI CDROM or
@@ -4108,6 +4126,11 @@
   your EPP chipset is from the SMC series, you are likely to have to
   set this value greater than 0.
 
+SGI wd93 Scsi Driver
+CONFIG_SCSI_SGIWD93
+  This is the SCSI driver for WD33C93 / WD33C95 SCSI chips used in many
+  SGI machines.
+
 SCSI Debug host simulator.
 CONFIG_SCSI_DEBUG
   This is a host adapter simulator that can be programmed to simulate
@@ -5312,7 +5335,7 @@
   This is yet another chipset driver for the COM90xx cards, but this
   time only using memory-mapped mode, and no IO ports at all. This
   driver is completely untested, so if you have one of these cards,
-  please mail dwmw2@cam.ac.uk, especially if it works!
+  please mail David.Woodhouse@mvhi.com, especially if it works!
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you
@@ -5838,6 +5861,10 @@
   This is support for the DIGITAL series of EISA (DEFEA) and PCI
   (DEFPA) controllers which can connect you to a local FDDI network.
 
+SGI Seeq ethernet controller support
+  This is a driver for the Seeq based Ethernet adapters used in many
+  Silicon Graphics machines.
+
 Acorn Ether1 card
 CONFIG_ARM_ETHER1
   If you have an Acorn system with one of these (AKA25) network cards,
@@ -6387,6 +6414,12 @@
   The module is called nfsd.o. If you want to compile it as a module,
   say M here and read Documentation/modules.txt. If unsure, say N.
 
+Emulate Sun NFS daemon
+CONFIG_NFSD_SUN
+  If you would like for the server to allow clients to access
+  directories that are mountpoints on the local filesystem (this is
+  how nfsd behaves on Sun systems), say yes here.  If unsure, say N.
+
 OS/2 HPFS filesystem support (read only)
 CONFIG_HPFS_FS
   OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
@@ -8187,7 +8220,7 @@
   say more than an occasional beep, by programming the PC speaker.
   Kernel patches and programs to do that are in the pcsndrv package on
   ftp://sunsite.unc.edu/pub/Linux/kernel/patches/console/ and in the
-  pcsp patch at ftp://dwmw2.robinson.cam.ac.uk/pub/kernel/ .
+  pcsp patch at http://www.imladris.demon.co.uk/pcsp/
 
 OSS sound modules
 CONFIG_SOUND_OSS
@@ -9261,7 +9294,7 @@
 
 Ariadne support
 CONFIG_ARIADNE
-  If you have a VillageTronics Ariadne Ethernet adapter, say Y.
+  If you have a Village Tronic Ariadne Ethernet adapter, say Y.
   Otherwise, say N.
 
   This driver is also available as a module ( = code which can be
@@ -9271,7 +9304,7 @@
 
 Ariadne II support
 CONFIG_ARIADNE2
-  If you have a VillageTronics Ariadne II Ethernet adapter, say Y.
+  If you have a Village Tronic Ariadne II Ethernet adapter, say Y.
   Otherwise, say N.
 
   This driver is also available as a module ( = code which can be
@@ -9745,6 +9778,46 @@
   Say 'Y' here for ARM systems with the VIDC video controller and 16-bit
   Linear sound DACs.  If unsure, say N.
 
+Backward compatibility mode for Xpmac
+CONFIG_FB_COMPAT_XPMAC
+  If you use the Xpmac X server (common with mklinux), you'll need
+  to enable this to use X. You should consider changing to XFree86
+  which includes a server that supports the frame buffer device
+  directly (XF68_FBDev).
+
+Support for PowerMac keyboard
+CONFIG_MAC_KEYBOARD
+  This option allows you to use an ADB keyboard attached to your
+  machine. Note that this disables any other (ie. PS/2) keyboard
+  support, even if your machine is physically capable of using both
+  at the same time.
+  
+  If you use an ADB keyboard (4 pin connector), say Y here.
+  If you use a PS/2 keyboard (6 pin connector), say N here.
+
+Support for PowerMac floppy
+CONFIG_MAC_FLOPPY
+  If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
+  floppy controller, say Y here. Most commonly found in PowerMacs.
+
+Support for PowerMac serial ports
+CONFIG_MAC_SERIAL
+  If you have Macintosh style serial ports (8 pin mini-DIN), this
+  is the driver for them. If you also have regular serial ports
+  and enable the driver for them, you can't currently use the
+  serial console feature.
+
+Support for PowerMac ADB mouse
+CONFIG_ADBMOUSE
+  If you have an ADB mouse (4 pin connector) as is common on
+  Macintoshes, say Y here.
+
+Winbond SL82c105 support
+CONFIG_BLK_DEV_SL82C105
+  If you have a Winbond SL82c105 IDE controller, say Y here to
+  enable special configuration for this chip. This is common
+  on various CHRP motherboards, but could be used elsewhere.
+  If in doubt, say Y.
 #
 # A couple of things I keep forgetting:
 #   capitalize: AppleTalk, Ethernet, DMA, FTP, Internet, Intel, IRQ, 
@@ -9853,7 +9926,7 @@
 # LocalWords:  INSNS Ataris AutoConfig ZORRO OCS AMIFB Agnus Denise ECS CDTV GB
 # LocalWords:  AGA Cybervision CYBER GSP TMS DMI Zorro ACSI ROMs SLM BioNet GVP
 # LocalWords:  PAMsNet TekMagic Cyberstorm MkI CYBERSTORMII MkII BLZ onboard cx
-# LocalWords:  VillageTronics ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB
+# LocalWords:  Village Tronic ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB
 # LocalWords:  Rhotron BioData's Multiface AMIGAMOUSE COPCON Amiga's bitplanes
 # LocalWords:  ATARIMOUSE MFPSER SCC's MegaSTE ESCC Atari's GVPIOEXT DMASOUND
 # LocalWords:  fdutils cisco univercd rpcg htm iface lapb LAPBETHER tpqic qic
diff -u --recursive --new-file v2.1.125/linux/Documentation/joystick-api.txt linux/Documentation/joystick-api.txt
--- v2.1.125/linux/Documentation/joystick-api.txt	Fri Oct  9 13:27:04 1998
+++ linux/Documentation/joystick-api.txt	Wed Oct 21 08:43:33 1998
@@ -98,7 +98,7 @@
 
 may work well if you handle JS_EVENT_INIT events separately,
 
-	if (js_event.type & ~JS_EVENT_INIT == JS_EVENT_BUTTON) {
+	if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) {
 	   if (js_event.value)
 	      buttons_state |= (1 << js_event.number);
 	   else
@@ -292,9 +292,12 @@
 
 The axis values do not have a defined range in the original 0.x driver,
 except for that the values are non-negative. The 1.2.8+ drivers use a
-fixed range for reporting the values, 0 being the minimum, 128 the
+fixed range for reporting the values, 1 being the minimum, 128 the
 center, and 255 maximum value.
 
+The v0.8.0.2 driver also had an interface for 'digital joysticks', (now
+called Multisystem joystick in this driver), under /dev/djsX. This driver
+doesn't try to be compatible with that interface.
 
 6. Final Notes
 ~~~~~~~~~~~~~~
diff -u --recursive --new-file v2.1.125/linux/Documentation/joystick-parport.txt linux/Documentation/joystick-parport.txt
--- v2.1.125/linux/Documentation/joystick-parport.txt	Fri Oct  9 13:27:04 1998
+++ linux/Documentation/joystick-parport.txt	Wed Oct 21 08:43:33 1998
@@ -231,7 +231,13 @@
 
 (pin 7) -----> Button 2
 
-2.2.1 Multisystem joysticks using joy-console.c
+  And that's it.
+
+  On a side note, if you have already built a different adapter for use with
+the digital joystick driver 0.8.0.2, this is also supported by the joy-db9.c
+driver, as device type 8. (See section 3.2)
+
+2.2.2 Multisystem joysticks using joy-console.c
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   For some people just one joystick per parallel port is not enough, and/or
 want to use them on one parallel port together with NES/SNES/PSX pads. This
@@ -440,21 +446,23 @@
 more parallel ports.
 
   Changes:
-    v0.1 : First version (SNES only)
-    v0.2 : X/Y directions were exchanged...
-    v0.3 : Adaptation for kernel 2.1
-    v0.4 : Adaptation for joystick-1.2.6
-	   - added open/close callbacks
-    v0.5 : Renamed to "joy-console" because I have added
-	   PSX controller support.
-    v0.6 : NES support
-    v0.7V: Added "multi system" support
-    v0.8 : Bugfixed PSX driver...
-    v0.9V: Changed multi system support
-	   Added Multi2 support
-	   Fixed parport handling
-	   Cleaned up
-    v0.10: Fixed PSX buttons 7 and 8
+    v0.1  : First version (SNES only)
+    v0.2  : X/Y directions were exchanged...
+    v0.3  : Adaptation for kernel 2.1
+    v0.4  : Adaptation for joystick-1.2.6
+	    - added open/close callbacks
+    v0.5  : Renamed to "joy-console" because I have added
+	    PSX controller support.
+    v0.6  : NES support
+    v0.7V : Added "multi system" support
+    v0.8  : Bugfixed PSX driver...
+    v0.9V : Changed multi system support
+	    Added Multi2 support
+	    Fixed parport handling
+	    Cleaned up
+    v0.10 : Fixed PSX buttons 8 and 9
+    v0.11V: Switched to EXCL mode
+	    Removed wakeup
 
 3.2 joy-db9.c
 ~~~~~~~~~~~~~
@@ -478,6 +486,7 @@
 	  5  | Genesis pad (5+1 buttons)
 	  6  | Genesis pad (6+1 buttons)
 	  7  | Saturn pad
+	  8  | Multisystem 1-button joystick (v0.8.0.2 pin-out)
 
   Should you want to use more than one of these joysticks/pads at once, you
 can use js_db9_2 and js_db9_3 as additional command line parameters for two
@@ -489,6 +498,9 @@
     v0.3V: Added Sega Saturn support
 	   Fixed parport and PS/2 mode handling
 	   Cleaned up
+    v0.4V: Switched to EXCL mode
+           Removed wakeup
+    v0.5V: Added 0.8.0.2 HW compatibility for Multi sticks
 
 3.3 joy-turbografx.c
 ~~~~~~~~~~~~~~~~~~~~
@@ -506,9 +518,6 @@
   Should you want to use more than one of these interfaces at once, you can
 use js_tg_2 and js_tg_3 as additional command line parameters for two more
 interfaces.
-
-  Changes:
-    v0.1V: First version
 
 3.4 End
 ~~~~~~~
diff -u --recursive --new-file v2.1.125/linux/Documentation/joystick.txt linux/Documentation/joystick.txt
--- v2.1.125/linux/Documentation/joystick.txt	Fri Oct  9 13:27:04 1998
+++ linux/Documentation/joystick.txt	Wed Oct 21 08:43:33 1998
@@ -1,12 +1,9 @@
-		     Linux Joystick driver v1.2.11 BETA
+		     Linux Joystick driver v1.2.12
 	       (c) 1996-1998 Vojtech Pavlik <vojtech@ucw.cz>
 ----------------------------------------------------------------------------
 
 0. Disclaimer
 ~~~~~~~~~~~~~
-  This is a BETA release. It probably will work well for you, but it doesn't
-have to.
-
   This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the Free
 Software Foundation; either version 2 of the License, or (at your option)
@@ -25,7 +22,7 @@
 - mail your message to <vojtech@ucw.cz>, or by paper mail: Vojtech Pavlik,
 Ucitelska 1576, Prague 8, 182 00 Czech Republic
 
-  For your convenience, the GNU General Public Licens version 2 is included
+  For your convenience, the GNU General Public License version 2 is included
 in the package: See the file COPYING.
 
 1. Intro
@@ -36,19 +33,19 @@
   These currently include various analog joysticks (both variable resistor
 based and microswitch+resistor based), following IBM PC joystick standard,
 with extensions like additional hats and buttons compatible with CH
-Flightstick Pro, ThrustMaster FCS or PC 6 or 8 button gamepads.
+Flightstick Pro, ThrustMaster FCS or 6 and 8 button gamepads.
 
   In addition to these it also supports some of the new PC joysticks that
-use porprietary digital protocols to communicate over the gameport,
-currently by FPGaming, Genius, Gravis, Logitech, MadCatz and Microsoft.
-ThrustMaster and Creative Labs protocols are in the works.
+use proprietary digital protocols to communicate over the gameport,
+currently by FPGaming, Genius, Gravis, Logitech, MadCatz, Microsoft and
+ThrustMaster. Creative Labs protocol support is still to be done.
 
   The driver also includes support for many gamepads and joysticks that were
 used by various non-PC computers and game consoles. These include Multi
 system joysticks (Atari, Amiga, Commodore, Amstrad), Sega gamepads (Master
 System, Genesis, Saturn), Nintendo gamepads (NES, SNES), Sony gamepads (PSX).
 Support for N64, Atari Jaguar, Atari 2600, NES FourScore, SNES MultiTap,
-Pegasus, PSX NegCon and others might be added later.
+PSX NegCon and others might be added later.
 
   Last, but not least there is also native Amiga joystick support for the
 Amiga linux port.
@@ -92,24 +89,23 @@
 module at once, if you have more than one joystick installed.
 
   If you want to have the driver compiled into your kernel, you first need
-to patch the kernel. For that, use either kernel-2.0.35.patch, or
-kernel-2.1.115.patch files, that are included in the joystick package, and
-using the command
+to patch the kernel, so that it contains the current driver version. You do
+that with a command: 
 
-	patch -Esp1 < /usr/src/joystick-1.2.x/kernel-2.x.y.patch
+	patch -Esp1 < /usr/src/joystick-1.2.x/kernel-2.x.y.diff
 
 in
 
 	/usr/src/linux
 
-apply the patch to your kernel. To compile joystick support into the kernel,
-use the kernel configuration scripts, and answer 'Y' to Joystick support and
-also to at least one of the hardware specific options.
-
-  After patching the kernel you can also compile it as a module, answering
-'M' to all joystick support you want to have modules for. It is possible to
-have the main joystick driver compiled into the kernel and the hardware
-dependent drivers as modules.
+  To compile joystick support into the kernel, use the kernel configuration
+scripts, and answer 'Y' to Joystick support and also to at least one of the
+hardware specific options.
+
+  You can also compile the driver as modules, answering 'M' to all joystick
+support you want to have modules for. It is possible to have the main
+joystick driver compiled into the kernel and the hardware dependent drivers
+as modules.
 
   After you're done with installation of the driver itself, you'll need to
 create the joystick device files in /dev so that applications can use them.
@@ -128,7 +124,7 @@
 
 * 2-axis, 4-button joystick
 * 3-axis, 4-button joystick
-* Two 2-axis, 2-buttons joysticks on an Y-cable
+* Two 2-axis, 2-button joysticks on an Y-cable
 
   For other joystick types (more/less axes, hats, and buttons) support
 you'll need to specify the types either on the kernel command line or on the
@@ -155,12 +151,12 @@
 	 9  |   512 | CHF Hat 1
 	10  |  1024 | CHF Hat 2
 	11  |  2048 | FCS Hat
-	12  |  4096 | PXY Button X
-	13  |  8192 | PXY Button Y
-	14  | 16384 | PXY Button U
-	15  | 32768 | PXY Button V
+	12  |  4096 | Pad Button X
+	13  |  8192 | Pad Button Y
+	14  | 16384 | Pad Button U
+	15  | 32768 | Pad Button V
 
-(CHF = CH Flightstick Pro, FCS = ThrustMaster FCS, PXY - Pad with 6 or 8 buttons)
+(CHF = CH Flightstick Pro, FCS = ThrustMaster FCS)
 
   Following is a table of joysticks for which the 'm' values are known. If
 you have any additions/corrections to it, e-mail me.
@@ -176,6 +172,7 @@
 	Laing #1 PC SuperPad			| 0xf0f3
 	Microsoft SideWinder Standard		| 0x003b
 	QuickShot QS-201 SuperWarrior		| 0x00fb
+	Saitek Megapad XII			| 0x30f3
 
   In case you have one of the joystick in the table below, and it doesn't
 work with a specific driver in digital mode for some reason, you can use
@@ -470,9 +467,9 @@
   1.1.3		Leslie F. Donaldson	<donaldlf@cs.rose-hulman.edu>
   1.2.0		Eng-Jon Ong		<ongej@dcs.qmw.ac.uk>
   1.2.8		Ragnar Hojland Espinosa	<ragnar@lightside.ddns.org>
-  1.2.3-1.2.9	Andree Borrmann		<a.borrmann@tu-bs.de>
   1.1.0-1.2.9	Brian Gerst		<bgerst@quark.vpplus.com>
-  0.9.0-1.2.11	Vojtech Pavlik		<vojtech@ucw.cz>
+  1.2.3-1.2.12	Andree Borrmann		<a.borrmann@tu-bs.de>
+  0.9.0-1.2.12	Vojtech Pavlik		<vojtech@ucw.cz>
 
   If you think you should be in this list and are not, it's possible that
 I forgot to include you - contact me and I'll correct the error. :)
diff -u --recursive --new-file v2.1.125/linux/Documentation/mca.txt linux/Documentation/mca.txt
--- v2.1.125/linux/Documentation/mca.txt	Wed Jun 24 22:54:02 1998
+++ linux/Documentation/mca.txt	Sat Oct 17 15:33:45 1998
@@ -31,8 +31,7 @@
 		mca_set_adapter_name( slot, "adapter name & description" );
 		mca_set_adapter_procfn( slot, dev_getinfo, dev );
 
-		/* read the POS registers.  Most devices only need
-		2 and 3 */
+		/* read the POS registers.  Most devices only use 2 and 3 */
 		pos2 = mca_read_stored_pos( slot, 2 );
 		pos3 = mca_read_stored_pos( slot, 3 );
 		pos4 = mca_read_stored_pos( slot, 4 );
@@ -45,7 +44,8 @@
 
 Loadable modules should modify this to test that the specified IRQ and
 IO ports (plus whatever other stuff) match.  See 3c523.c for example
-code.
+code (actually, smc-mca.c has a slightly more complex example that can
+handle a list of adapter ids).
 
 Keep in mind that devices should never directly access the POS registers
 (via inb(), outb(), etc).  While it's generally safe, there is a small
@@ -57,11 +57,11 @@
 and mca_write_pos() are also available for (safer) direct POS access,
 but their use is _highly_ discouraged.  mca_write_pos() is particularly
 dangerous, as it is possible for adapters to be put in inconsistent
-states (e.g. sharing IO address, etc) and may result in crashes, toasted
-hardware, and operator injury.
+states (i.e. sharing IO address, etc) and may result in crashes, toasted
+hardware, and blindness.
 
-User level drivers (such as the AGX X server) can use /proc/mca to find
-adapters (see below).
+User level drivers (such as the AGX X server) can use /proc/mca/pos to
+find adapters (see below).
 
 Some MCA adapters can also be detected via the usual ISA-style device
 probing (many SCSI adapters, for example).  This sort of thing is highly
@@ -91,8 +91,8 @@
 /proc/mca
 =========
 
-I did a major rewrite of /proc/mca.  It is now a directory containing
-various files for adapters and other stuff.
+/proc/mca is a directory containing various files for adapters and
+other stuff.
 
 	/proc/mca/pos		Straight listing of POS registers
 	/proc/mca/slot[1-8]	Information on adapter in specific slot
@@ -100,6 +100,8 @@
 	/proc/mca/scsi		Same for integrated SCSI
 	/proc/mca/machine	Machine information
 
+See Appendix A for a sample.
+
 Device drivers can easily add their own information function for
 specific slots (including integrated ones) via the
 mca_set_adapter_procfn() call.  Drivers that support this are ESDI, IBM
@@ -132,10 +134,9 @@
 Disable it with:
 	mca_set_adapter_procfn( slot, NULL, NULL );
 
-It is also recommended, even if you don't write a proc function, to
-set the name of the adapter (e.g. "PS/2 ESDI Controller") via
-mca_set_adapter_name( int slot, char* name ).  Up to 30 characters are
-used.
+It is also recommended that, even if you don't write a proc function, to
+set the name of the adapter (i.e. "PS/2 ESDI Controller") via
+mca_set_adapter_name( int slot, char* name ).
 
 MCA Device Drivers
 ==================
@@ -146,65 +147,174 @@
 	drivers/block/ps2esdi.c
 	include/linux/ps2esdi.h
    Uses major number 36, and should use /dev files /dev/eda, /dev/edb.
-   Supports two drives, but only one controller.  Usually requires the
-   command-line args ed=cyl,head,sec
+   Supports two drives, but only one controller.  May use the
+   command-line args "ed=cyl,head,sec" and "tp720".
 
 2) PS/2 SCSI
 	drivers/scsi/ibmmca.c
 	drivers/scsi/ibmmca.h
    The driver for the IBM SCSI subsystem.  Includes both integrated
    controllers and adapter cards.  May require command-line arg
-   ibmmcascsi=pun to force detection of an adapter.
+   "ibmmcascsi=io_port" to force detection of an adapter.  If you have a
+   machine with a front-panel display (i.e. model 95), you can use
+   "ibmmcascsi=display" to enable a drive activity indicator.
 
 3) 3c523
 	drivers/net/3c523.c
 	drivers/net/3c523.h
-   3Com 3c523 Etherlink/MC Ethernet driver.
+   3Com 3c523 Etherlink/MC ethernet driver.
 
-4) SMC Ultra/MCA
+4) SMC Ultra/MCA and IBM Adapter/A
 	drivers/net/smc-mca.c
 	drivers/net/smc-mca.h
-	Elite/A (8013EP/A) and Elite10T/A (8013WP/A) Ethernet driver
+	Driver for the MCA version of the SMC Ultra and various other
+	OEM'ed and work-alike cards (Elite, Adapter/A, etc).
 
-As well, drivers/char/psaux.c was modified to support IRQ sharing (it's
-#ifdef CONFIG_MCA'ed, for your convenience, although PCI users might be
-able to use it...)
+5) NE/2
+	driver/net/ne2.c
+	driver/net/ne2.h
+	The NE/2 is the MCA version of the NE2000.  This may not work
+	with clones that have a different adapter id than the original
+	NE/2.
+
+6) Future Domain MCS-600/700, OEM'd IBM Fast SCSI Aapter/A and
+   Reply Sound Blaster/SCSI (SCSI part)
+	Better support for these cards than the driver for ISA.
+   Supports multiple cards with IRQ sharing.
+
+Also added boot time option of scsi-probe, which can do reordering of
+SCSI host adapters. This will direct the kernel on the order which
+SCSI adapter should be detected. Example:
+  scsi-probe=ibmmca,fd_mcs,adaptec1542,buslogic
 
 The serial drivers were modified to support the extended IO port range
 of the typical MCA system (also #ifdef CONFIG_MCA).
 
 The following devices work with existing drivers:
 1) Token-ring
-2) Future Domain SCSI (MCS-600, MCS-700, not MCS-350)
-3) Adaptec 1640 SCSI (aha1542 driver)
-4) Buslogic SCSI (various)
+2) Future Domain SCSI (MCS-600, MCS-700, not MCS-350, OEM'ed IBM SCSI)
+3) Adaptec 1640 SCSI (using the aha1542 driver)
+4) Bustek/Buslogic SCSI (various)
+5) Probably all Arcnet cards.
+6) Some, possibly all, MCA IDE controllers.
+7) 3Com 3c529 (MCA version of 3c509) (patched)
+
+8) Intel EtherExpressMC  (patched version)
+   You need to have CONFIG_MCA defined to have EtherExpressMC support.
+9) Reply Sound Blaster/SCSI (SB part) (patched version)
 
 Bugs & Other Weirdness
 ======================
 
 NMIs tend to occur with MCA machines because of various hardware
-weirdness, bus timeouts, and many other non-critical things.  Those of
-you who have NMI problems should probably set the CONFIG_IGNORE_NMI flag
-somewhere.  NMIs seem to be particularly common on the model 70.
-
-Various Pentium machines have serious problems with the FPU test in
-bugs.h.  You may need to comment out the FPU test before you can even
-boot.  This occurs, as far as we know, on the Pentium-equipped 85s, 95s,
-and some servers.  The PCI/MCA PC 750s are fine as far as I can tell.
+weirdness, bus timeouts, and many other non-critical things.  Some basic
+code to handle them (inspired by the NetBSD MCA code) has been added to
+detect the guilty device, but it's pretty incomplete.  If NMIs are a
+persistent problem (on some model 70 or 80s, they occur every couple
+shell commands), the CONFIG_IGNORE_NMI flag will take care of that.
+
+Various Pentium machines have had serious problems with the FPU test in
+bugs.h.  Basically, the machine hangs after the HLT test.  This occurs,
+as far as we know, on the Pentium-equipped 85s, 95s, and some PC Servers.
+The PCI/MCA PC 750s are fine as far as I can tell.  The ``mca-pentium''
+boot-prompt flag will disable the FPU bug check if this is a problem
+with your machine.
 
 The model 80 has a raft of problems that are just too weird and unique
 to get into here.  Some people have no trouble while others have nothing
-but problems.  I'd suspect the problems are related to the age of the
-average 80 and accompanying hardware deterioration.
+but problems.  I'd suspect some problems are related to the age of the
+average 80 and accompanying hardware deterioration, although others
+are definitely design problems with the hardware.  Among the problems
+include SCSI controller problems, ESDI controller problems, and serious
+screw-ups in the floppy controller.  Oh, and the parallel port is also
+pretty flaky.  There were about 5 or 6 different model 80 motherboards
+produced to fix various obscure problems.  As far as I know, it's pretty
+much impossible to tell which bugs a particular model 80 has (other than
+triggering them, that is).
+
+Drivers are required for some MCA memory adapters.  If you're suddenly
+short a few megs of RAM, this might be the reason.  The (I think) Enhanced
+Memory Adapter commonly found on the model 70 is one.  There's a very
+alpha driver floating around, but it's pretty ugly (disassembled from
+the DOS driver, actually).  See the MCA Linux web page (URL below)
+for more current memory info.
+
+The Thinkpad 700 and 720 will work, but various components are either
+non-functional, flaky, or we don't know anything about them.  The
+graphics controller is supposed to be some WD, but we can't get things
+working properly.  The PCMCIA slots don't seem to work.  Ditto for APM.
+The serial ports work, but detection seems to be flaky.
 
 Credits
 =======
 A whole pile of people have contributed to the MCA code.  I'd include
 their names here, but I don't have a list handy.  Check the MCA Linux
-home page (URL below) for an out-of-date list.
+home page (URL below) for a perpetually out-of-date list.
 
 =====================================================================
-http://glycerine.cetmm.uni.edu/mca
+MCA Linux Home Page: http://glycerine.itsmm.uni.edu/mca/
 
-Chris Beauregard
+Christophe Beauregard
 chrisb@truespectra.com
+cpbeaure@calum.csclub.uwaterloo.ca
+
+=====================================================================
+Appendix A: Sample /proc/mca
+
+This is from my model 8595.  Slot 1 contains the standard IBM SCSI
+adapter, slot 3 is an Adaptec AHA-1640, slot 5 is a XGA-1 video adapter,
+and slot 7 is the 3c523 Etherlink/MC.
+
+/proc/mca/machine:
+Model Id: 0xf8
+Submodel Id: 0x14
+BIOS Revision: 0x5
+
+/proc/mca/pos:
+Slot 1: ff 8e f1 fc a0 ff ff ff  IBM SCSI Adapter w/Cache
+Slot 2: ff ff ff ff ff ff ff ff  
+Slot 3: 1f 0f 81 3b bf b6 ff ff  
+Slot 4: ff ff ff ff ff ff ff ff  
+Slot 5: db 8f 1d 5e fd c0 00 00  
+Slot 6: ff ff ff ff ff ff ff ff  
+Slot 7: 42 60 ff 08 ff ff ff ff  3Com 3c523 Etherlink/MC
+Slot 8: ff ff ff ff ff ff ff ff  
+Video: ff ff ff ff ff ff ff ff  
+SCSI: ff ff ff ff ff ff ff ff  
+
+/proc/mca/slot1:
+Slot: 1
+Adapter Name: IBM SCSI Adapter w/Cache
+Id: 8eff
+Enabled: Yes
+POS: ff 8e f1 fc a0 ff ff ff 
+Subsystem PUN: 7
+Detected at boot: Yes
+
+/proc/mca/slot3:
+Slot: 3
+Adapter Name: Unknown
+Id: 0f1f
+Enabled: Yes
+POS: 1f 0f 81 3b bf b6 ff ff 
+
+/proc/mca/slot5:
+Slot: 5
+Adapter Name: Unknown
+Id: 8fdb
+Enabled: Yes
+POS: db 8f 1d 5e fd c0 00 00 
+
+/proc/mca/slot7:
+Slot: 7
+Adapter Name: 3Com 3c523 Etherlink/MC
+Id: 6042
+Enabled: Yes
+POS: 42 60 ff 08 ff ff ff ff 
+Revision: 0xe
+IRQ: 9
+IO Address: 0x3300-0x3308
+Memory: 0xd8000-0xdbfff
+Transceiver: External
+Device: eth0
+Hardware Address: 02 60 8c 45 c4 2a
diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/00-INDEX linux/Documentation/powerpc/00-INDEX
--- v2.1.125/linux/Documentation/powerpc/00-INDEX	Sat May  2 14:19:51 1998
+++ linux/Documentation/powerpc/00-INDEX	Sat Oct 10 09:53:24 1998
@@ -11,4 +11,5 @@
 	- use and state info about Linux/PPC on MP machines
 sound.txt
 	- info on sound support under Linux/PPC
-
+zImage_layout.txt
+	- info on the kernel images for Linux/PPC
diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/smp.txt linux/Documentation/powerpc/smp.txt
--- v2.1.125/linux/Documentation/powerpc/smp.txt	Thu Apr 23 20:21:27 1998
+++ linux/Documentation/powerpc/smp.txt	Sat Oct 10 09:53:24 1998
@@ -5,7 +5,7 @@
 (Cort Dougan, cort@cs.nmt.edu) please email me if you have questions,
 comments or corrections.
 
-Last Change: 4.1.98
+Last Change: 10.8.98
 
 SMP support for Linux/PPC is still in its early stages and likely to
 be buggy for a while.  If you want to help by writing code or testing
@@ -13,7 +13,7 @@
 
 1. State of Supported Hardware
 
-  PowerSurge Architecture - UMAX s900, Apple 9500/9600/8500/8600/7500/7600
+  PowerSurge Architecture - tested on UMAX s900, Apple 9600
     The second processor on this machine boots up just fine and
     enters its idle loop.  Hopefully a completely working SMP kernel
     on this machine will be done shortly.
@@ -22,7 +22,9 @@
     necessary to work with any number would not be overly difficult but
     I don't have any machines with >2 processors so it's not high on my
     list of priorities.  If anyone else would like do to the work email
-    me and I can point out the places that need changed.
+    me and I can point out the places that need changed.  If you have >2
+    processors and don't want to add support yourself let me know and I
+    can take a look into it.
 
   BeBox
     BeBox support hasn't been added to the 2.1.X kernels from 2.0.X
diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/sound.txt linux/Documentation/powerpc/sound.txt
--- v2.1.125/linux/Documentation/powerpc/sound.txt	Thu Apr 23 20:21:27 1998
+++ linux/Documentation/powerpc/sound.txt	Sat Oct 10 09:53:24 1998
@@ -1,7 +1,7 @@
             Information about PowerPC Sound support
 =====================================================================
 
-Please mail me me (Cort Dougan, cort@cs.nmt.edu) if you have questions,
+Please mail me (Cort Dougan, cort@cs.nmt.edu) if you have questions,
 comments or corrections.
 
 Last Change: 3.24.98
diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/zImage_layout.txt linux/Documentation/powerpc/zImage_layout.txt
--- v2.1.125/linux/Documentation/powerpc/zImage_layout.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/powerpc/zImage_layout.txt	Sat Oct 10 09:53:24 1998
@@ -0,0 +1,47 @@
+          Information about the Linux/PPC kernel images
+=====================================================================
+
+Please mail me me (Cort Dougan, cort@cs.nmt.edu) if you have questions,
+comments or corrections.
+
+This document is meant to answer several questions I've had about how
+the PReP system boots and how Linux/PPC interacts with that mechanism.
+It would be nice if we could have information on how other architectures
+boot here as well.  If you have anything to contribute, please
+let me know.
+
+
+1. PReP boot file
+
+  This is the file necessary to boot PReP systems from floppy or
+  hard drive.  The firmware reads the PReP partition table entry
+  and will load the image accordingly.
+
+  To boot the zImage, copy it onto a floppy with dd if=zImage of=/dev/fd0h1440
+  or onto a PReP hard drive partition with dd if=zImage of=/dev/sda4
+  assuming you've created a PReP partition (type 0x41) with fdisk on
+  /dev/sda4.
+
+  The layout of the image format is:
+
+  0x0     +------------+
+          |            | PReP partition table entry
+          |            |
+  0x400   +------------+
+          |            | Bootstrap program code + data
+          |            |
+          |            |
+          +------------+
+          |            | compressed kernel, elf header removed
+          +------------+
+          |            | initrd (if loaded)
+          +------------+
+          |            | Elf section table for bootstrap program
+          +------------+
+
+
+2. MBX boot file
+
+  The MBX boards can load an elf image, and relocate it to the
+  proper location in memory - it copies the image to the location it was
+  linked at.
diff -u --recursive --new-file v2.1.125/linux/Documentation/sound/MultiSound linux/Documentation/sound/MultiSound
--- v2.1.125/linux/Documentation/sound/MultiSound	Tue Aug 18 22:02:01 1998
+++ linux/Documentation/sound/MultiSound	Fri Oct  9 11:56:59 1998
@@ -1,180 +1,476 @@
-Getting Firmware
-~~~~~~~~~~~~~~~~
-
-See the end of this document on how to obtain and create the necessary
-firmware files.
-
-
-Supported Features
-~~~~~~~~~~~~~~~~~~
-
-Currently digital audio and mixer functionality is supported.  (memory
-mapped digital audio is not yet supported).  Modular MultiSound
-support is composed of the following modules:
-
-msnd		- MultiSound base (requires soundcore)
-msnd_classic	- Base audio/mixer support for Classic, Monetery and
-                  Tahiti cards
-msnd_pinnacle	- Base audio/mixer support for Pinnacle and Fiji cards
-
-
-Important Notes - Read Before Using
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-* The firmware files are not included (may change in future).  You
-must obtain these images from Turtle Beach (they are included in the
-MultiSound Development Kits), and place them in /etc/sound for
-example, and give the full paths in the Linux configuration.  Please
-note these files must be binary files, not assembler.
-
-* You need the following information to use this driver: the card's
-I/O base (i.e. 0x250), the IRQ (i.e. 5), and the shared memory area
-(i.e. 0xd8000).
-
-* Probing is not currently implemented, and only the msnd_classic
-driver will actually program the card's IRQ and SMA locations; the
-msnd_pinnacle is primarily for use with the card in PnP mode, however
-it should work if you know what the card's resource values are (this
-will change in the future).
-
-* Note the Turtle Beach Pinnacle card contains a Kurzweil MA-1
-synthesizer with an MPU compatible interface, which should work with
-the mpu401 module.  You must know the resource values of the MA-1.
-
-
-Examples
-~~~~~~~~
-
-* If you have a MultiSound Classic/Monterey/Tahiti:
-
-insmod soundcore
-insmod msnd
-insmod msnd_classic io=0x290 irq=7 mem=0xd0000
-
-* If you have a MultiSound Pinnacle:
-
-insmod soundcore
-insmod msnd
-insmod msnd_pinnacle io=0x210 irq=5 mem=0xd8000
-
-* To use the MPU-compatible Kurzweil synth on the Pinnacle, add the
-following:
-
-insmod sound
-insmod mpu401 io=0x330 irq=9
-
-
-msnd_classic, msnd_pinnacle Required Options
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If the following options are not given, the module will not load.
-Examine the kernel message log for informative error messages.
-WARNING--probing isn't supported so try to make sure you have the
-correct shared memory area, otherwise you may experience problems.
-
-io		        I/O base of DSP, e.g. io=0x210
-irq		        IRQ number, e.g. irq=5
-mem		        Shared memory area, e.g. mem=0xd8000
-
-
-msnd_classic, msnd_pinnacle Additional Options
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-fifosize		The digital audio FIFOs, in kilobytes.  The
-			default is 64kB (two FIFOs are allocated, so
-			this uses up 128kB).
-
-calibrate_signal	Setting this to one calibrates the ADCs to the
-			signal, zero calibrates to the card (defaults
-			to zero).
-
-
-msnd_pinnacle Additional Options
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-digital			Specify digital=1 to enable the S/PDIF input
-			if you have the digital daughterboard
-			adapter. This will enable access to the
-			DIGITAL1 input for the soundcard in the mixer.
-			Some mixer programs might have trouble setting
-			the DIGITAL1 source as an input.  If you have
-			trouble, you can try the setdigital.c program
-			at the bottom of this document.
-
-
-Obtaining and Creating Firmware Files
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	For the Classic/Tahiti/Monterey
-	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
-
-Download to /tmp and unzip the following file from Turtle Beach:
-
-	ftp://ftp.tbeach.com/pub/tbs/pinn/msndvkit.zip
-
-When unzipped, unzip the file named MsndFiles.zip.  Then copy the
-following firmware files to /etc/sound (note the file renaming):
-
-  cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin
-  cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin
-
-When configuring the Linux kernel, specify /etc/sound/msndinit.bin and
-/etc/sound/msndperm.bin for the two firmware files (Linux kernel
-versions older than 2.2 do not ask for firmware paths, and are
-hardcoded to /etc/sound).
-
-
-	For the Pinnacle/Fiji
-	~~~~~~~~~~~~~~~~~~~~~
-
-Download to /tmp and unzip the following file from Turtle Beach (be
-sure to use the entire URL; some have had trouble navigating to the
-URL):
-
-	ftp://ftp.tbeach.com/oldpub/tbs/pinn/pnddk100.zip
-
-Put the following lines into a file named conv.l (between the start
-and end lines):
-
--- conv.l start --
-%%
-[ \n\t,\r]
-\;.*
-DB
-[0-9A-Fa-f]+H	{ int n; sscanf(yytext, "%xH", &n); printf("%c", n); }
--- conv.l end --
-
-Then, compile the conv program with GNU make with the following
-command:
-
-  make LEX=flex LOADLIBES=-lfl conv
-
-This should give you an executable named conv.  Now, we create the
-binary firmware files by doing the following conversion (assuming the
-archive unpacked into a directory named PINNDDK):
-
-  ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin
-  ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin
-
-The conv (and conv.l) program is not needed after conversion and can
-be safely deleted.  Then, when configuring the Linux kernel, specify
-/etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two
-firmware files (Linux kernel versions older than 2.2 do not ask for
-firmware paths, and are hardcoded to /etc/sound).
-
-
-Recording from the S/PDIF Input
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you have a Pinnacle or Fiji with S/PDIF input and want to set it as
-the input source, you can use this program if you have trouble trying
-to do it with a mixer program (be sure to insert the module with the
-digital=1 option).
-
-Compile with:
-cc -O setdigital.c -o setdigital
-
--- start setdigital.c --
+#! /bin/sh
+#
+#  Turtle Beach MultiSound Driver Notes
+#  -- Andrew Veliath <andrewtv@usa.net>
+#
+#  Last update:                      September 10, 1998
+#  Corresponding msnd driver:        0.8.2
+#
+# ** This file is a README (top part) and shell archive (bottom part).
+#    The corresponding archived utility sources can be unpacked by
+#    running `sh MultiSound' (the utilities are only needed for the
+#    Pinnacle and Fiji cards). **
+#
+#
+#  -=-=- Getting Firmware -=-=-
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#  
+#  See the section `Obtaining and Creating Firmware Files' in this
+#  document for instructions on obtaining the necessary firmware
+#  files.
+#  
+#  
+#  Supported Features
+#  ~~~~~~~~~~~~~~~~~~
+#  
+#  Currently, full-duplex digital audio (/dev/dsp only, /dev/audio is
+#  not currently available) and mixer functionality (/dev/mixer) are
+#  supported (memory mapped digital audio is not yet supported).
+#  Digital transfers and monitoring can be done as well if you have
+#  the digital daughterboard (see the section on using the S/PDIF port
+#  for more information).
+#
+#  Support for the Turtle Beach MultiSound Hurricane architecture is
+#  composed of the following modules (these can also operate compiled
+#  into the kernel):
+#  
+#  msnd               - MultiSound base (requires soundcore)
+#
+#  msnd_classic       - Base audio/mixer support for Classic, Monetery and
+#                       Tahiti cards
+#
+#  msnd_pinnacle      - Base audio/mixer support for Pinnacle and Fiji cards
+#  
+#  
+#  Important Notes - Read Before Using
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#  
+#  The firmware files are not included (may change in future).  You
+#  must obtain these images from Turtle Beach (they are included in
+#  the MultiSound Development Kits), and place them in /etc/sound for
+#  example, and give the full paths in the Linux configuration.  If
+#  you are compiling in support for the MultiSound driver rather than
+#  using it as a module, these firmware files must be accessible
+#  during kernel compilation.
+#
+#  Please note these files must be binary files, not assembler.  See
+#  the section later in this document for instructions to obtain these
+#  files.
+#  
+#  
+#  Configuring Card Resources
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#  ** This section is very important, as your card may not work at all
+#     or your machine may crash if you do not do this correctly. **
+#
+#  * Classic/Monterey/Tahiti
+#  
+#  These cards are configured through the driver msnd_classic.  You must
+#  know the io port, then the driver will select the irq and memory resources
+#  on the card.  It is up to you to know if these are free locations or now,
+#  a conflict can lock the machine up.
+#
+#  * Pinnacle/Fiji
+#
+#  The Pinnacle and Fiji cards have an extra config port, either
+#  0x250, 0x260 or 0x270.  This port can be disabled to have the card
+#  configured strictly through PnP, however you lose the ability to
+#  access the IDE controller and joystick devices on this card when
+#  using PnP.  The included pinnaclecfg program in this shell archive
+#  can be used to configure the card in non-PnP mode, and in PnP mode
+#  you can use isapnptools.  These are described briefly here.
+#
+#  pinnaclecfg is not required; you can use the msnd_pinnacle module
+#  to fully configure the card as well.  However, pinnaclecfg can be
+#  used to change the resource values of a particular device after the
+#  msnd_pinnacle module has been loaded.  If you are compiling the
+#  driver into the kernel, you must set these values during compile
+#  time, however other peripheral resource values can be changed with
+#  the pinnaclecfg program after the kernel is loaded.
+#
+#
+#  *** PnP mode
+#  
+#  Use pnpdump to obtain a sample configuration if you can; I was able
+#  to obtain one with the command `pnpdump 1 0x203' -- this may vary
+#  for you (running pnpdump by itself did not work for me).  Then,
+#  edit this file and use isapnp to uncomment and set the card values.
+#  Use these values when inserting the msnd_pinnacle module.  Using
+#  this method, you can set the resources for the DSP and the Kurzweil
+#  synth (Pinnacle).  Since Linux does not directly support PnP
+#  devices, you may have difficulty when using the card in PnP mode
+#  when it the driver is compiled into the kernel.  Using non-PnP mode
+#  is preferable in this case.
+#
+#  Here is an example mypinnacle.conf for isapnp that sets the card to
+#  io base 0x210, irq 5 and mem 0xd8000, and also sets the Kurzweil
+#  synth to 0x330 and irq 9 (may need editing for your system):
+#
+#  (READPORT 0x0203)
+#  (CSN 2)
+#  (IDENTIFY *)
+#  
+#  # DSP
+#  (CONFIGURE BVJ0440/-1 (LD 0
+#          (INT 0 (IRQ 5 (MODE +E))) (IO 0 (BASE 0x0210)) (MEM 0 (BASE 0x0d8000))
+#          (ACT Y)))
+#  
+#  # Kurzweil Synth (Pinnacle Only)
+#  (CONFIGURE BVJ0440/-1 (LD 1
+#          (IO 0 (BASE 0x0330)) (INT 0 (IRQ 9 (MODE +E)))
+#          (ACT Y)))
+#  
+#  (WAITFORKEY)
+#
+#
+#  *** Non-PnP mode
+#  
+#  The second way is by running the card in non-PnP mode.  This
+#  actually has some advantages in that you can access some other
+#  devices on the card, such as the joystick and IDE controller.  To
+#  configure the card, unpack this shell archive and build the
+#  pinnaclecfg program.  Using this program, you can assign the
+#  resource values to the card's devices, or disable the devices.  As
+#  an alternative to using pinnaclecfg, you can specify many of the
+#  configuration values when loading the msnd_pinnacle module (or
+#  during kernel configuration when compiling the driver into the
+#  kernel).
+#
+#  If you specify cfg=0x250 for the msnd_pinnacle module, it
+#  automatically configure the card to the given io, irq and memory
+#  values using that config port (the config port is jumper selectable
+#  on the card to 0x250, 0x260 or 0x270).
+#
+#  See the `msnd_pinnacle Additional Options' section below for more
+#  information on these parameters (also, if you compile the driver
+#  directly into the kernel, these extra parameters can be useful
+#  here).
+#
+#
+# ** It is very easy to cause problems in your machine if you choose a
+#    resource value which is incorrect. **
+#  
+#
+#  Examples
+#  ~~~~~~~~
+#  
+#  * MultiSound Classic/Monterey/Tahiti:
+#  
+#  insmod soundcore
+#  insmod msnd
+#  insmod msnd_classic io=0x290 irq=7 mem=0xd0000
+#  
+#  * MultiSound Pinnacle in PnP mode:
+#  
+#  insmod soundcore
+#  insmod msnd
+#  isapnp mypinnacle.conf
+#  insmod msnd_pinnacle io=0x210 irq=5 mem=0xd8000 <-- match mypinnacle.conf values
+#  
+#  * MultiSound Pinnacle in non-PnP mode (replace 0x250 with your configuration port,
+#    one of 0x250, 0x260 or 0x270):
+#  
+#  insmod soundcore
+#  insmod msnd
+#  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000
+#  
+# * To use the MPU-compatible Kurzweil synth on the Pinnacle in PnP
+#   mode, add the following (assumes you did `isapnp mypinnacle.conf'):
+#  
+#  insmod sound
+#  insmod mpu401 io=0x330 irq=9                    <-- match mypinnacle.conf values
+#  
+# * To use the MPU-compatible Kurzweil synth on the Pinnacle in non-PnP
+#   mode, add the following.  Note how we first configure the peripheral's
+#   resources, _then_ install a Linux driver for it:
+#  
+#  insmod sound
+#  pinnaclecfg 0x250 mpu 0x330 9
+#  insmod mpu401 io=0x330 irq=9
+#
+#  -- OR you can use the following sequence without pinnaclecfg in non-PnP mode:
+#
+#  insmod soundcore
+#  insmod msnd
+#  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 mpu_io=0x330 mpu_irq=9
+#  insmod sound
+#  insmod mpu401 io=0x330 irq=9
+#
+# * To setup the joystick port on the Pinnacle in non-PnP mode (though
+#   you have to find the actual Linux joystick driver elsewhere), you
+#   can use pinnaclecfg:
+#
+#   pinnaclecfg 0x250 joystick 0x200
+#
+#  -- OR you can configure this using msnd_pinnacle with the following:
+#
+#  insmod soundcore
+#  insmod msnd
+#  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 joystick_io=0x200
+#
+#  
+#  msnd_classic, msnd_pinnacle Required Options
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#  
+#  If the following options are not given, the module will not load.
+#  Examine the kernel message log for informative error messages.
+#  WARNING--probing isn't supported so try to make sure you have the
+#  correct shared memory area, otherwise you may experience problems.
+#  
+#  io                   I/O base of DSP, e.g. io=0x210
+#  irq                  IRQ number, e.g. irq=5
+#  mem                  Shared memory area, e.g. mem=0xd8000
+#  
+#  
+#  msnd_classic, msnd_pinnacle Additional Options
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#  
+#  fifosize             The digital audio FIFOs, in kilobytes.  If not
+#                       specified, the default will be used.  Increasing
+#                       this value will reduce the chance of a FIFO
+#                       underflow at the expense of increasing overall
+#                       latency.  For example, fifosize=512 will
+#                       allocate 512kB read and write FIFOs (1MB total).
+#                       While this may reduce dropouts, a heavy machine
+#                       load will undoubtedly starve the FIFO of data
+#                       and you will eventually get dropouts.  One
+#                       option is to alter the scheduling priority of
+#                       the playback process, using `nice' or some form
+#                       of POSIX soft real-time scheduling.
+#
+#  calibrate_signal     Setting this to one calibrates the ADCs to the
+#                       signal, zero calibrates to the card (defaults
+#                       to zero).
+#  
+#  
+#  msnd_pinnacle Additional Options
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#  digital              Specify digital=1 to enable the S/PDIF input
+#                       if you have the digital daughterboard
+#                       adapter. This will enable access to the
+#                       DIGITAL1 input for the soundcard in the mixer.
+#                       Some mixer programs might have trouble setting
+#                       the DIGITAL1 source as an input.  If you have
+#                       trouble, you can try the setdigital.c program
+#                       at the bottom of this document.
+#
+#  cfg                  Non-PnP configuration port for the Pinnacle
+#                       and Fiji (typically 0x250, 0x260 or 0x270,
+#                       depending on the jumper configuration).  If
+#                       this option is omitted, then it is assumed
+#                       that the card is in PnP mode, and that the
+#                       specified DSP resource values are already
+#                       configured with PnP (i.e. it won't attempt to
+#                       do any sort of configuration).
+#
+#  When the Pinnacle is in non-PnP mode, you can use the following
+#  options to configure particular devices.  If a full specification
+#  for a device is not given, then the device is not configured.  Note
+#  that you still must use a Linux driver for any of these devices
+#  once their resources are setup (such as the Linux joystick driver,
+#  or the MPU401 driver from OSS for the Kurzweil synth).
+#
+#  mpu_io               I/O port of MPU (on-board Kurzweil synth)
+#  mpu_irq              IRQ of MPU (on-board Kurzweil synth)
+#  ide_io0		First I/O port of IDE controller
+#  ide_io1		Second I/O port of IDE controller
+#  ide_irq		IRQ IDE controller
+#  joystick_io          I/O port of joystick
+#  
+#  
+#  Obtaining and Creating Firmware Files
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#  
+#       For the Classic/Tahiti/Monterey
+#       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+#  
+#  Download to /tmp and unzip the following file from Turtle Beach:
+#  
+#       ftp://ftp.voyetra.com/pub/tbs/msndcl/msndvkit.zip
+#  
+#  When unzipped, unzip the file named MsndFiles.zip.  Then copy the
+#  following firmware files to /etc/sound (note the file renaming):
+#  
+#    cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin
+#    cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin
+#  
+#  When configuring the Linux kernel, specify /etc/sound/msndinit.bin and
+#  /etc/sound/msndperm.bin for the two firmware files (Linux kernel
+#  versions older than 2.2 do not ask for firmware paths, and are
+#  hardcoded to /etc/sound).
+#
+#  If you are compiling the driver into the kernel, these files must
+#  be accessible during compilation, but will not be needed later.
+#  The files must remain, however, if the driver is used as a module.
+#  
+#  
+#       For the Pinnacle/Fiji
+#       ~~~~~~~~~~~~~~~~~~~~~
+#  
+#  Download to /tmp and unzip the following file from Turtle Beach (be
+#  sure to use the entire URL; some have had trouble navigating to the
+#  URL):
+#  
+#       ftp://ftp.voyetra.com/pub/tbs/pinn/pnddk100.zip
+#
+#  Unpack this shell archive, and run make in the created directory
+#  (you need a C compiler and flex to build the utilities).  This
+#  should give you the executables conv, pinnaclecfg and setdigital.
+#  conv is only used temporarily here to create the firmware files,
+#  while pinnaclecfg is used to configure the Pinnacle or Fiji card in
+#  non-PnP mode, and setdigital can be used to set the S/PDIF input on
+#  the mixer (pinnaclecfg and setdigital should be copied to a
+#  convenient place, possibly run during system initialization).
+#
+#  To generating the firmware files with the `conv' program, we create
+#  the binary firmware files by doing the following conversion
+#  (assuming the archive unpacked into a directory named PINNDDK):
+#  
+#    ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin
+#    ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin
+#  
+#  The conv (and conv.l) program is not needed after conversion and can
+#  be safely deleted.  Then, when configuring the Linux kernel, specify
+#  /etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two
+#  firmware files (Linux kernel versions older than 2.2 do not ask for
+#  firmware paths, and are hardcoded to /etc/sound).
+#  
+#  If you are compiling the driver into the kernel, these files must
+#  be accessible during compilation, but will not be needed later.
+#  The files must remain, however, if the driver is used as a module.
+#
+#  
+#  Using Digital I/O with the S/PDIF Port
+#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#  If you have a Pinnacle or Fiji with the digital daughterboard and
+#  want to set it as the input source, you can use this program if you
+#  have trouble trying to do it with a mixer program (be sure to
+#  insert the module with the digital=1 option, or say Y to the option
+#  during compiled-in kernel operation).  Upon selection of the S/PDIF
+#  port, you should be able monitor and record from it.
+#
+#  There is something to note about using the S/PDIF port.  Digital
+#  timing is taken from the digital signal, so if a signal is not
+#  connected to the port and it is selected as recording input, you
+#  will find PCM playback to be distorted in playback rate.  Also,
+#  attempting to record at a sampling rate other than the DAT rate may
+#  be problematic (i.e. trying to record at 8000Hz when the DAT signal
+#  is 44100Hz).  If you have a problem with this, set the recording
+#  input to the line in if you need to record at a rate other than
+#  that of the DAT rate.
+#
+#
+#  -- Shell archive attached below, just run `sh MultiSound' to extract.
+#     Contains Pinnacle/Fiji utilities to convert firmware, configure
+#     in non-PnP mode, and select the DIGITAL1 input for the mixer.
+#
+#
+#!/bin/sh
+# This is a shell archive (produced by GNU sharutils 4.2).
+# To extract the files from this archive, save it to some FILE, remove
+# everything before the `!/bin/sh' line above, then type `sh FILE'.
+#
+# Made on 1998-09-05 08:26 EDT by <andrewtv@ztransform.velsoft.com>.
+# Source directory was `/home/andrewtv/programming/pinnacle/pinnacle'.
+#
+# Existing files will *not* be overwritten unless `-c' is specified.
+#
+# This shar contains:
+# length mode       name
+# ------ ---------- ------------------------------------------
+#   2111 -rw-rw-r-- MultiSound.d/setdigital.c
+#  10301 -rw-rw-r-- MultiSound.d/pinnaclecfg.c
+#     96 -rw-rw-r-- MultiSound.d/Makefile
+#    141 -rw-rw-r-- MultiSound.d/conv.l
+#
+save_IFS="${IFS}"
+IFS="${IFS}:"
+gettext_dir=FAILED
+locale_dir=FAILED
+first_param="$1"
+for dir in $PATH
+do
+  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
+     && ($dir/gettext --version >/dev/null 2>&1)
+  then
+    set `$dir/gettext --version 2>&1`
+    if test "$3" = GNU
+    then
+      gettext_dir=$dir
+    fi
+  fi
+  if test "$locale_dir" = FAILED && test -f $dir/shar \
+     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
+  then
+    locale_dir=`$dir/shar --print-text-domain-dir`
+  fi
+done
+IFS="$save_IFS"
+if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
+then
+  echo=echo
+else
+  TEXTDOMAINDIR=$locale_dir
+  export TEXTDOMAINDIR
+  TEXTDOMAIN=sharutils
+  export TEXTDOMAIN
+  echo="$gettext_dir/gettext -s"
+fi
+touch -am 1231235999 $$.touch >/dev/null 2>&1
+if test ! -f 1231235999 && test -f $$.touch; then
+  shar_touch=touch
+else
+  shar_touch=:
+  echo
+  $echo 'WARNING: not restoring timestamps.  Consider getting and'
+  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
+  echo
+fi
+rm -f 1231235999 $$.touch
+#
+if mkdir _sh21233; then
+  $echo 'x -' 'creating lock directory'
+else
+  $echo 'failed to create lock directory'
+  exit 1
+fi
+# ============= MultiSound.d/setdigital.c ==============
+if test ! -d 'MultiSound.d'; then
+  $echo 'x -' 'creating directory' 'MultiSound.d'
+  mkdir 'MultiSound.d'
+fi
+if test -f 'MultiSound.d/setdigital.c' && test "$first_param" != -c; then
+  $echo 'x -' SKIPPING 'MultiSound.d/setdigital.c' '(file already exists)'
+else
+  $echo 'x -' extracting 'MultiSound.d/setdigital.c' '(text)'
+  sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/setdigital.c' &&
+/*********************************************************************
+X *
+X * setdigital.c - sets the DIGITAL1 input for a mixer
+X *
+X * Copyright (C) 1998 Andrew Veliath
+X *
+X * This program is free software; you can redistribute it and/or modify
+X * it under the terms of the GNU General Public License as published by
+X * the Free Software Foundation; either version 2 of the License, or
+X * (at your option) any later version.
+X *
+X * This program is distributed in the hope that it will be useful,
+X * but WITHOUT ANY WARRANTY; without even the implied warranty of
+X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+X * GNU General Public License for more details.
+X *
+X * You should have received a copy of the GNU General Public License
+X * along with this program; if not, write to the Free Software
+X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+X *
+X * $Id: setdigital.c,v 1.1 1998/08/29 03:32:33 andrewtv Exp $
+X *
+X ********************************************************************/
+X
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -182,53 +478,586 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/soundcard.h>
-
+X
+int main(int argc, char *argv[])
+{
+X	int fd;
+X	unsigned long recmask, recsrc;
+X
+X	if (argc != 2) {
+X		fprintf(stderr, "usage: setdigital <mixer device>\n");
+X		exit(1);
+X	}
+X
+X	if ((fd = open(argv[1], O_RDWR)) < 0) {
+X		perror(argv[1]);
+X		exit(1);
+X	}
+X
+X	if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) {
+X		fprintf(stderr, "error: ioctl read recording mask failed\n");
+X		perror("ioctl");
+X		close(fd);
+X		exit(1);
+X	}
+X
+X	if (!(recmask & SOUND_MASK_DIGITAL1)) {
+X		fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n");
+X		close(fd);
+X		exit(1);
+X	}
+X
+X	if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) {
+X		fprintf(stderr, "error: ioctl read recording source failed\n");
+X		perror("ioctl");
+X		close(fd);
+X		exit(1);
+X	}
+X
+X	recsrc |= SOUND_MASK_DIGITAL1;
+X	
+X	if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) {
+X		fprintf(stderr, "error: ioctl write recording source failed\n");
+X		perror("ioctl");
+X		close(fd);
+X		exit(1);
+X	}
+X
+X	close(fd);
+X	
+X	return 0;
+}
+SHAR_EOF
+  $shar_touch -am 0828233298 'MultiSound.d/setdigital.c' &&
+  chmod 0664 'MultiSound.d/setdigital.c' ||
+  $echo 'restore of' 'MultiSound.d/setdigital.c' 'failed'
+  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
+  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
+    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
+    || $echo 'MultiSound.d/setdigital.c:' 'MD5 check failed'
+47720746d4367bae9954787c311c56fd  MultiSound.d/setdigital.c
+SHAR_EOF
+  else
+    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/setdigital.c'`"
+    test 2111 -eq "$shar_count" ||
+    $echo 'MultiSound.d/setdigital.c:' 'original size' '2111,' 'current size' "$shar_count!"
+  fi
+fi
+# ============= MultiSound.d/pinnaclecfg.c ==============
+if test -f 'MultiSound.d/pinnaclecfg.c' && test "$first_param" != -c; then
+  $echo 'x -' SKIPPING 'MultiSound.d/pinnaclecfg.c' '(file already exists)'
+else
+  $echo 'x -' extracting 'MultiSound.d/pinnaclecfg.c' '(text)'
+  sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/pinnaclecfg.c' &&
+/*********************************************************************
+X *
+X * pinnaclecfg.c - Pinnacle/Fiji Device Configuration Program
+X *
+X * This is for NON-PnP mode only.  For PnP mode, use isapnptools.
+X *
+X * This is Linux-specific, and must be run with root permissions.
+X *
+X * Part of the Turtle Beach MultiSound Sound Card Driver for Linux
+X *
+X * Copyright (C) 1998 Andrew Veliath
+X *
+X * This program is free software; you can redistribute it and/or modify
+X * it under the terms of the GNU General Public License as published by
+X * the Free Software Foundation; either version 2 of the License, or
+X * (at your option) any later version.
+X *
+X * This program is distributed in the hope that it will be useful,
+X * but WITHOUT ANY WARRANTY; without even the implied warranty of
+X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+X * GNU General Public License for more details.
+X *
+X * You should have received a copy of the GNU General Public License
+X * along with this program; if not, write to the Free Software
+X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+X *
+X * $Id: pinnaclecfg.c,v 1.3 1998/08/29 03:32:32 andrewtv Exp $
+X *
+X ********************************************************************/
+X
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <asm/io.h>
+#include <asm/types.h>
+X
+#define IREG_LOGDEVICE		0x07
+#define IREG_ACTIVATE		0x30
+#define LD_ACTIVATE		0x01
+#define LD_DISACTIVATE		0x00
+#define IREG_EECONTROL		0x3F
+#define IREG_MEMBASEHI		0x40
+#define IREG_MEMBASELO		0x41
+#define IREG_MEMCONTROL		0x42
+#define IREG_MEMRANGEHI		0x43
+#define IREG_MEMRANGELO		0x44
+#define MEMTYPE_8BIT		0x00
+#define MEMTYPE_16BIT		0x02
+#define MEMTYPE_RANGE		0x00
+#define MEMTYPE_HIADDR		0x01
+#define IREG_IO0_BASEHI		0x60
+#define IREG_IO0_BASELO		0x61
+#define IREG_IO1_BASEHI		0x62
+#define IREG_IO1_BASELO		0x63
+#define IREG_IRQ_NUMBER		0x70
+#define IREG_IRQ_TYPE		0x71
+#define IRQTYPE_HIGH		0x02
+#define IRQTYPE_LOW		0x00
+#define IRQTYPE_LEVEL		0x01
+#define IRQTYPE_EDGE		0x00
+X
+#define HIBYTE(w)		((BYTE)(((WORD)(w) >> 8) & 0xFF))
+#define LOBYTE(w)		((BYTE)(w))
+#define MAKEWORD(low,hi)	((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8)))
+X
+typedef __u8			BYTE;
+typedef __u16			USHORT;
+typedef __u16			WORD;
+X
+static int config_port = -1;
+X
+static int msnd_write_cfg(int cfg, int reg, int value)
+{
+X	outb(reg, cfg);
+X	outb(value, cfg + 1);
+X	if (value != inb(cfg + 1)) {
+X		fprintf(stderr, "error: msnd_write_cfg: I/O error\n");
+X		return -EIO;
+X	}
+X	return 0;
+}
+X
+static int msnd_read_cfg(int cfg, int reg)
+{
+X	outb(reg, cfg);
+X	return inb(cfg + 1);
+}
+X
+static int msnd_write_cfg_io0(int cfg, int num, WORD io)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
+X		return -EIO;
+X	return 0;
+}
+X
+static int msnd_read_cfg_io0(int cfg, int num, WORD *io)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	
+X	*io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO0_BASELO),
+X		       msnd_read_cfg(cfg, IREG_IO0_BASEHI));
+X
+X	return 0;
+}
+X
+static int msnd_write_cfg_io1(int cfg, int num, WORD io)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
+X		return -EIO;
+X	return 0;
+}
+X
+static int msnd_read_cfg_io1(int cfg, int num, WORD *io)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	
+X	*io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO1_BASELO),
+X		       msnd_read_cfg(cfg, IREG_IO1_BASEHI));
+X
+X	return 0;
+}
+X
+static int msnd_write_cfg_irq(int cfg, int num, WORD irq)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
+X		return -EIO;
+X	return 0;
+}
+X
+static int msnd_read_cfg_irq(int cfg, int num, WORD *irq)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	
+X	*irq = msnd_read_cfg(cfg, IREG_IRQ_NUMBER);
+X
+X	return 0;
+}
+X
+static int msnd_write_cfg_mem(int cfg, int num, int mem)
+{
+X	WORD wmem;
+X
+X	mem >>= 8;
+X	mem &= 0xfff;
+X	wmem = (WORD)mem;
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
+X		return -EIO;
+X	if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT)))
+X		return -EIO;
+X	return 0;
+}
+X
+static int msnd_read_cfg_mem(int cfg, int num, int *mem)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	
+X	*mem = MAKEWORD(msnd_read_cfg(cfg, IREG_MEMBASELO),
+X			msnd_read_cfg(cfg, IREG_MEMBASEHI));
+X	*mem <<= 8;
+X
+X	return 0;
+}
+X
+static int msnd_activate_logical(int cfg, int num)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
+X		return -EIO;
+X	return 0;
+}
+X
+static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	if (msnd_write_cfg_io0(cfg, num, io0))
+X		return -EIO;
+X	if (msnd_write_cfg_io1(cfg, num, io1))
+X		return -EIO;
+X	if (msnd_write_cfg_irq(cfg, num, irq))
+X		return -EIO;
+X	if (msnd_write_cfg_mem(cfg, num, mem))
+X		return -EIO;
+X	if (msnd_activate_logical(cfg, num))
+X		return -EIO;
+X	return 0;
+}
+X
+static int msnd_read_cfg_logical(int cfg, int num, WORD *io0, WORD *io1, WORD *irq, int *mem)
+{
+X	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
+X		return -EIO;
+X	if (msnd_read_cfg_io0(cfg, num, io0))
+X		return -EIO;
+X	if (msnd_read_cfg_io1(cfg, num, io1))
+X		return -EIO;
+X	if (msnd_read_cfg_irq(cfg, num, irq))
+X		return -EIO;
+X	if (msnd_read_cfg_mem(cfg, num, mem))
+X		return -EIO;
+X	return 0;
+}
+X
+static void usage(void)
+{
+X	fprintf(stderr,
+X		"\n"
+X		"pinnaclecfg 1.0\n"
+X		"\n"
+X		"usage: pinnaclecfg <config port> [device config]\n"
+X		"\n"
+X		"This is for use with the card in NON-PnP mode only.\n"
+X		"\n"
+X		"Available devices (not all available for Fiji):\n"
+X		"\n"
+X		"        Device                       Description\n"
+X		"        -------------------------------------------------------------------\n"
+X		"        reset                        Reset all devices (i.e. disable)\n"
+X		"        show                         Display current device configurations\n"
+X		"\n"
+X		"        dsp <io> <irq> <mem>         Audio device\n"
+X		"        mpu <io> <irq>               Internal Kurzweil synth\n"
+X		"        ide <io0> <io1> <irq>        On-board IDE controller\n"
+X		"        joystick <io>                Joystick port\n"
+X		"\n");
+X	exit(1);
+}
+X
+static int cfg_reset(void)
+{
+X	int i;
+X
+X	for (i = 0; i < 4; ++i)
+X		msnd_write_cfg_logical(config_port, i, 0, 0, 0, 0);
+X	
+X	return 0;
+}
+X
+static int cfg_show(void)
+{
+X	int i;
+X	int count = 0;
+X
+X	for (i = 0; i < 4; ++i) {
+X		WORD io0, io1, irq;
+X		int mem;
+X		msnd_read_cfg_logical(config_port, i, &io0, &io1, &irq, &mem);
+X		switch (i) {
+X		case 0:
+X			if (io0 || irq || mem) {
+X				printf("dsp 0x%x %d 0x%x\n", io0, irq, mem);
+X				++count;
+X			}
+X			break;
+X		case 1:
+X			if (io0 || irq) {
+X				printf("mpu 0x%x %d\n", io0, irq);
+X				++count;
+X			}
+X			break;
+X		case 2:
+X			if (io0 || io1 || irq) {
+X				printf("ide 0x%x 0x%x %d\n", io0, io1, irq);
+X				++count;
+X			}
+X			break;
+X		case 3:
+X			if (io0) {
+X				printf("joystick 0x%x\n", io0);
+X				++count;
+X			}
+X			break;
+X		}
+X	}
+X
+X	if (count == 0)
+X		fprintf(stderr, "no devices configured\n");
+X	
+X	return 0;
+}
+X
+static int cfg_dsp(int argc, char *argv[])
+{
+X	int io, irq, mem;
+X
+X	if (argc < 3 ||
+X	    sscanf(argv[0], "0x%x", &io) != 1 ||
+X	    sscanf(argv[1], "%d", &irq) != 1 ||
+X	    sscanf(argv[2], "0x%x", &mem) != 1)
+X		usage();
+X
+X	if (!(io == 0x290 ||
+X	      io == 0x260 ||
+X	      io == 0x250 ||
+X	      io == 0x240 ||
+X	      io == 0x230 ||
+X	      io == 0x220 ||
+X	      io == 0x210 ||
+X	      io == 0x3e0)) {
+X		fprintf(stderr, "error: io must be one of "
+X			"210, 220, 230, 240, 250, 260, 290, or 3E0\n");
+X		usage();
+X	}
+X	
+X	if (!(irq == 5 ||
+X	      irq == 7 ||
+X	      irq == 9 ||
+X	      irq == 10 ||
+X	      irq == 11 ||
+X	      irq == 12)) {
+X		fprintf(stderr, "error: irq must be one of "
+X			"5, 7, 9, 10, 11 or 12\n");
+X		usage();
+X	}
+X
+X	if (!(mem == 0xb0000 ||
+X	      mem == 0xc8000 ||
+X	      mem == 0xd0000 ||
+X	      mem == 0xd8000 ||
+X	      mem == 0xe0000 ||
+X	      mem == 0xe8000)) {
+X		fprintf(stderr, "error: mem must be one of "
+X			"0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
+X		usage();
+X	}
+X
+X	return msnd_write_cfg_logical(config_port, 0, io, 0, irq, mem);
+}
+X
+static int cfg_mpu(int argc, char *argv[])
+{
+X	int io, irq;
+X
+X	if (argc < 2 ||
+X	    sscanf(argv[0], "0x%x", &io) != 1 ||
+X	    sscanf(argv[1], "%d", &irq) != 1)
+X		usage();
+X	
+X	return msnd_write_cfg_logical(config_port, 1, io, 0, irq, 0);
+}
+X
+static int cfg_ide(int argc, char *argv[])
+{
+X	int io0, io1, irq;
+X
+X	if (argc < 3 ||
+X	    sscanf(argv[0], "0x%x", &io0) != 1 ||
+X	    sscanf(argv[0], "0x%x", &io1) != 1 ||
+X	    sscanf(argv[1], "%d", &irq) != 1)
+X		usage();
+X	
+X	return msnd_write_cfg_logical(config_port, 2, io0, io1, irq, 0);
+}
+X
+static int cfg_joystick(int argc, char *argv[])
+{
+X	int io;
+X
+X	if (argc < 1 ||
+X	    sscanf(argv[0], "0x%x", &io) != 1)
+X		usage();
+X	
+X	return msnd_write_cfg_logical(config_port, 3, io, 0, 0, 0);
+}
+X
 int main(int argc, char *argv[])
 {
-	int fd;
-	unsigned long recmask, recsrc;
-
-	if (argc != 2) {
-		fprintf(stderr, "usage: setdigital <mixer device>\n");
-		exit(1);
-	} else
-
-	if ((fd = open(argv[1], O_RDWR)) < 0) {
-		perror(argv[1]);
-		exit(1);
-	}
-
-	if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) {
-		fprintf(stderr, "error: ioctl read recmask failed\n");
-		perror("ioctl");
-		close(fd);
-		exit(1);
-	}
-
-	if (!(recmask & SOUND_MASK_DIGITAL1)) {
-		fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n");
-		close(fd);
-		exit(1);
-	}
-
-	if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) {
-		fprintf(stderr, "error: ioctl read recsrc failed\n");
-		perror("ioctl");
-		close(fd);
-		exit(1);
-	}
-
-	recsrc |= SOUND_MASK_DIGITAL1;
-	
-	if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) {
-		fprintf(stderr, "error: ioctl write recsrc failed\n");
-		perror("ioctl");
-		close(fd);
-		exit(1);
-	}
-
-	close(fd);
-	
-	return 0;
+X	char *device;
+X	int rv = 0;
+X
+X	--argc; ++argv;
+X
+X	if (argc < 2)
+X		usage();
+X
+X	sscanf(argv[0], "0x%x", &config_port);
+X	if (config_port != 0x250 && config_port != 0x260 && config_port != 0x270) {
+X		fprintf(stderr, "error: <config port> must be 0x250, 0x260 or 0x270\n");
+X		exit(1);
+X	}
+X	if (ioperm(config_port, 2, 1)) {
+X		perror("ioperm");
+X		fprintf(stderr, "note: pinnaclecfg must be run as root\n");
+X		exit(1);
+X	}
+X	device = argv[1];
+X
+X	argc -= 2; argv += 2;
+X
+X	if (strcmp(device, "reset") == 0)
+X		rv = cfg_reset();
+X	else if (strcmp(device, "show") == 0)
+X		rv = cfg_show();
+X	else if (strcmp(device, "dsp") == 0)
+X		rv = cfg_dsp(argc, argv);
+X	else if (strcmp(device, "mpu") == 0)
+X		rv = cfg_mpu(argc, argv);
+X	else if (strcmp(device, "ide") == 0)
+X		rv = cfg_ide(argc, argv);
+X	else if (strcmp(device, "joystick") == 0)
+X		rv = cfg_joystick(argc, argv);
+X	else {
+X		fprintf(stderr, "error: unknown device %s\n", device);
+X		usage();
+X	}
+X
+X	if (rv)
+X		fprintf(stderr, "error: device configuration failed\n");
+X	
+X	return 0;
 }
--- end setdigital.c --
+SHAR_EOF
+  $shar_touch -am 0905082598 'MultiSound.d/pinnaclecfg.c' &&
+  chmod 0664 'MultiSound.d/pinnaclecfg.c' ||
+  $echo 'restore of' 'MultiSound.d/pinnaclecfg.c' 'failed'
+  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
+  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
+    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
+    || $echo 'MultiSound.d/pinnaclecfg.c:' 'MD5 check failed'
+71f99b834a2845daae8ae034623e313e  MultiSound.d/pinnaclecfg.c
+SHAR_EOF
+  else
+    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/pinnaclecfg.c'`"
+    test 10301 -eq "$shar_count" ||
+    $echo 'MultiSound.d/pinnaclecfg.c:' 'original size' '10301,' 'current size' "$shar_count!"
+  fi
+fi
+# ============= MultiSound.d/Makefile ==============
+if test -f 'MultiSound.d/Makefile' && test "$first_param" != -c; then
+  $echo 'x -' SKIPPING 'MultiSound.d/Makefile' '(file already exists)'
+else
+  $echo 'x -' extracting 'MultiSound.d/Makefile' '(text)'
+  sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/Makefile' &&
+CC	= gcc
+CFLAGS	= -O
+PROGS	= setdigital pinnaclecfg conv
+X
+all: $(PROGS)
+X
+clean:
+X	rm -f $(PROGS)
+SHAR_EOF
+  $shar_touch -am 0828231798 'MultiSound.d/Makefile' &&
+  chmod 0664 'MultiSound.d/Makefile' ||
+  $echo 'restore of' 'MultiSound.d/Makefile' 'failed'
+  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
+  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
+    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
+    || $echo 'MultiSound.d/Makefile:' 'MD5 check failed'
+ab95a049d10611a5e5d559a56965b33f  MultiSound.d/Makefile
+SHAR_EOF
+  else
+    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/Makefile'`"
+    test 96 -eq "$shar_count" ||
+    $echo 'MultiSound.d/Makefile:' 'original size' '96,' 'current size' "$shar_count!"
+  fi
+fi
+# ============= MultiSound.d/conv.l ==============
+if test -f 'MultiSound.d/conv.l' && test "$first_param" != -c; then
+  $echo 'x -' SKIPPING 'MultiSound.d/conv.l' '(file already exists)'
+else
+  $echo 'x -' extracting 'MultiSound.d/conv.l' '(text)'
+  sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/conv.l' &&
+%%
+[ \n\t,\r]
+\;.*
+DB
+[0-9A-Fa-f]+H	{ int n; sscanf(yytext, "%xH", &n); printf("%c", n); }
+%%
+int yywrap() { return 1; }
+main() { yylex(); }
+SHAR_EOF
+  $shar_touch -am 0828231798 'MultiSound.d/conv.l' &&
+  chmod 0664 'MultiSound.d/conv.l' ||
+  $echo 'restore of' 'MultiSound.d/conv.l' 'failed'
+  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
+  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
+    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
+    || $echo 'MultiSound.d/conv.l:' 'MD5 check failed'
+d2411fc32cd71a00dcdc1f009e858dd2  MultiSound.d/conv.l
+SHAR_EOF
+  else
+    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/conv.l'`"
+    test 141 -eq "$shar_count" ||
+    $echo 'MultiSound.d/conv.l:' 'original size' '141,' 'current size' "$shar_count!"
+  fi
+fi
+rm -fr _sh21233
+exit 0
diff -u --recursive --new-file v2.1.125/linux/Documentation/stallion.txt linux/Documentation/stallion.txt
--- v2.1.125/linux/Documentation/stallion.txt	Wed Jun 24 22:54:02 1998
+++ linux/Documentation/stallion.txt	Fri Oct 23 08:26:03 1998
@@ -4,8 +4,8 @@
 
 Copyright (C) 1994-1998,  Stallion Technologies (support@stallion.com).
 
-Version:   5.4.6
-Date:      23JUN98
+Version:   5.4.7
+Date:      23OCT98
 
 
 
diff -u --recursive --new-file v2.1.125/linux/MAINTAINERS linux/MAINTAINERS
--- v2.1.125/linux/MAINTAINERS	Fri Oct  9 13:27:04 1998
+++ linux/MAINTAINERS	Tue Oct 20 14:17:45 1998
@@ -16,7 +16,8 @@
 	SMC etherpower for that.)
 
 3.	Make sure your changes compile correctly in multiple
-	configurations.
+	configurations. In paticular check changes work both as a module
+	and built into the kernel.
 
 4.	When you are happy with a change make it generally available for
 	testing and await feedback.
@@ -28,7 +29,8 @@
 	job the maintainers (and especially Linus) do is to keep things
 	looking the same. Sometimes this means that the clever hack in
 	your driver to get around a problem actual needs to become a
-	generalized kernel feature ready for next time.
+	generalized kernel feature ready for next time. See 
+	Documentation/CodingStyle for guidance here.
 
 	PLEASE try to include any credit lines you want added with the
 	patch. It avoids people being missed off by mistake and makes
@@ -240,6 +242,11 @@
 L:	linux-net@vger.rutgers.edu
 S:	Maintained
 
+ETHERTEAM 16I DRIVER
+P:      Mika Kuoppala
+M:      miku@iki.fi
+S:      Maintained
+
 EXT2 FILE SYSTEM
 P:	Remy Card
 M:	Remy.Card@linux.org
@@ -303,6 +310,12 @@
 L:	linux-hams@vger.rutgers.edu
 S:	Maintained
 
+HIPPI
+P:	Jes Sorensen
+M:	Jes.Sorensen@cern.ch
+L:	linux-hippi@sunsite.auc.dk
+S:	Maintained
+
 HP100:	Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
 P:	Jaroslav Kysela
 M:	perex@jcu.cz
@@ -484,9 +497,7 @@
 P:	Andrea Arcangeli
 M:	andrea@e-mind.com
 L:	linux-parport@torque.net
-L:	pnp-list@redhat.com
 W:	http://www.cyberelk.demon.co.uk/parport.html
-W:	http://www.cage.curtin.edu.au/~campbell/parbus/
 S:	Maintained
 
 PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES
@@ -702,6 +713,12 @@
 L:	linux-x25@vger.rutgers.edu
 S:	Maintained
 
+Z85230 SYNCHRONOUS DRIVER
+P:	Alan Cox
+M:	alan@redhat.com
+W:	http://roadrunner.swansea.linux.org.uk/synchronous.shtml
+S:	Maintained
+
 Z8530 DRIVER FOR AX.25
 P:	Joerg Reuter
 M:	jreuter@poboxes.com
@@ -709,7 +726,6 @@
 W:	http://qsl.net/dl1bke/
 L:	linux-hams@vger.rutgers.edu
 S:	Maintained
-
 
 REST:
 P:	Linus Torvalds
diff -u --recursive --new-file v2.1.125/linux/Makefile linux/Makefile
--- v2.1.125/linux/Makefile	Fri Oct  9 13:27:04 1998
+++ linux/Makefile	Fri Oct 16 20:33:22 1998
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 125
+SUBLEVEL = 126
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -u --recursive --new-file v2.1.125/linux/README linux/README
--- v2.1.125/linux/README	Tue Aug 18 22:02:01 1998
+++ linux/README	Sat Oct 10 10:30:35 1998
@@ -96,15 +96,6 @@
    the current directory, but an alternative directory can be specified
    as the second argument.
 
- - Make sure your /usr/include/asm, /usr/include/linux, and /usr/include/scsi
-   directories are just symlinks to the kernel sources:
-
-		cd /usr/include
-		rm -rf asm linux scsi
-		ln -s /usr/src/linux/include/asm-i386 asm
-		ln -s /usr/src/linux/include/linux linux
-		ln -s /usr/src/linux/include/scsi scsi
-
  - Make sure you have no stale .o files and dependencies lying around:
 
 		cd /usr/src/linux
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/Makefile linux/arch/alpha/Makefile
--- v2.1.125/linux/arch/alpha/Makefile	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/Makefile	Mon Oct 12 11:40:12 1998
@@ -19,17 +19,23 @@
 # Determine if GCC understands the -mcpu= option.
 have_mcpu := $(shell if $(CC) -mcpu=ev5 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
 
-# If GENERIC, make sure to turn off any instruction set extensions that
-# the host compiler might have on by default.  Given that EV4 and EV5
-# have the same instruction set, prefer EV5 because an EV5 schedule is
-# more likely to keep an EV4 processor busy than vice-versa.
-ifeq ($(CONFIG_ALPHA_GENERIC)$(have_mcpu),yy)
- CFLAGS := $(CFLAGS) -mcpu=ev5
-endif
-
-# If EV6, turn on the proper optimizations.
-ifeq ($(CONFIG_ALPHA_EV6)$(have_mcpu),yy)
- CFLAGS := $(CFLAGS) -mcpu=ev6
+# Turn on the proper cpu optimizations.
+ifeq ($(have_mcpu),y)
+  # If GENERIC, make sure to turn off any instruction set extensions that
+  # the host compiler might have on by default.  Given that EV4 and EV5
+  # have the same instruction set, prefer EV5 because an EV5 schedule is
+  # more likely to keep an EV4 processor busy than vice-versa.
+  ifeq ($(CONFIG_ALPHA_GENERIC),y)
+    CFLAGS := $(CFLAGS) -mcpu=ev5
+  endif
+  ifeq ($(CONFIG_ALPHA_EV4),y)
+    CFLAGS := $(CFLAGS) -mcpu=ev4
+  endif
+  # Leave out EV5, since it is too hard to figure out whether we
+  # should use EV56 insns or not.
+  ifeq ($(CONFIG_ALPHA_EV6),y)
+    CFLAGS := $(CFLAGS) -mcpu=ev6
+  endif
 endif
 
 # For TSUNAMI, we must have the assembler not emulate our instructions.
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile
--- v2.1.125/linux/arch/alpha/boot/Makefile	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/boot/Makefile	Mon Oct 12 11:40:12 1998
@@ -36,7 +36,10 @@
 	tools/mkbb bootimage tools/lxboot
 
 bootpfile:	tools/bootph vmlinux.nh
-	( cat tools/bootph vmlinux.nh ) > bootpfile
+	cat tools/bootph vmlinux.nh > bootpfile
+ifdef INITRD
+	cat $(INITRD) >> bootpfile
+endif
 
 srmboot:	bootdevice bootimage
 	dd if=bootimage of=$(BOOTDEV) bs=512 seek=1 skip=1
@@ -48,15 +51,18 @@
 vmlinux.gz: vmlinux
 	gzip -fv9 vmlinux
 
-#
-# A raw binary without header.  Used by raw boot.
-#
 main.o: ksize.h
 
 bootp.o: ksize.h
 
-ksize.h: $(OBJSTRIP) vmlinux.nh
-	echo "#define KERNEL_SIZE `$(OBJSTRIP) -p vmlinux.nh /dev/null`" > $@
+ksize.h: vmlinux.nh dummy
+	echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T
+ifdef INITRD
+	[ -f $(INITRD) ] || exit 1
+	echo "#define INITRD_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
+endif
+	cmp -s $@T $@ || mv -f $@T $@
+	rm -f $@T
 
 vmlinux.nh: $(VMLINUX) $(OBJSTRIP)
 	$(OBJSTRIP) -v $(VMLINUX) vmlinux.nh
@@ -91,3 +97,5 @@
 	rm -f vmlinux.nh ksize.h
 
 dep:
+
+dummy:
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/boot/bootp.c linux/arch/alpha/boot/bootp.c
--- v2.1.125/linux/arch/alpha/boot/bootp.c	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/boot/bootp.c	Mon Oct 12 11:40:12 1998
@@ -22,74 +22,30 @@
 
 #include "ksize.h"
 
-extern int vsprintf(char *, const char *, va_list);
 extern unsigned long switch_to_osf_pal(unsigned long nr,
 	struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
-	unsigned long vptb, unsigned long *kstk);
+	unsigned long *vptb);
 
-extern long dispatch(long code, ...);
-
-static void
-puts(const char *str, int len)
-{
-	long written;
-
-	while (len > 0) {
-		written = dispatch(CCB_PUTS, 0, str, len);
-		if (written < 0)
-			break;
-		len -= (unsigned int) written;
-		str += (unsigned int) written;
-	}
-}
-
-int printk(const char * fmt, ...)
-{
-	va_list args;
-	int i, j, remaining, num_nl;
-	static char buf[1024];
-
-	va_start(args, fmt);
-	i = vsprintf(buf, fmt, args);
-	va_end(args);
-
-	/* expand \n into \r\n: */
-
-	num_nl = 0;
-	for (j = 0; j < i; ++j) {
-	    if (buf[j] == '\n')
-	    	++num_nl;
-	}
-	remaining = i + num_nl;
-	for (j = i - 1; j >= 0; --j) {
-	    buf[j + num_nl] = buf[j];
-	    if (buf[j] == '\n') {
-	    	--num_nl;
-		buf[j + num_nl] = '\r';
-	    }
-	}
-
-	puts(buf, remaining);
-	return i;
-}
-
-#define hwrpb (*INIT_HWRPB)
+struct hwrpb_struct *hwrpb = INIT_HWRPB;
+static struct pcb_struct pcb_va[1];
 
 /*
  * Find a physical address of a virtual object..
  *
  * This is easy using the virtual page table address.
  */
-struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
+
+static inline void *
+find_pa(unsigned long *vptb, void *ptr)
 {
-	unsigned long address = (unsigned long) pcb;
+	unsigned long address = (unsigned long) ptr;
 	unsigned long result;
 
 	result = vptb[address >> 13];
 	result >>= 32;
 	result <<= 13;
 	result |= address & 0x1fff;
-	return (struct pcb_struct *) result;
+	return (void *) result;
 }	
 
 /*
@@ -101,31 +57,19 @@
  * code has the L1 page table identity-map itself in the second PTE
  * in the L1 page table. Thus the L1-page is virtually addressable
  * itself (through three levels) at virtual address 0x200802000.
- *
- * As we don't want it there anyway, we also move the L1 self-map
- * up as high as we can, so that the last entry in the L1 page table
- * maps the page tables.
- *
- * As a result, the OSF/1 pal-code will instead use a virtual page table
- * map located at 0xffffffe00000000.
  */
-#define pcb_va ((struct pcb_struct *) 0x20000000)
-#define old_vptb (0x0000000200000000UL)
-#define new_vptb (0xfffffffe00000000UL)
-void pal_init(void)
+
+#define VPTB	((unsigned long *) 0x200000000)
+#define L1	((unsigned long *) 0x200802000)
+
+void
+pal_init(void)
 {
-	unsigned long i, rev, sum;
-	unsigned long *L1, *l;
+	unsigned long i, rev;
 	struct percpu_struct * percpu;
 	struct pcb_struct * pcb_pa;
 
-	/* Find the level 1 page table and duplicate it in high memory */
-	L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */
-	L1[1023] = L1[1];
-
-	percpu = (struct percpu_struct *)
-			(hwrpb.processor_offset + (unsigned long) &hwrpb),
-		
+	/* Create the dummy PCB.  */
 	pcb_va->ksp = 0;
 	pcb_va->usp = 0;
 	pcb_va->ptbr = L1[1] >> 32;
@@ -133,58 +77,45 @@
 	pcb_va->pcc = 0;
 	pcb_va->unique = 0;
 	pcb_va->flags = 1;
-	pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
-	printk("Switching to OSF PAL-code .. ");
+	pcb_va->res1 = 0;
+	pcb_va->res2 = 0;
+	pcb_pa = find_pa(VPTB, pcb_va);
+
 	/*
 	 * a0 = 2 (OSF)
 	 * a1 = return address, but we give the asm the vaddr of the PCB
 	 * a2 = physical addr of PCB
 	 * a3 = new virtual page table pointer
-	 * a4 = KSP (but we give it 0, asm sets it)
+	 * a4 = KSP (but the asm sets it)
 	 */
-	i = switch_to_osf_pal(
-		2,
-		pcb_va,
-		pcb_pa,
-		new_vptb,
-		0);
+	srm_printk("Switching to OSF PAL-code .. ");
+
+	i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
 	if (i) {
-		printk("failed, code %ld\n", i);
+		srm_printk("failed, code %ld\n", i);
 		halt();
 	}
-	rev = percpu->pal_revision = percpu->palcode_avail[2];
 
-	hwrpb.vptb = new_vptb;
+	percpu = (struct percpu_struct *)
+		(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
+	rev = percpu->pal_revision = percpu->palcode_avail[2];
 
-	/* update checksum: */
-	sum = 0;
-	for (l = (unsigned long *) &hwrpb;
-	     l < (unsigned long *) &hwrpb.chksum;
-	     ++l)
-		sum += *l;
-	hwrpb.chksum = sum;
-
-	printk("Ok (rev %lx)\n", rev);
-	/* remove the old virtual page-table mapping */
-	L1[1] = 0;
+	srm_printk("Ok (rev %lx)\n", rev);
 
 	tbia(); /* do it directly in case we are SMP */
 }
 
-static inline long load(unsigned long dst,
-			unsigned long src,
-			unsigned long count)
+static inline void
+load(unsigned long dst, unsigned long src, unsigned long count)
 {
-	extern void * memcpy(void *, const void *, size_t);
-
 	memcpy((void *)dst, (void *)src, count);
-	return count;
 }
 
 /*
  * Start the kernel.
  */
-static void runkernel(void)
+static inline void
+runkernel(void)
 {
 	__asm__ __volatile__(
 		"bis %1,%1,$30\n\t"
@@ -199,65 +130,82 @@
 #define KERNEL_ORIGIN \
 	((((unsigned long)&_end) + 511) & ~511)
 
-void start_kernel(void)
+void
+start_kernel(void)
 {
-	static long i;
-	static int nbytes;
 	/*
-	 * note that this crufty stuff with static and envval and envbuf
-	 * is because:
+	 * Note that this crufty stuff with static and envval
+	 * and envbuf is because:
 	 *
-	 * 1. frequently, the stack is is short, and we don't want to overrun;
-	 * 2. frequently the stack is where we are going to copy the kernel to;
-	 * 3. a certain SRM console required the GET_ENV output to stack.
+	 * 1. Frequently, the stack is short, and we don't want to overrun;
+	 * 2. Frequently the stack is where we are going to copy the kernel to;
+	 * 3. A certain SRM console required the GET_ENV output to stack.
+	 *    ??? A comment in the aboot sources indicates that the GET_ENV
+	 *    destination must be quadword aligned.  Might this explain the
+	 *    behaviour, rather than requiring output to the stack, which
+	 *    seems rather far-fetched.
 	 */
-	static char envval[256];
-	char envbuf[256];
+	static long nbytes;
+	static char envval[256] __attribute__((aligned(8)));
+#ifdef INITRD_SIZE
+	static unsigned long initrd_start;
+#endif
 
-	printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
-	if (hwrpb.pagesize != 8192) {
-		printk("Expected 8kB pages, got %ldkB\n",
-		       hwrpb.pagesize >> 10);
+	srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
+	if (INIT_HWRPB->pagesize != 8192) {
+		srm_printk("Expected 8kB pages, got %ldkB\n",
+		           INIT_HWRPB->pagesize >> 10);
+		return;
+	}
+	if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
+		srm_printk("Expected vptb at %p, got %p\n",
+			   VPTB, (void *)INIT_HWRPB->vptb);
 		return;
 	}
 	pal_init();
 
-	nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
-			  envbuf, sizeof(envbuf));
-	if (nbytes < 0 || nbytes >= sizeof(envbuf)) {
+#ifdef INITRD_SIZE
+	/* The initrd must be page-aligned.  See below for the 
+	   cause of the magic number 5.  */
+	initrd_start = ((START_ADDR + 5*KERNEL_SIZE) | (PAGE_SIZE-1)) + 1;
+	srm_printk("Initrd positioned at %#lx\n", initrd_start);
+#endif
+
+	nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
+			      envval, sizeof(envval));
+	if (nbytes < 0 || nbytes >= sizeof(envval)) {
 		nbytes = 0;
 	}
-	envbuf[nbytes] = '\0';
-	memcpy(envval, envbuf, nbytes+1);
-	printk("Loading the kernel...'%s'\n", envval);
+	envval[nbytes] = '\0';
+	srm_printk("Loading the kernel...'%s'\n", envval);
 
 	/* NOTE: *no* callbacks or printouts from here on out!!! */
 
-#if 1
 	/*
-	 * this is a hack, as some consoles seem to get virtual 20000000
+	 * This is a hack, as some consoles seem to get virtual 20000000
 	 * (ie where the SRM console puts the kernel bootp image) memory
 	 * overlapping physical 310000 memory, which causes real problems
 	 * when attempting to copy the former to the latter... :-(
 	 *
-	 * so, we first move the kernel virtual-to-physical way above where
+	 * So, we first move the kernel virtual-to-physical way above where
 	 * we physically want the kernel to end up, then copy it from there
 	 * to its final resting place... ;-}
 	 *
-	 * sigh...
+	 * Sigh...
 	 */
 
-        i = load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
-        i = load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
-#else
-	i = load(START_ADDR, KERNEL_ORIGIN, KERNEL_SIZE);
+#ifdef INITRD_SIZE
+	load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_SIZE);
 #endif
+        load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
+        load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
 
+	memset((char*)ZERO_PAGE, 0, PAGE_SIZE);
 	strcpy((char*)ZERO_PAGE, envval);
+#ifdef INITRD_SIZE
+	((long *)(ZERO_PAGE+256))[0] = initrd_start;
+	((long *)(ZERO_PAGE+256))[1] = INITRD_SIZE;
+#endif
 
 	runkernel();
-
-	for (i = 0 ; i < 0x100000000 ; i++)
-		/* nothing */;
-	halt();
 }
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/boot/head.S linux/arch/alpha/boot/head.S
--- v2.1.125/linux/arch/alpha/boot/head.S	Sat Mar 16 03:52:12 1996
+++ linux/arch/alpha/boot/head.S	Mon Oct 12 11:40:12 1998
@@ -6,28 +6,22 @@
 
 #include <asm/system.h>
 
-#define halt .long PAL_halt
-
 	.set noreorder
 	.globl	__start
 	.ent	__start
 __start:
-	bis	$31,$31,$31
-	br	1f
-	/* room for the initial PCB, which comes here */
-	.quad	0,0,0,0,0,0,0,0
-1:	br	$27,2f
-2:	ldgp	$29,0($27)
-	lda	$27,start_kernel
-	jsr	$26,($27),start_kernel
-	halt
+	br	$29,2f
+2:	ldgp	$29,0($29)
+	jsr	$26,start_kernel
+	call_pal PAL_halt
 	.end __start
 
 	.align 5
 	.globl	wrent
 	.ent	wrent
 wrent:
-	.long PAL_wrent
+	.prologue 0
+	call_pal PAL_wrent
 	ret ($26)
 	.end wrent
 
@@ -35,7 +29,8 @@
 	.globl	wrkgp
 	.ent	wrkgp
 wrkgp:
-	.long PAL_wrkgp
+	.prologue 0
+	call_pal PAL_wrkgp
 	ret ($26)
 	.end wrkgp
 
@@ -44,6 +39,7 @@
 	.ent	switch_to_osf_pal
 switch_to_osf_pal:
 	subq	$30,128,$30
+	.frame	$30,128,$26
 	stq	$26,0($30)
 	stq	$1,8($30)
 	stq	$2,16($30)
@@ -60,11 +56,12 @@
 	stq	$13,104($30)
 	stq	$14,112($30)
 	stq	$15,120($30)
+	.prologue 0
 
 	stq	$30,0($17)	/* save KSP in PCB */
 
 	bis	$30,$30,$20	/* a4 = KSP */
-	br	$17,__do_swppal
+	br	$17,1f
 
 	ldq	$26,0($30)
 	ldq	$1,8($30)
@@ -84,56 +81,22 @@
 	ldq	$15,120($30)
 	addq	$30,128,$30
 	ret ($26)
-
-__do_swppal:
-	.long	PAL_swppal
+1:	call_pal PAL_swppal
 	.end	switch_to_osf_pal
 
-.globl	dispatch
-.ent	dispatch
-dispatch:
-	subq	$30,80,$30
-	stq	$26,0($30)
-	stq	$29,8($30)
-
-	stq	$8,16($30)
-	stq	$9,24($30)
-	stq	$10,32($30)
-	stq	$11,40($30)
-	stq	$12,48($30)
-	stq	$13,56($30)
-	stq	$14,64($30)
-	stq	$15,72($30)
-
-	lda	$1,0x10000000		/* hwrpb */
-	ldq	$2,0xc0($1)		/* crb offset */
-	addq	$2,$1,$2		/* crb */
-	ldq	$27,0($2)		/* dispatch procedure value */
-
-	ldq	$2,8($27)		/* dispatch call address */
-	jsr	$26,($2)		/* call it (weird VMS call seq) */
-
-	ldq	$26,0($30)
-	ldq	$29,8($30)
-
-	ldq	$8,16($30)
-	ldq	$9,24($30)
-	ldq	$10,32($30)
-	ldq	$11,40($30)
-	ldq	$12,48($30)
-	ldq	$13,56($30)
-	ldq	$14,64($30)
-	ldq	$15,72($30)
-
-	addq	$30,80,$30
-	ret	$31,($26)
-.end    dispatch
-
 	.align 3
 	.globl	tbi
 	.ent	tbi
 tbi:
-	.long PAL_tbi
+	.prologue 0
+	call_pal PAL_tbi
 	ret	($26)
 	.end tbi
 
+	.align 3
+	.globl	halt
+	.ent	halt
+halt:
+	.prologue 0
+	call_pal PAL_halt
+	.end halt
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.1.125/linux/arch/alpha/config.in	Tue Aug 18 22:02:01 1998
+++ linux/arch/alpha/config.in	Mon Oct 12 11:40:12 1998
@@ -175,8 +175,6 @@
 	define_bool CONFIG_ALPHA_AVANTI y
 fi
 
-#bool 'Echo console messages on /dev/ttyS0 (COM1)' CONFIG_SERIAL_ECHO
-
 if [ "$CONFIG_PCI" = "y" ]; then
   bool 'PCI quirks' CONFIG_PCI_QUIRKS
   if [ "$CONFIG_PCI_QUIRKS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.1.125/linux/arch/alpha/kernel/alpha_ksyms.c	Tue Aug 18 22:02:01 1998
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Mon Oct 12 11:40:12 1998
@@ -136,6 +136,37 @@
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strlen_user);
 
+/* 
+ * SMP-specific symbols.
+ */
+
+#ifdef __SMP__
+EXPORT_SYMBOL(synchronize_irq);
+EXPORT_SYMBOL(flush_tlb_all);
+EXPORT_SYMBOL(flush_tlb_mm);
+EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(flush_tlb_range);
+EXPORT_SYMBOL(cpu_data);
+EXPORT_SYMBOL(cpu_number_map);
+EXPORT_SYMBOL(global_bh_lock);
+EXPORT_SYMBOL(global_bh_count);
+EXPORT_SYMBOL(synchronize_bh);
+EXPORT_SYMBOL(global_irq_holder);
+EXPORT_SYMBOL(__global_cli);
+EXPORT_SYMBOL(__global_sti);
+EXPORT_SYMBOL(__global_save_flags);
+EXPORT_SYMBOL(__global_restore_flags);
+#if DEBUG_SPINLOCK
+EXPORT_SYMBOL(spin_unlock);
+EXPORT_SYMBOL(spin_lock);
+EXPORT_SYMBOL(spin_trylock);
+#endif
+#if DEBUG_RWLOCK
+EXPORT_SYMBOL(write_lock);
+EXPORT_SYMBOL(read_lock);
+#endif
+#endif /* __SMP__ */
+
 /*
  * The following are special because they're not called
  * explicitly (the C compiler or assembler generates them in
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- v2.1.125/linux/arch/alpha/kernel/bios32.c	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/kernel/bios32.c	Mon Oct 12 11:40:12 1998
@@ -524,16 +524,8 @@
 			size = (mask & base) & 0xffffffff;
 			switch (type) {
 			case PCI_BASE_ADDRESS_MEM_TYPE_32:
-				break;
-
 			case PCI_BASE_ADDRESS_MEM_TYPE_64:
-				printk("bios32 WARNING: "
-				       "ignoring 64-bit device in "
-				       "slot %d, function %d: \n",
-				       PCI_SLOT(dev->devfn),
-				       PCI_FUNC(dev->devfn));
-				idx++;	/* skip extra 4 bytes */
-				continue;
+				break;
 
 			case PCI_BASE_ADDRESS_MEM_TYPE_1M:
 				/*
@@ -594,6 +586,29 @@
 						   off, base);
 			handle = PCI_HANDLE(bus->number) | base;
 			dev->base_address[idx] = handle;
+
+			/*
+			 * Currently for 64-bit cards, we simply do the usual
+			 * for setup of the first register (low) of the pair,
+			 * and then clear out the second (high) register, as
+			 * we are not yet able to do 64-bit addresses, and
+			 * setting the high register to 0 allows 32-bit SAC
+			 * addresses to be used.
+			 */
+			if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+				pcibios_write_config_dword(bus->number,
+							   dev->devfn,
+							   off+4, 0);
+				/* Bypass hi reg in the loop.  */
+				dev->base_address[++idx] = 0;
+
+				printk("bios32 WARNING: "
+				       "handling 64-bit device in "
+				       "slot %d, function %d: \n",
+				       PCI_SLOT(dev->devfn),
+				       PCI_FUNC(dev->devfn));
+			}
+
 			DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%lx (0x%x)\n",
 				  dev->device, handle, size));
 		}
@@ -692,36 +707,46 @@
 		struct pci_dev *bridge = bus->self;
 
 		DBG_DEVS(("layout_bus: config bus %d bridge\n", bus->number));
+
 		/*
 		 * Set up the top and bottom of the PCI I/O segment
 		 * for this bus.
 		 */
 		pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
-					  0x1c, &l);
+					  PCI_IO_BASE, &l);
 		l &= 0xffff0000;
 		l |= ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
 		pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
-					   0x1c, l);
+					   PCI_IO_BASE, l);
+
+		/* Also clear out the upper 16 bits.  */
+		pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
+					   PCI_IO_BASE_UPPER16, 0);
+
 		/*
 		 * Set up the top and bottom of the  PCI Memory segment
 		 * for this bus.
 		 */
 		l = ((bmem & 0xfff00000) >> 16) | ((tmem - 1) & 0xfff00000);
 		pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
-					   0x20, l);
+					   PCI_MEMORY_BASE, l);
 		/*
 		 * Turn off downstream PF memory address range:
 		 */
 		pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
-					   0x24, 0x0000ffff);
+					   PCI_PREF_MEMORY_BASE, 0x0000ffff);
+
 		/*
 		 * Tell bridge that there is an ISA bus in the system,
 		 * and (possibly) a VGA as well.
 		 */
+		/* ??? This appears to be a single-byte write into MIN_GNT.
+		   What is up with this?  */
 		l = 0x00040000; /* ISA present */
 		if (found_vga) l |= 0x00080000; /* VGA present */
 		pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
 					   0x3c, l);
+
 		/*
 		 * Clear status bits, enable I/O (for downstream I/O),
 		 * turn on master enable (for upstream I/O), turn on
@@ -729,7 +754,7 @@
 		 * master enable (for upstream memory and I/O).
 		 */
 		pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
-					   0x4, 0xffff0007);
+					   PCI_COMMAND, 0xffff0007);
 	}
 	DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
 	return found_vga;
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/core_pyxis.c linux/arch/alpha/kernel/core_pyxis.c
--- v2.1.125/linux/arch/alpha/kernel/core_pyxis.c	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/kernel/core_pyxis.c	Mon Oct 12 11:40:12 1998
@@ -99,33 +99,13 @@
 mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
 	     unsigned char *type1)
 {
-	unsigned long addr;
+	*type1 = (bus == 0) ? 0 : 1;
+	*pci_addr = (bus << 16) | (device_fn << 8) | (where);
 
 	DBG_CNF(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
-		 " pci_addr=0x%p, type1=0x%p)\n",
-		 bus, device_fn, where, pci_addr, type1));
+		 " returning address 0x%p\n"
+		 bus, device_fn, where, *pci_addr));
 
-	if (bus == 0) {
-		int device;
-
-		device = device_fn >> 3;
-		/* Type 0 configuration cycle. */
-#if NOT_NOW
-		if (device > 20) {
-			DBG_CNF(("mk_conf_addr: device (%d) > 20, return -1\n",
-				 device));
-			return -1;
-		}
-#endif
-		*type1 = 0;
-		addr = (device_fn << 8) | (where);
-	} else {
-		/* Type 1 configuration cycle.  */
-		*type1 = 1;
-		addr = (bus << 16) | (device_fn << 8) | (where);
-	}
-	*pci_addr = addr;
-	DBG_CNF(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
 	return 0;
 }
 
@@ -142,12 +122,11 @@
 	stat0 = *(vuip)PYXIS_ERR;
 	*(vuip)PYXIS_ERR = stat0; mb();
 	temp = *(vuip)PYXIS_ERR;  /* re-read to force write */
-	DBG_CNF(("conf_read: PYXIS ERR was 0x%x\n", stat0));
 
 	/* If Type1 access, must set PYXIS CFG.  */
 	if (type1) {
 		pyxis_cfg = *(vuip)PYXIS_CFG;
-		*(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
+		*(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb();
 		temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
 	}
 
@@ -172,14 +151,15 @@
 
 	/* If Type1 access, must reset IOC CFG so normal IO space ops work.  */
 	if (type1) {
-		*(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
+		*(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb();
 		temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
 	}
 
+	__restore_flags(flags);
+
 	DBG_CNF(("conf_read(addr=0x%lx, type1=%d) = %#x\n",
 		 addr, type1, value));
 
-	__restore_flags(flags);
 	return value;
 }
 
@@ -190,9 +170,6 @@
 	unsigned int stat0, temp;
 	unsigned int pyxis_cfg = 0;
 
-	DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n",
-		 addr, value, type1));
-
 	__save_and_cli(flags);	/* avoid getting hit by machine check */
 
 	/* Reset status register to avoid losing errors.  */
@@ -203,7 +180,7 @@
 	/* If Type1 access, must set PYXIS CFG.  */
 	if (type1) {
 		pyxis_cfg = *(vuip)PYXIS_CFG;
-		*(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
+		*(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb();
 		temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
 	}
 
@@ -216,18 +193,20 @@
 	/* Access configuration space.  */
 	*(vuip)addr = value;
 	mb();
-	mb();  /* magic */
-	temp = *(vuip)PYXIS_ERR; /* do a PYXIS read to force the write */
+	temp = *(vuip)addr; /* read back to force the write */
 	PYXIS_mcheck_expected = 0;
 	mb();
 
 	/* If Type1 access, must reset IOC CFG so normal IO space ops work.  */
 	if (type1) {
-		*(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
+		*(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb();
 		temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
 	}
 
 	__restore_flags(flags);
+
+	DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n",
+		 addr, value, type1));
 }
 
 int
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v2.1.125/linux/arch/alpha/kernel/entry.S	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/kernel/entry.S	Mon Oct 12 11:40:12 1998
@@ -552,7 +552,6 @@
 ret_from_sys_call:
 	cmovne	$26,0,$19		/* $19 = 0 => non-restartable */
 	/* check bottom half interrupts */
-	bne	$1,ret_from_handle_bh
 	ldq	$3,bh_active
 	ldq	$4,bh_mask
 	and	$3,$4,$2
@@ -678,7 +677,7 @@
 	bis	$30,$30,$18
 	bis	$31,$31,$16
 	jsr	$26,do_signal
-	lda	$30,SWITCH_STACK_SIZE($30)
+	bsr	$1,undo_switch_stack
 	br	$31,restore_all
 .end entSys
 
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S
--- v2.1.125/linux/arch/alpha/kernel/head.S	Tue Aug 18 22:02:02 1998
+++ linux/arch/alpha/kernel/head.S	Mon Oct 12 11:40:12 1998
@@ -9,8 +9,6 @@
 
 #include <asm/system.h>
 
-#define halt call_pal PAL_halt
-
 .globl swapper_pg_dir
 .globl _stext
 swapper_pg_dir=SWAPPER_PGD
@@ -29,28 +27,28 @@
 	lda	$30,0x4000($8)
 	/* ... and then we can start the kernel.  */
 	jsr	$26,start_kernel
-	halt
+	call_pal PAL_halt
 	.end __start
 
 #ifdef __SMP__
 	.align 3
 	.globl	__start_cpu
 	.ent	__start_cpu
-	/* on entry here from SRM console, the HWPCB of this processor */
-	/* has been loaded, and $27 contains the task pointer */
+	/* On entry here from SRM console, the HWPCB of this processor
+	   has been loaded, and $27 contains the task pointer */
 __start_cpu:
 	.prologue 0
-	/* first order of business, load the GP */
+	/* First order of business, load the GP */
 	br	$26,1f
 1:	ldgp	$29,0($26)
 	/* We need to get current loaded up with our first task...  */
-	lda	$8,0($27)
-	/* set FEN */
+	mov	$27,$8
+	/* Set FEN */
 	lda	$16,1($31)
 	call_pal PAL_wrfen
 	/* ... and then we can start the processor.  */
 	jsr	$26,start_secondary
-	halt
+	call_pal PAL_halt
 	.end __start_cpu
 #endif /* __SMP__ */
 
@@ -121,10 +119,20 @@
 	.globl  wripir
 	.ent    wripir
 wripir:
+	.prologue 0
 	call_pal PAL_wripir
 	ret     ($26)
 	.end wripir
 
+	.align 3
+	.globl wrvptptr
+	.ent wrvptptr
+wrvptptr:
+	.prologue 0
+	call_pal PAL_wrvptptr
+	ret	($26)
+	.end wrvptptr
+
 	#
 	# The following two functions are needed for supporting SRM PALcode
 	# on the PC164 (at least), since that PALcode manages the interrupt
@@ -152,3 +160,17 @@
 	call_pal PAL_cserve
 	ret	($26)
 	.end	cserve_dis
+
+	#
+	# It is handy, on occasion, to make halt actually just loop. 
+	# Putting it here means we dont have to recompile the whole
+	# kernel.
+	#
+
+	.align 3
+	.globl	halt
+	.ent	halt
+halt:
+	.prologue 0
+	call_pal PAL_halt
+	.end	halt
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.1.125/linux/arch/alpha/kernel/irq.c	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/kernel/irq.c	Mon Oct 12 11:40:12 1998
@@ -311,26 +311,41 @@
 
 int get_irq_list(char *buf)
 {
-	int i, len = 0;
+	int i, j;
 	struct irqaction * action;
-	int cpu = smp_processor_id();
+	char *p = buf;
+
+#ifdef __SMP__
+	p += sprintf(p, "           ");
+	for (j = 0; j < smp_num_cpus; j++)
+		p += sprintf(p, "CPU%d       ", j);
+	*p++ = '\n';
+#endif
 
 	for (i = 0; i < NR_IRQS; i++) {
 		action = irq_action[i];
 		if (!action) 
 			continue;
-		len += sprintf(buf+len, "%2d: %10u %c %s",
-			       i, kstat.irqs[cpu][i],
-			       (action->flags & SA_INTERRUPT) ? '+' : ' ',
-			       action->name);
+		p += sprintf(p, "%3d: ",i);
+#ifndef __SMP__
+		p += sprintf(p, "%10u ", kstat_irqs(i));
+#else
+		for (j = 0; j < smp_num_cpus; j++)
+			p += sprintf(p, "%10u ",
+				     kstat.irqs[cpu_logical_map(j)][i]);
+#endif
+		p += sprintf(p, "  %c%s",
+			     (action->flags & SA_INTERRUPT)?'+':' ',
+			     action->name);
+
 		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ", %s%s",
-				       (action->flags & SA_INTERRUPT) ? "+":"",
-				       action->name);
+			p += sprintf(p, ", %c%s",
+				     (action->flags & SA_INTERRUPT)?'+':' ',
+				     action->name);
 		}
-		len += sprintf(buf+len, "\n");
+		*p++ = '\n';
 	}
-	return len;
+	return p - buf;
 }
 
 #ifdef __SMP__
@@ -427,8 +442,10 @@
 	/*
 	 * Finally.
 	 */
+#if DEBUG_SPINLOCK
 	global_irq_lock.task = current;
 	global_irq_lock.previous = where;
+#endif
 	global_irq_holder = cpu;
 	previous_irqholder = where;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/irq.h linux/arch/alpha/kernel/irq.h
--- v2.1.125/linux/arch/alpha/kernel/irq.h	Wed Sep  9 14:51:03 1998
+++ linux/arch/alpha/kernel/irq.h	Mon Oct 12 11:40:12 1998
@@ -11,12 +11,8 @@
 #define STANDARD_INIT_IRQ_PROLOG	\
 	outb(0, DMA1_RESET_REG);	\
 	outb(0, DMA2_RESET_REG);	\
-	outb(0, DMA1_MASK_REG);		\
-	outb(0, DMA2_MASK_REG);		\
 	outb(0, DMA1_CLR_MASK_REG);	\
-	outb(0, DMA2_CLR_MASK_REG);	\
-	outb(DMA_MODE_CASCADE, DMA2_MODE_REG)
-
+	outb(0, DMA2_CLR_MASK_REG)
 
 extern unsigned long alpha_irq_mask;
 
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/machvec.h linux/arch/alpha/kernel/machvec.h
--- v2.1.125/linux/arch/alpha/kernel/machvec.h	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/machvec.h	Mon Oct 12 11:40:12 1998
@@ -27,8 +27,7 @@
 #define CAT1(x,y)  x##y
 #define CAT(x,y)   CAT1(x,y)
 
-#define DO_DEFAULT_RTC				\
-	rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 0
+#define DO_DEFAULT_RTC rtc_port: 0x70
 
 #define DO_EV4_MMU							\
 	max_asn:			EV4_MAX_ASN,			\
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v2.1.125/linux/arch/alpha/kernel/process.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/process.c	Mon Oct 12 11:40:12 1998
@@ -181,6 +181,9 @@
 		return;
 	}
 
+	if (alpha_using_srm)
+		srm_paging_stop();
+
 	halt();
 }
 
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h
--- v2.1.125/linux/arch/alpha/kernel/proto.h	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/proto.h	Mon Oct 12 11:40:12 1998
@@ -143,6 +143,7 @@
 
 /* time.c */
 extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs);
+extern unsigned long est_cycle_freq;
 
 /* smc37c93x.c */
 extern void SMC93x_Init(void);
@@ -172,5 +173,12 @@
 extern void entUna(void);
 
 /* process.c */
-void generic_kill_arch (int mode, char *reboot_cmd);
-void cpu_idle(void *) __attribute__((noreturn));
+extern void generic_kill_arch (int mode, char *reboot_cmd);
+extern void cpu_idle(void *) __attribute__((noreturn));
+
+/* ptrace.c */
+extern int ptrace_set_bpt (struct task_struct *child);
+extern int ptrace_cancel_bpt (struct task_struct *child);
+
+/* ../mm/init.c */
+void srm_paging_stop(void);
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c
--- v2.1.125/linux/arch/alpha/kernel/ptrace.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/ptrace.c	Mon Oct 12 11:40:12 1998
@@ -12,27 +12,26 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/malloc.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
+#include "proto.h"
+
+#define DEBUG	DBG_MEM
 #undef DEBUG
 
 #ifdef DEBUG
-
 enum {
 	DBG_MEM		= (1<<0),
 	DBG_BPT		= (1<<1),
 	DBG_MEM_ALL	= (1<<2)
 };
-
-int debug_mask = DBG_BPT;
-
-# define DBG(fac,args)	{if ((fac) & debug_mask) printk args;}
-
+#define DBG(fac,args)	{if ((fac) & DEBUG) printk args;}
 #else
-# define DBG(fac,args)
+#define DBG(fac,args)
 #endif
 
 #define BREAKINST	0x00000080	/* call_pal bpt */
@@ -45,33 +44,26 @@
 /*
  * Processes always block with the following stack-layout:
  *
- *  +================================+ --------------------------
- *  | PALcode saved frame (ps, pc,   | ^		      ^
- *  | gp, a0, a1, a2)		     | |		      |
- *  +================================+ | struct pt_regs	      |
- *  |	        		     | |		      |
- *  | frame generated by SAVE_ALL    | |		      |
- *  |	        		     | v		      | P
- *  +================================+			      |	A
- *  |	        		     | ^		      |	G
- *  | frame saved by do_switch_stack | | struct switch_stack  |	E
- *  |	        		     | v		      |	_
- *  +================================+			      |	S
- *  |	        		     |			      |	I
- *  |	        		     |			      |	Z
- *  /	        		     /			      |	E
- *  /	                             /			      |
- *  |				     |			      |
- *  |				     |			      |
- *  |				     |			      v
- *  +================================+ <-------------------------
- *					task + PAGE_SIZE
+ *  +================================+ <---- task + 2*PAGE_SIZE
+ *  | PALcode saved frame (ps, pc,   | ^
+ *  | gp, a0, a1, a2)		     | |
+ *  +================================+ | struct pt_regs
+ *  |	        		     | |
+ *  | frame generated by SAVE_ALL    | |
+ *  |	        		     | v
+ *  +================================+
+ *  |	        		     | ^
+ *  | frame saved by do_switch_stack | | struct switch_stack
+ *  |	        		     | v
+ *  +================================+
  */
-#define PT_REG(reg)	(PAGE_SIZE - sizeof(struct pt_regs)	\
+#define PT_REG(reg)	(PAGE_SIZE*2 - sizeof(struct pt_regs)		\
 			 + (long)&((struct pt_regs *)0)->reg)
-#define SW_REG(reg)	(PAGE_SIZE - sizeof(struct pt_regs)	\
-			 - sizeof(struct switch_stack)		\
+
+#define SW_REG(reg)	(PAGE_SIZE*2 - sizeof(struct pt_regs)		\
+			 - sizeof(struct switch_stack)			\
 			 + (long)&((struct switch_stack *)0)->reg)
+
 /* 
  * The following table maps a register index into the stack offset at
  * which the register is saved.  Register indices are 0-31 for integer
@@ -80,10 +72,10 @@
  * get_reg/put_reg below).
  */
 enum {
-	REG_R0 = 0, REG_F0 = 32, REG_PC = 64
+	REG_R0 = 0, REG_F0 = 32, REG_FPCR = 63, REG_PC = 64
 };
 
-static unsigned short regoff[] = {
+static int regoff[] = {
 	PT_REG(	   r0), PT_REG(	   r1), PT_REG(	   r2), PT_REG(	  r3),
 	PT_REG(	   r4), PT_REG(	   r5), PT_REG(	   r6), PT_REG(	  r7),
 	PT_REG(	   r8), SW_REG(	   r9), SW_REG(	  r10), SW_REG(	 r11),
@@ -106,38 +98,40 @@
 static long zero;
 
 /*
- * Get contents of register REGNO in task TASK.
+ * Get address of register REGNO in task TASK.
  */
-static inline long get_reg(struct task_struct * task, long regno)
+static long *
+get_reg_addr(struct task_struct * task, unsigned long regno)
 {
 	long *addr;
 
 	if (regno == 30) {
 		addr = &task->tss.usp;
-	} else if (regno == 31) {
+	} else if (regno == 31 || regno > 64) {
 		zero = 0;
 		addr = &zero;
 	} else {
-		addr = (long *) (regoff[regno] + PAGE_SIZE + (long)task);
+		addr = (long *)((long)task + regoff[regno]);
 	}
-	return *addr;
+	return addr;
 }
 
 /*
- * Write contents of register REGNO in task TASK.
+ * Get contents of register REGNO in task TASK.
  */
-static inline int put_reg(struct task_struct *task, long regno, long data)
+static inline long
+get_reg(struct task_struct * task, unsigned long regno)
 {
-	long *addr, zero;
+	return *get_reg_addr(task, regno);
+}
 
-	if (regno == 30) {
-		addr = &task->tss.usp;
-	} else if (regno == 31) {
-		addr = &zero;
-	} else {
-		addr = (long *) (regoff[regno] + PAGE_SIZE + (long)task);
-	}
-	*addr = data;
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int
+put_reg(struct task_struct *task, unsigned long regno, long data)
+{
+	*get_reg_addr(task, regno) = data;
 	return 0;
 }
 
@@ -147,8 +141,9 @@
  * and that it is in the task area before calling this: this routine does
  * no checking.
  */
-static unsigned long get_long(struct task_struct * tsk,
-			      struct vm_area_struct * vma, unsigned long addr)
+static unsigned long
+get_long(struct task_struct * tsk, struct vm_area_struct * vma,
+	 unsigned long addr)
 {
 	pgd_t * pgdir;
 	pmd_t * pgmiddle;
@@ -199,8 +194,9 @@
  * Now keeps R/W state of page so that a text page stays readonly
  * even if a debugger scribbles breakpoints into it.  -M.U-
  */
-static void put_long(struct task_struct * tsk, struct vm_area_struct * vma,
-		     unsigned long addr, unsigned long data)
+static void
+put_long(struct task_struct * tsk, struct vm_area_struct * vma,
+	 unsigned long addr, unsigned long data)
 {
 	pgd_t *pgdir;
 	pmd_t *pgmiddle;
@@ -250,8 +246,8 @@
 	flush_tlb();
 }
 
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk,
-					       unsigned long addr)
+static struct vm_area_struct *
+find_extend_vma(struct task_struct * tsk, unsigned long addr)
 {
 	struct vm_area_struct * vma;
 
@@ -274,8 +270,8 @@
  * This routine checks the page boundaries, and that the offset is
  * within the task area. It then calls get_long() to read a long.
  */
-static int read_long(struct task_struct * tsk, unsigned long addr,
-		     unsigned long * result)
+static int
+read_long(struct task_struct * tsk, unsigned long addr, unsigned long * result)
 {
 	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
 
@@ -315,8 +311,8 @@
  * This routine checks the page boundaries, and that the offset is
  * within the task area. It then calls put_long() to write a long.
  */
-static int write_long(struct task_struct * tsk, unsigned long addr,
-		      unsigned long data)
+static int
+write_long(struct task_struct * tsk, unsigned long addr, unsigned long data)
 {
 	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
 
@@ -349,8 +345,8 @@
 /*
  * Read a 32bit int from address space TSK.
  */
-static int read_int(struct task_struct * tsk, unsigned long addr,
-		    unsigned int *data)
+static int
+read_int(struct task_struct * tsk, unsigned long addr, unsigned int *data)
 {
 	unsigned long l, align;
 	int res;
@@ -376,8 +372,8 @@
  * For simplicity, do a read-modify-write of the 64bit word that
  * contains the 32bit word that we are about to write.
  */
-static int write_int(struct task_struct * tsk, unsigned long addr,
-		     unsigned int data)
+static int
+write_int(struct task_struct * tsk, unsigned long addr, unsigned int data)
 {
 	unsigned long l, align;
 	int res;
@@ -400,7 +396,8 @@
 /*
  * Set breakpoint.
  */
-int ptrace_set_bpt(struct task_struct * child)
+int
+ptrace_set_bpt(struct task_struct * child)
 {
 	int displ, i, res, reg_b, nsaved = 0;
 	u32 insn, op_code;
@@ -422,31 +419,31 @@
 		 * branch (emulation can be tricky for fp branches).
 		 */
 		displ = ((s32)(insn << 11)) >> 9;
-		child->tss.debugreg[nsaved++] = pc + 4;
+		child->tss.bpt_addr[nsaved++] = pc + 4;
 		if (displ)		/* guard against unoptimized code */
-			child->tss.debugreg[nsaved++] = pc + 4 + displ;
+			child->tss.bpt_addr[nsaved++] = pc + 4 + displ;
 		DBG(DBG_BPT, ("execing branch\n"));
 	} else if (op_code == 0x1a) {
 		reg_b = (insn >> 16) & 0x1f;
-		child->tss.debugreg[nsaved++] = get_reg(child, reg_b);
+		child->tss.bpt_addr[nsaved++] = get_reg(child, reg_b);
 		DBG(DBG_BPT, ("execing jump\n"));
 	} else {
-		child->tss.debugreg[nsaved++] = pc + 4;
+		child->tss.bpt_addr[nsaved++] = pc + 4;
 		DBG(DBG_BPT, ("execing normal insn\n"));
 	}
 
 	/* install breakpoints: */
 	for (i = 0; i < nsaved; ++i) {
-		res = read_int(child, child->tss.debugreg[i], &insn);
+		res = read_int(child, child->tss.bpt_addr[i], &insn);
 		if (res < 0)
 			return res;
-		child->tss.debugreg[i + 2] = insn;
-		DBG(DBG_BPT, ("    -> next_pc=%lx\n", child->tss.debugreg[i]));
-		res = write_int(child, child->tss.debugreg[i], BREAKINST);
+		child->tss.bpt_insn[i] = insn;
+		DBG(DBG_BPT, ("    -> next_pc=%lx\n", child->tss.bpt_addr[i]));
+		res = write_int(child, child->tss.bpt_addr[i], BREAKINST);
 		if (res < 0)
 			return res;
 	}
-	child->tss.debugreg[4] = nsaved;
+	child->tss.bpt_nsaved = nsaved;
 	return 0;
 }
 
@@ -454,11 +451,12 @@
  * Ensure no single-step breakpoint is pending.  Returns non-zero
  * value if child was being single-stepped.
  */
-int ptrace_cancel_bpt(struct task_struct * child)
+int
+ptrace_cancel_bpt(struct task_struct * child)
 {
-	int i, nsaved = child->tss.debugreg[4];
+	int i, nsaved = child->tss.bpt_nsaved;
 
-	child->tss.debugreg[4] = 0;
+	child->tss.bpt_nsaved = 0;
 
 	if (nsaved > 2) {
 		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
@@ -466,16 +464,18 @@
 	}
 
 	for (i = 0; i < nsaved; ++i) {
-		write_int(child, child->tss.debugreg[i],
-			  child->tss.debugreg[i + 2]);
+		write_int(child, child->tss.bpt_addr[i],
+			  child->tss.bpt_insn[i]);
 	}
 	return (nsaved != 0);
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
-			   int a4, int a5, struct pt_regs regs)
+asmlinkage long
+sys_ptrace(long request, long pid, long addr, long data,
+	   int a4, int a5, struct pt_regs regs)
 {
 	struct task_struct *child;
+	unsigned long tmp;
 	long ret;
 
 	lock_kernel();
@@ -540,9 +540,7 @@
 	switch (request) {
 	/* When I and D space are separate, these will need to be fixed.  */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
-	case PTRACE_PEEKDATA: {
-		unsigned long tmp;
-
+	case PTRACE_PEEKDATA:
 		ret = read_long(child, addr, &tmp);
 		DBG(DBG_MEM, ("peek %#lx->%#lx\n", addr, tmp));
 		if (ret < 0)
@@ -550,13 +548,12 @@
 		regs.r0 = 0;	/* special return: no errors */
 		ret = tmp;
 		goto out;
-	}
 
-	/* read register number ADDR. */
+	/* Read register number ADDR. */
 	case PTRACE_PEEKUSR:
 		regs.r0 = 0;	/* special return: no errors */
-		DBG(DBG_MEM, ("peek $%ld=%#lx\n", addr, regs.r0));
 		ret = get_reg(child, addr);
+		DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret));
 		goto out;
 
 	/* When I and D space are separate, this will have to be fixed.  */
@@ -573,7 +570,7 @@
 
 	case PTRACE_SYSCALL: /* continue and stop at next
 				(return from) syscall */
-	case PTRACE_CONT: { /* restart after signal. */
+	case PTRACE_CONT:    /* restart after signal. */
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out;
@@ -587,14 +584,13 @@
 		ptrace_cancel_bpt(child);
 		ret = data;
 		goto out;
-	}
 
 	/*
 	 * Make the child exit.  Best I can do is send it a sigkill.
 	 * perhaps it should be put in the status that it wants to
 	 * exit.
 	 */
-	case PTRACE_KILL: {
+	case PTRACE_KILL:
 		if (child->state != TASK_ZOMBIE) {
 			wake_up_process(child);
 			child->exit_code = SIGKILL;
@@ -603,22 +599,20 @@
 		ptrace_cancel_bpt(child);
 		ret = 0;
 		goto out;
-	}
 
-	case PTRACE_SINGLESTEP: {  /* execute single instruction. */
+	case PTRACE_SINGLESTEP:  /* execute single instruction. */
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out;
-		child->tss.debugreg[4] = -1;	/* mark single-stepping */
+		child->tss.bpt_nsaved = -1;	/* mark single-stepping */
 		child->flags &= ~PF_TRACESYS;
 		wake_up_process(child);
 		child->exit_code = data;
 		/* give it a chance to run. */
 		ret = 0;
 		goto out;
-	}
 
-	case PTRACE_DETACH: { /* detach a process that was attached. */
+	case PTRACE_DETACH: /* detach a process that was attached. */
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out;
@@ -632,7 +626,6 @@
 		ptrace_cancel_bpt(child);
 		ret = 0;
 		goto out;
-	}
 
 	default:
 		ret = -EIO;
@@ -643,7 +636,8 @@
 	return ret;
 }
 
-asmlinkage void syscall_trace(void)
+asmlinkage void
+syscall_trace(void)
 {
 	if ((current->flags & (PF_PTRACED|PF_TRACESYS))
 	    != (PF_PTRACED|PF_TRACESYS))
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v2.1.125/linux/arch/alpha/kernel/setup.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/setup.c	Mon Oct 12 11:40:12 1998
@@ -467,19 +467,22 @@
 				vec = eb66_vecs[eb66_indices[member]];
 			break;
 		case ST_DEC_1000:
-			if (cpu == EV5_CPU)
+			cpu &= 0xffffffff;
+			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &mikasa_primo_mv;
 			else
 				vec = &mikasa_mv;
 			break;
 		case ST_DEC_NORITAKE:
-			if (cpu == EV5_CPU)
+			cpu &= 0xffffffff;
+			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &noritake_primo_mv;
 			else
 				vec = &noritake_mv;
 			break;
 		case ST_DEC_2100_A500:
-			if (cpu == EV5_CPU)
+			cpu &= 0xffffffff;
+			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &sable_gamma_mv;
 			else
 				vec = &sable_mv;
@@ -678,7 +681,7 @@
 		      "system variation\t: %s\n"
 		      "system revision\t\t: %ld\n"
 		      "system serial number\t: %s\n"
-		      "cycle frequency [Hz]\t: %lu\n"
+		      "cycle frequency [Hz]\t: %lu %s\n"
 		      "timer frequency [Hz]\t: %lu.%02lu\n"
 		      "page size [bytes]\t: %ld\n"
 		      "phys. address bits\t: %ld\n"
@@ -691,7 +694,8 @@
 		       (char*)cpu->serial_no,
 		       systype_name, sysvariation_name, hwrpb->sys_revision,
 		       (char*)hwrpb->ssn,
-		       hwrpb->cycle_freq,
+		       hwrpb->cycle_freq ? : est_cycle_freq,
+		       hwrpb->cycle_freq ? "" : "est.",
 		       hwrpb->intr_freq / 4096,
 		       (100 * hwrpb->intr_freq / 4096) % 100,
 		       hwrpb->pagesize,
@@ -703,8 +707,8 @@
 		       platform_string());
 
 #ifdef __SMP__
-	return len + smp_info(buffer+len);
-#else
-	return len;
+	len += smp_info(buffer+len);
 #endif
+
+	return len;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c
--- v2.1.125/linux/arch/alpha/kernel/signal.c	Tue Jun 23 10:01:19 1998
+++ linux/arch/alpha/kernel/signal.c	Mon Oct 12 11:40:12 1998
@@ -33,9 +33,6 @@
 asmlinkage int do_signal(sigset_t *, struct pt_regs *,
 			 struct switch_stack *, unsigned long, unsigned long);
 
-extern int ptrace_set_bpt (struct task_struct *child);
-extern int ptrace_cancel_bpt (struct task_struct *child);
-
 
 /*
  * The OSF/1 sigprocmask calling sequence is different from the
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/smc37c93x.c linux/arch/alpha/kernel/smc37c93x.c
--- v2.1.125/linux/arch/alpha/kernel/smc37c93x.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/smc37c93x.c	Mon Oct 12 11:40:12 1998
@@ -8,6 +8,7 @@
 #include <linux/malloc.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
 #include <asm/hwrpb.h>
 #include <asm/io.h>
@@ -86,21 +87,28 @@
 	unsigned long indexPort;
 	unsigned long dataPort;
 
+	int i;
+
 	configPort = indexPort = baseAddr;
 	dataPort = configPort + 1;
 
-	outb(CONFIG_ON_KEY, configPort);
-	outb(CONFIG_ON_KEY, configPort);
-	outb(DEVICE_ID, indexPort);
-	devId = inb(dataPort);
-	if ( devId == VALID_DEVICE_ID ) {
-		outb(DEVICE_REV, indexPort);
-		devRev = inb(dataPort);
-	}
-	else {
-		baseAddr = 0;
+#define NUM_RETRIES 5
+
+	for (i = 0; i < NUM_RETRIES; i++)
+	{
+		outb(CONFIG_ON_KEY, configPort);
+		outb(CONFIG_ON_KEY, configPort);
+		outb(DEVICE_ID, indexPort);
+		devId = inb(dataPort);
+		if (devId == VALID_DEVICE_ID) {
+			outb(DEVICE_REV, indexPort);
+			devRev = inb(dataPort);
+			break;
+		}
+		else
+			udelay(100);
 	}
-	return baseAddr;
+	return (i != NUM_RETRIES) ? baseAddr : 0L;
 }
 
 static void __init SMCRunState(unsigned long baseAddr)
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.1.125/linux/arch/alpha/kernel/smp.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/smp.c	Mon Oct 12 11:40:12 1998
@@ -39,6 +39,7 @@
 
 unsigned int boot_cpu_id = 0;
 static int smp_activated = 0;
+static unsigned long ipicnt[NR_CPUS] = {0,}; /* IPI counts */
 
 int smp_found_config = 0; /* Have we found an SMP box */
 static int max_cpus = -1;
@@ -619,7 +620,6 @@
 {
 	tbia();
 	clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask);
-	mb();
 	return 0;
 }
 
@@ -627,12 +627,9 @@
 local_flush_tlb_mm(unsigned int this_cpu)
 {
 	struct mm_struct * mm = ipi_msg_flush_tb.p.flush_mm;
-	if (mm != current->mm)
-		flush_tlb_other(mm);
-	else
+	if (mm == current->mm)
 		flush_tlb_current(mm);
 	clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask);
-	mb();
 	return 0;
 }
 
@@ -642,12 +639,9 @@
 	struct vm_area_struct * vma = ipi_msg_flush_tb.p.flush_vma;
 	struct mm_struct * mm = vma->vm_mm;
 
-	if (mm != current->mm)
-		flush_tlb_other(mm);
-	else
+	if (mm == current->mm)
 		flush_tlb_current_page(mm, vma, ipi_msg_flush_tb.flush_addr);
 	clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask);
-	mb();
 	return 0;
 }
 
@@ -701,7 +695,7 @@
 	volatile int * pending_ipis = &ipi_bits[this_cpu];
 	int ops;
 
-	mb();
+	mb();		/* Order bit setting and interrupt. */
 #if 0
 	printk("handle_ipi: on CPU %d ops 0x%x PC 0x%lx\n",
 	       this_cpu, *pending_ipis, regs->pc);
@@ -711,10 +705,10 @@
 		for (first = 0; (ops & 1) == 0; ++first, ops >>= 1)
 			; /* look for the first thing to do */
 		clear_bit(first, pending_ipis);
-		mb();
+		mb();	/* Order bit clearing and data access. */
 		if ((*ipi_func[first])(this_cpu))
-		  printk("%d\n", first);
-		mb();
+			printk("%d\n", first);
+		mb();	/* Order data access and bit clearing. */
 	}
 	if (hwrpb->txrdy)
 	  secondary_console_message();
@@ -726,19 +720,26 @@
 	int i;
 	unsigned int j;
 
+	mb();			/* Order out-of-band data and bit setting. */
 	for (i = 0, j = 1; i < NR_CPUS; ++i, j += j) {
 		if ((to_whom & j) == 0)
 			continue;
 		set_bit(operation, &ipi_bits[i]);
-		mb();
+		mb();		/* Order bit setting and interrupt. */
 		wripir(i);
 	}
 }
 
-int smp_info(char *buffer)
+int
+smp_info(char *buffer)
 {
-        return sprintf(buffer, "CPUs probed %d active %d map 0x%x\n",
-		       smp_num_probed, smp_num_cpus, cpu_present_map);
+	int i;
+	unsigned long sum = 0;
+	for (i = 0; i < NR_CPUS; i++)
+		sum += ipicnt[i];
+
+        return sprintf(buffer, "CPUs probed %d active %d map 0x%x IPIs %ld\n",
+		       smp_num_probed, smp_num_cpus, cpu_present_map, sum);
 }
 
 /* wrapper for call from panic() */
@@ -763,19 +764,22 @@
 	unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id());
 	int timeout = 10000;
 
+	spin_lock_own(&kernel_flag, "flush_tlb_all");
+
 	ipi_msg_flush_tb.flush_tb_mask = to_whom;
 	send_ipi_message(to_whom, TLB_ALL);
 	tbia();
 
 	while (ipi_msg_flush_tb.flush_tb_mask) {
-	  if (--timeout < 0) {
-	    printk("flush_tlb_all: STUCK on CPU %d mask 0x%x\n",
-		   smp_processor_id(), ipi_msg_flush_tb.flush_tb_mask);
-	    ipi_msg_flush_tb.flush_tb_mask = 0;
-	    break;
-	  }
-	  udelay(100);
-		; /* Wait for all clear from other CPUs. */
+		if (--timeout < 0) {
+			printk("flush_tlb_all: STUCK on CPU %d mask 0x%x\n",
+			       smp_processor_id(),
+			       ipi_msg_flush_tb.flush_tb_mask);
+			ipi_msg_flush_tb.flush_tb_mask = 0;
+			break;
+		}
+		/* Wait for all clear from other CPUs. */
+		udelay(100);
 	}
 }
 
@@ -785,6 +789,8 @@
 	unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id());
 	int timeout = 10000;
 
+	spin_lock_own(&kernel_flag, "flush_tlb_mm");
+
 	ipi_msg_flush_tb.p.flush_mm = mm;
 	ipi_msg_flush_tb.flush_tb_mask = to_whom;
 	send_ipi_message(to_whom, TLB_MM);
@@ -814,6 +820,8 @@
 	struct mm_struct * mm = vma->vm_mm;
 	int timeout = 10000;
 
+	spin_lock_own(&kernel_flag, "flush_tlb_page");
+
 	ipi_msg_flush_tb.p.flush_vma = vma;
 	ipi_msg_flush_tb.flush_addr = addr;
 	ipi_msg_flush_tb.flush_tb_mask = to_whom;
@@ -849,6 +857,8 @@
 	timeout = 10000;
 	to_whom = cpu_present_map ^ (1 << smp_processor_id());
 
+	spin_lock_own(&kernel_flag, "flush_tlb_range");
+
 	ipi_msg_flush_tb.p.flush_mm = mm;
 	ipi_msg_flush_tb.flush_tb_mask = to_whom;
 	send_ipi_message(to_whom, TLB_MM);
@@ -871,11 +881,51 @@
 }
 
 #if DEBUG_SPINLOCK
-void spin_lock(spinlock_t * lock)
+
+#ifdef MANAGE_SPINLOCK_IPL
+
+static inline long 
+spinlock_raise_ipl(spinlock_t * lock)
+{
+ 	long min_ipl = lock->target_ipl;
+	long last_ipl = swpipl(7);
+	if (last_ipl < 7 && min_ipl < 7)
+		setipl(min_ipl < last_ipl ? last_ipl : min_ipl);
+	return last_ipl;
+}
+
+static inline void
+spinlock_restore_ipl(long prev)
+{
+	setipl(prev);
+}
+
+#else
+
+#define spinlock_raise_ipl(LOCK)	0
+#define spinlock_restore_ipl(PREV)	((void)0)
+
+#endif /* MANAGE_SPINLOCK_IPL */
+
+void
+spin_unlock(spinlock_t * lock)
+{
+	long old_ipl = lock->saved_ipl;
+	mb();
+	lock->lock = 0;
+	spinlock_restore_ipl(old_ipl);
+}
+
+void
+spin_lock(spinlock_t * lock)
 {
 	long tmp;
-	long stuck;
+	long stuck = 1<<27;
 	void *inline_pc = __builtin_return_address(0);
+	unsigned long started = jiffies;
+	int printed = 0;
+	int cpu = smp_processor_id();
+	long old_ipl = spinlock_raise_ipl(lock);
 
  try_again:
 
@@ -885,15 +935,15 @@
 	   of this object file's text section so as to perfect
 	   branch prediction.  */
 	__asm__ __volatile__(
-	"1:	ldq_l	%0,%1\n"
+	"1:	ldl_l	%0,%1\n"
 	"	subq	%2,1,%2\n"
 	"	blbs	%0,2f\n"
 	"	or	%0,1,%0\n"
-	"	stq_c	%0,%1\n"
+	"	stl_c	%0,%1\n"
 	"	beq	%0,3f\n"
 	"4:	mb\n"
 	".section .text2,\"ax\"\n"
-	"2:	ldq	%0,%1\n"
+	"2:	ldl	%0,%1\n"
 	"	subq	%2,1,%2\n"
 	"3:	blt	%2,4b\n"
 	"	blbs	%0,2b\n"
@@ -905,13 +955,43 @@
 	: "2" (stuck));
 
 	if (stuck < 0) {
-		printk("spinlock stuck at %p (cur=%p, own=%p, prev=%p)\n",
-		       inline_pc, current, lock->task, lock->previous);
+		if (!printed) {
+			printk("spinlock stuck at %p(%d) owner %s at %p\n",
+			       inline_pc, cpu, lock->task->comm,
+			       lock->previous);
+			printed = 1;
+		}
+		stuck = 1<<30;
 		goto try_again;
-	} else {
-		lock->previous = inline_pc;
+	}
+
+	/* Exiting.  Got the lock.  */
+	lock->saved_ipl = old_ipl;
+	lock->on_cpu = cpu;
+	lock->previous = inline_pc;
+	lock->task = current;
+
+	if (printed) {
+		printk("spinlock grabbed at %p(%d) %ld ticks\n",
+		       inline_pc, cpu, jiffies - started);
+	}
+}
+
+int
+spin_trylock(spinlock_t * lock)
+{
+	long old_ipl = spinlock_raise_ipl(lock);
+	int ret;
+	if ((ret = !test_and_set_bit(0, lock))) {
+		mb();
+		lock->saved_ipl = old_ipl;
+		lock->on_cpu = smp_processor_id();
+		lock->previous = __builtin_return_address(0);
 		lock->task = current;
+	} else {
+		spinlock_restore_ipl(old_ipl);
 	}
+	return ret;
 }
 #endif /* DEBUG_SPINLOCK */
 
@@ -930,22 +1010,21 @@
 	__asm__ __volatile__(
 	"1:	ldl_l	%1,%0\n"
 	"	blbs	%1,6f\n"
-	"	or	%1,1,%2\n"
-	"	stl_c	%2,%0\n"
-	"	beq	%2,6f\n"
 	"	blt	%1,8f\n"
+	"	mov	1,%1\n"
+	"	stl_c	%1,%0\n"
+	"	beq	%1,6f\n"
 	"4:	mb\n"
 	".section .text2,\"ax\"\n"
-	"6:	ldl	%1,%0\n"
-	"	blt	%3,4b	# debug\n"
+	"6:	blt	%3,4b	# debug\n"
 	"	subl	%3,1,%3	# debug\n"
+	"	ldl	%1,%0\n"
 	"	blbs	%1,6b\n"
-	"	br	1b\n"
-	"8:	ldl	%1,%0\n"
-	"	blt	%4,4b	# debug\n"
+	"8:	blt	%4,4b	# debug\n"
 	"	subl	%4,1,%4	# debug\n"
+	"	ldl	%1,%0\n"
 	"	blt	%1,8b\n"
-	"	br	4b\n"
+	"	br	1b\n"
 	".previous"
 	: "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (regy)
 	, "=&r" (stuck_lock), "=&r" (stuck_reader)
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/sys_jensen.c linux/arch/alpha/kernel/sys_jensen.c
--- v2.1.125/linux/arch/alpha/kernel/sys_jensen.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/sys_jensen.c	Mon Oct 12 11:40:12 1998
@@ -128,7 +128,7 @@
 	BUS(jensen),
 	machine_check:		jensen_machine_check,
 	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
-	rtc_port: 0x170, rtc_addr: 0, rtc_bcd: 1,
+	rtc_port: 0x170,
 
 	nr_irqs:		16,
 	irq_probe_mask:		_PROBE_MASK(16),
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c
--- v2.1.125/linux/arch/alpha/kernel/sys_ruffian.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/sys_ruffian.c	Mon Oct 12 11:40:12 1998
@@ -247,8 +247,7 @@
 struct alpha_machine_vector ruffian_mv __initmv = {
 	vector_name:		"Ruffian",
 	DO_EV5_MMU,
-	/* RUFFIAN always uses BCD, like a PeeCee.  */
-	rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 1,
+	DO_DEFAULT_RTC,
 	/* For the moment, do not use BWIO on RUFFIAN.  */
 	IO(PYXIS,pyxis,pyxis),
 	DO_PYXIS_BUS,
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c
--- v2.1.125/linux/arch/alpha/kernel/sys_sx164.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/sys_sx164.c	Mon Oct 12 11:40:12 1998
@@ -103,7 +103,10 @@
 static void
 sx164_init_irq(void)
 {
-	STANDARD_INIT_IRQ_PROLOG;
+	outb(0, DMA1_RESET_REG);
+	outb(0, DMA2_RESET_REG);
+	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+	outb(0, DMA2_MASK_REG);
 
 	if (alpha_using_srm) {
 		alpha_mv.update_irq_hw = sx164_srm_update_irq_hw;
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.1.125/linux/arch/alpha/kernel/time.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/kernel/time.c	Tue Oct 20 09:43:21 1998
@@ -62,11 +62,13 @@
 	time_t last_rtc_update;
 } state;
 
+unsigned long est_cycle_freq;
+
 
 static inline __u32 rpcc(void)
 {
     __u32 result;
-    asm volatile ("rpcc %0" : "r="(result));
+    asm volatile ("rpcc %0" : "=r"(result));
     return result;
 }
 
@@ -162,7 +164,7 @@
  * drivers depend on them being initialized (e.g., joystick driver).
  */
 
-/* It is (normally) only counter 1 that presents config problems, so
+/* It is (normally) only counter 0 that presents config problems, so
    provide this support function to do the rest of the job.  */
 
 void inline
@@ -184,12 +186,20 @@
 static inline void
 rtc_init_pit (void)
 {
+	unsigned char control;
+
 	/* Setup interval timer if /dev/rtc is being used */
 	outb(0x34, 0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
 	outb(LATCH & 0xff, 0x40);	/* LSB */
 	outb(LATCH >> 8, 0x40);		/* MSB */
 	request_region(0x40, 0x20, "timer"); /* reserve pit */
 
+	/* Turn off RTC interrupts before /dev/rtc is initialized */
+	control = CMOS_READ(RTC_CONTROL);
+        control &= ~(RTC_PIE | RTC_AIE | RTC_UIE);
+        CMOS_WRITE(control, RTC_CONTROL);
+        CMOS_READ(RTC_INTR_FLAGS);
+
 	init_pit_rest();
 }
 #endif
@@ -197,11 +207,25 @@
 void
 generic_init_pit (void)
 {
-	int x;
-	if ((x = (CMOS_READ(RTC_FREQ_SELECT) & 0x3f)) != 0x26) {
+	unsigned char x;
+
+        /* Reset periodic interrupt frequency.  */
+	x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f;
+	if (x != 0x26 && x != 0x19 && x != 0x06) {
 		printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x);
 		CMOS_WRITE(0x26, RTC_FREQ_SELECT);
 	}
+
+	/* Turn on periodic interrupts.  */
+	x = CMOS_READ(RTC_CONTROL);
+	if (!(x & RTC_PIE)) {
+		printk("Turning on RTC interrupts.\n");
+		x |= RTC_PIE;
+		x &= ~(RTC_AIE | RTC_UIE);
+		CMOS_WRITE(x, RTC_CONTROL);
+	}
+	CMOS_READ(RTC_INTR_FLAGS);
+
 	request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */
 
 	/* Turn off the PIT.  */
@@ -223,11 +247,9 @@
 void
 time_init(void)
 {
-#ifdef CONFIG_RTC
-	unsigned char save_control;
-#endif
         void (*irq_handler)(int, void *, struct pt_regs *);
 	unsigned int year, mon, day, hour, min, sec, cc1, cc2;
+	unsigned long cycle_freq;
 
 	/* Initialize the timers.  */
 	init_pit();
@@ -246,16 +268,17 @@
 
 	/* If our cycle frequency isn't valid, go another round and give
 	   a guess at what it should be.  */
-	if (hwrpb->cycle_freq == 0) {
+	cycle_freq = hwrpb->cycle_freq;
+	if (cycle_freq == 0) {
 		printk("HWRPB cycle frequency bogus.  Estimating... ");
 
 		do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
 		do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
 		cc2 = rpcc();
-		hwrpb->cycle_freq = cc2 - cc1;
+		est_cycle_freq = cycle_freq = cc2 - cc1;
 		cc1 = cc2;
 
-		printk("%lu Hz\n", hwrpb->cycle_freq);
+		printk("%lu Hz\n", cycle_freq);
 	}
 
 	/* From John Bowman <bowman@math.ualberta.ca>: allow the values
@@ -300,18 +323,8 @@
 
 	state.last_time = cc1;
 	state.scaled_ticks_per_cycle
-		= ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
+		= ((unsigned long) HZ << FIX_SHIFT) / cycle_freq;
 	state.last_rtc_update = 0;
-
-#ifdef CONFIG_RTC 
-	/* turn off RTC interrupts before /dev/rtc is initialized */
-	save_control = CMOS_READ(RTC_CONTROL);
-        save_control &= ~RTC_PIE;
-        save_control &= ~RTC_AIE;
-        save_control &= ~RTC_UIE;
-        CMOS_WRITE(save_control, RTC_CONTROL);
-        CMOS_READ(RTC_INTR_FLAGS);
-#endif
 
 	/* setup timer */ 
         irq_handler = timer_interrupt;
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.1.125/linux/arch/alpha/kernel/traps.c	Tue Aug 18 22:02:02 1998
+++ linux/arch/alpha/kernel/traps.c	Mon Oct 12 11:40:12 1998
@@ -149,8 +149,6 @@
 			 unsigned long a2, unsigned long a3, unsigned long a4,
 			 unsigned long a5, struct pt_regs regs)
 {
-	extern int ptrace_cancel_bpt (struct task_struct *who);
-
 	lock_kernel();
 	die_if_kernel("Instruction fault", &regs, type, 0);
 	switch (type) {
@@ -558,11 +556,12 @@
 
 #define OP_INT_MASK	( 1L << 0x28 | 1L << 0x2c   /* ldl stl */	\
 			| 1L << 0x29 | 1L << 0x2d   /* ldq stq */	\
-			| 1L << 0x0c | 1L << 0x0d ) /* ldwu stw */
+			| 1L << 0x0c | 1L << 0x0d   /* ldwu stw */	\
+			| 1L << 0x0a | 1L << 0x0e ) /* ldbu stb */
 
 #define OP_WRITE_MASK	( 1L << 0x26 | 1L << 0x27   /* sts stt */	\
 			| 1L << 0x2c | 1L << 0x2d   /* stl stq */	\
-			| 1L << 0xd )		    /* stw */
+			| 1L << 0x0d | 1L << 0x0e ) /* stw stb */
 
 #define R(x)	((size_t) &((struct pt_regs *)0)->x)
 
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- v2.1.125/linux/arch/alpha/lib/Makefile	Tue Aug 18 22:02:02 1998
+++ linux/arch/alpha/lib/Makefile	Mon Oct 12 11:40:12 1998
@@ -7,7 +7,8 @@
 	strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
 	strchr.o strrchr.o \
 	copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
-	csum_ipv6_magic.o strcasecmp.o
+	csum_ipv6_magic.o strcasecmp.o \
+	srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
 
 lib.a: $(OBJS)
 	$(AR) rcs lib.a $(OBJS)
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_dispatch.S linux/arch/alpha/lib/srm_dispatch.S
--- v2.1.125/linux/arch/alpha/lib/srm_dispatch.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/srm_dispatch.S	Mon Oct 12 11:40:12 1998
@@ -0,0 +1,43 @@
+/*
+ *	arch/alpha/lib/srm_dispatch.S
+ */
+
+.globl	srm_dispatch
+.ent	srm_dispatch
+srm_dispatch:
+	.frame	$30,30,$26
+	subq	$30,80,$30
+	stq	$26,0($30)
+	stq	$8,8($30)
+	stq	$9,16($30)
+	stq	$10,24($30)
+	stq	$11,32($30)
+	stq	$12,40($30)
+	stq	$13,48($30)
+	stq	$14,56($30)
+	stq	$15,64($30)
+	stq	$29,72($30)
+	.mask	0x2400FF00, -80
+	.prologue 0
+
+	ldq	$1,hwrpb
+	ldq	$2,0xc0($1)		/* crb offset */
+	addq	$2,$1,$2		/* crb */
+	ldq	$27,0($2)		/* dispatch procedure value */
+
+	ldq	$2,8($27)		/* dispatch call address */
+	jsr	$26,($2)		/* call it (weird VMS call seq) */
+
+	ldq	$26,0($30)
+	ldq	$8,8($30)
+	ldq	$9,16($30)
+	ldq	$10,24($30)
+	ldq	$11,32($30)
+	ldq	$12,40($30)
+	ldq	$13,48($30)
+	ldq	$14,56($30)
+	ldq	$15,64($30)
+	ldq	$29,72($30)
+	addq	$30,80,$30
+	ret	$31,($26),1
+.end    srm_dispatch
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_fixup.S linux/arch/alpha/lib/srm_fixup.S
--- v2.1.125/linux/arch/alpha/lib/srm_fixup.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/srm_fixup.S	Mon Oct 12 11:40:12 1998
@@ -0,0 +1,42 @@
+/*
+ *	arch/alpha/lib/srm_fixup.S
+ */
+
+.globl	srm_fixup
+.ent	srm_fixup
+srm_fixup:
+	.frame	$30,30,$26
+	subq	$30,80,$30
+	stq	$26,0($30)
+	stq	$8,8($30)
+	stq	$9,16($30)
+	stq	$10,24($30)
+	stq	$11,32($30)
+	stq	$12,40($30)
+	stq	$13,48($30)
+	stq	$14,56($30)
+	stq	$15,64($30)
+	stq	$29,72($30)
+	.mask	0x2400FF00, -80
+	.prologue 0
+
+	ldq	$2,0xc0($17)		/* crb offset */
+	addq	$2,$1,$2		/* crb */
+	ldq	$27,16($2)		/* fixup procedure value */
+
+	ldq	$2,8($27)		/* dispatch call address */
+	jsr	$26,($2)		/* call it (weird VMS call seq) */
+
+	ldq	$26,0($30)
+	ldq	$8,8($30)
+	ldq	$9,16($30)
+	ldq	$10,24($30)
+	ldq	$11,32($30)
+	ldq	$12,40($30)
+	ldq	$13,48($30)
+	ldq	$14,56($30)
+	ldq	$15,64($30)
+	ldq	$29,72($30)
+	addq	$30,80,$30
+	ret	$31,($26),1
+.end    srm_fixup
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_printk.c linux/arch/alpha/lib/srm_printk.c
--- v2.1.125/linux/arch/alpha/lib/srm_printk.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/srm_printk.c	Mon Oct 12 11:40:12 1998
@@ -0,0 +1,21 @@
+/*
+ *	arch/alpha/lib/srm_printk.c
+ */
+
+#include <linux/kernel.h>
+#include <asm/console.h>
+
+long
+srm_printk(const char *fmt, ...)
+{
+	static char buf[1024];
+        va_list args;
+        long i;
+
+        va_start(args, fmt);
+        i = vsprintf(buf,fmt,args);
+        va_end(args);
+
+	srm_puts(buf);	
+        return i;
+}
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_puts.c linux/arch/alpha/lib/srm_puts.c
--- v2.1.125/linux/arch/alpha/lib/srm_puts.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/srm_puts.c	Mon Oct 12 11:40:12 1998
@@ -0,0 +1,34 @@
+/*
+ *	arch/alpha/lib/srm_puts.c
+ */
+
+#include <linux/string.h>
+#include <asm/console.h>
+
+void
+srm_puts(const char *str)
+{
+	/* Expand \n to \r\n as we go.  */
+
+	while (*str) {
+		long len;
+		const char *e = str;
+
+		if (*str == '\n') {
+			if (srm_dispatch(CCB_PUTS, 0, "\r", 1) < 0)
+				return;
+			++e;
+		}
+
+		e = strchr(e, '\n') ? : strchr(e, '\0');
+		len = e - str;
+
+		while (len > 0) {
+			long written = srm_dispatch(CCB_PUTS, 0, str, len);
+			if (written < 0)
+				return;
+			len -= written & 0xffffffff;
+			str += written & 0xffffffff;
+		}
+	}
+}
diff -u --recursive --new-file v2.1.125/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
--- v2.1.125/linux/arch/alpha/mm/init.c	Wed Sep  9 14:51:04 1998
+++ linux/arch/alpha/mm/init.c	Mon Oct 12 11:40:12 1998
@@ -30,7 +30,7 @@
 extern void die_if_kernel(char *,struct pt_regs *,long);
 extern void show_net_buffers(void);
 
-struct thread_struct * original_pcb_ptr;
+struct thread_struct original_pcb;
 
 #ifndef __SMP__
 struct pgtable_cache_struct quicklists;
@@ -193,47 +193,66 @@
 	unsigned long newptbr;
 	struct memclust_struct * cluster;
 	struct memdesc_struct * memdesc;
+	struct thread_struct *original_pcb_ptr;
 
 	/* initialize mem_map[] */
 	start_mem = free_area_init(start_mem, end_mem);
 
 	/* find free clusters, update mem_map[] accordingly */
 	memdesc = (struct memdesc_struct *)
-		(INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
+		(hwrpb->mddt_offset + (unsigned long) hwrpb);
 	cluster = memdesc->cluster;
 	for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
 		unsigned long pfn, nr;
-		if (cluster->usage & 1)
+
+		/* Bit 0 is console/PALcode reserved.  Bit 1 is
+		   non-volatile memory -- we might want to mark
+		   this for later */
+		if (cluster->usage & 3)
 			continue;
 		pfn = cluster->start_pfn;
 		nr = cluster->numpages;
 
-		/* non-volatile memory. We might want to mark this for later */
-		if (cluster->usage & 2)
-			continue;
-
 		while (nr--)
 			clear_bit(PG_reserved, &mem_map[pfn++].flags);
 	}
 
-	/* unmap the console stuff: we don't need it, and we don't want it */
-	/* Also set up the real kernel PCB while we're at it.. */
+	/* Initialize the kernel's page tables.  Linux puts the vptb in
+	   the last slot of the L1 page table.  */
 	memset((void *) ZERO_PAGE, 0, PAGE_SIZE);
 	memset(swapper_pg_dir, 0, PAGE_SIZE);
 	newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
 	pgd_val(swapper_pg_dir[1023]) =
 		(newptbr << 32) | pgprot_val(PAGE_KERNEL);
+
+	/* Set the vptb.  This is often done by the bootloader, but 
+	   shouldn't be required.  */
+	if (hwrpb->vptb != 0xfffffffe00000000) {
+		wrvptptr(0xfffffffe00000000);
+		hwrpb->vptb = 0xfffffffe00000000;
+		hwrpb_update_checksum(hwrpb);
+	}
+
+	/* Also set up the real kernel PCB while we're at it.  */
 	init_task.tss.ptbr = newptbr;
 	init_task.tss.pal_flags = 1;	/* set FEN, clear everything else */
 	init_task.tss.flags = 0;
-	original_pcb_ptr =
-	  phys_to_virt((unsigned long)load_PCB(&init_task.tss));
-#if 0
-printk("OKSP 0x%lx OPTBR 0x%lx\n",
-       original_pcb_ptr->ksp, original_pcb_ptr->ptbr);
-#endif
-
+	original_pcb_ptr = load_PCB(&init_task.tss);
 	tbia();
+
+	/* Save off the contents of the original PCB so that we can
+	   restore the original console's page tables for a clean reboot.
+
+	   Note that the PCB is supposed to be a physical address, but
+	   since KSEG values also happen to work, folks get confused.
+	   Check this here.  */
+
+	if ((unsigned long)original_pcb_ptr < PAGE_OFFSET) {
+		original_pcb_ptr = (struct thread_struct *)
+		  phys_to_virt((unsigned long) original_pcb_ptr);
+	}
+	original_pcb = *original_pcb_ptr;
+
 	return start_mem;
 }
 
@@ -250,18 +269,29 @@
 	current->tss.ptbr = init_task.tss.ptbr;
 	current->tss.pal_flags = 1;
 	current->tss.flags = 0;
-
-#if 0
-printk("paging_init_secondary: KSP 0x%lx PTBR 0x%lx\n",
-       current->tss.ksp, current->tss.ptbr);
-#endif
-
 	load_PCB(&current->tss);
 	tbia();
 
 	return;
 }
 #endif /* __SMP__ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
+void
+srm_paging_stop (void)
+{
+	/* Move the vptb back to where the SRM console expects it.  */
+	swapper_pg_dir[1] = swapper_pg_dir[1023];
+	tbia();
+	wrvptptr(0x200000000);
+	hwrpb->vptb = 0x200000000;
+	hwrpb_update_checksum(hwrpb);
+
+	/* Reload the page tables that the console had in use.  */
+	load_PCB(&original_pcb);
+	tbia();
+}
+#endif
 
 #if DEBUG_POISON
 static void
diff -u --recursive --new-file v2.1.125/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.1.125/linux/arch/i386/defconfig	Fri Oct  9 13:27:05 1998
+++ linux/arch/i386/defconfig	Fri Oct 23 10:13:39 1998
@@ -266,6 +266,7 @@
 CONFIG_PROC_FS=y
 CONFIG_NFS_FS=y
 CONFIG_NFSD=y
+# CONFIG_NFSD_SUN is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_CODA_FS is not set
diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.1.125/linux/arch/i386/kernel/bios32.c	Mon Sep 28 10:51:33 1998
+++ linux/arch/i386/kernel/bios32.c	Fri Oct 23 08:25:05 1998
@@ -346,7 +346,7 @@
  * attempt to make use of direct access hints provided by the PCI BIOS).
  *
  * This should be close to trivial, but it isn't, because there are buggy
- * chipsets (yes, you guessed it, by Intel) that have no class ID.
+ * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
  */
 __initfunc(int pci_sanity_check(struct pci_access *a))
 {
@@ -356,9 +356,9 @@
 		return 1;
 	for(dfn=0; dfn < 0x100; dfn++)
 		if ((!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &x) &&
-		     x == PCI_CLASS_BRIDGE_HOST) ||
+		     (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
 		    (!a->read_config_word(0, dfn, PCI_VENDOR_ID, &x) &&
-		     x == PCI_VENDOR_ID_INTEL))
+		     (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
 			return 1;
 	DBG("PCI: Sanity check failed\n");
 	return 0;
@@ -1063,6 +1063,16 @@
 			if (pin) {
 				pin--;		/* interrupt pins are numbered starting from 1 */
 				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
+				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
+					struct pci_dev * bridge = dev->bus->self;
+
+					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
+					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
+							PCI_SLOT(bridge->devfn), pin);
+					if (irq >= 0)
+						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
+							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
+				}
 				if (irq >= 0) {
 					printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
 						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/mca.c linux/arch/i386/kernel/mca.c
--- v2.1.125/linux/arch/i386/kernel/mca.c	Wed Aug 26 11:37:33 1998
+++ linux/arch/i386/kernel/mca.c	Sat Oct 17 15:33:45 1998
@@ -3,11 +3,29 @@
  *  Written by Martin Kolinek, February 1996
  *
  * Changes:
- *   July 28, 1996: fixed up integrated SCSI detection. Chris Beauregard
- *   August 3rd, 1996: made mca_info local, made integrated registers
- *     accessible through standard function calls, added name field,
- *     more sanity checking. Chris Beauregard
- *   August 9, 1996: Rewrote /proc/mca.  cpbeaure
+ *
+ *	Chris Beauregard July 28th, 1996
+ *	- Fixed up integrated SCSI detection
+ *
+ *	Chris Beauregard August 3rd, 1996
+ *	- Made mca_info local
+ *	- Made integrated registers accessible through standard function calls
+ *	- Added name field
+ *	- More sanity checking
+ *
+ *	Chris Beauregard August 9th, 1996
+ *	- Rewrote /proc/mca
+ *	
+ *	Chris Beauregard January 7th, 1997
+ *	- Added basic NMI-processing
+ *	- Added more information to mca_info structure
+ *
+ *	David Weinehall October 12th, 1998
+ *	- Made a lot of cleaning up in the source
+ *	- Added use of save_flags / restore_flags
+ *	- Added the 'driver_loaded' flag in MCA_adapter
+ *	- Added an alternative implemention of ZP Gu's mca_find_unused_adapter
+ *
  */
 
 #include <linux/types.h>
@@ -29,19 +47,38 @@
  * eight POS registers. Then the machine may have integrated video and
  * SCSI subsystems, which also have eight POS registers.
  * Other miscellaneous information follows.
-*/
+ */
+
+typedef enum {                                                                  
+	MCA_ADAPTER_NORMAL = 0,                                                 
+	MCA_ADAPTER_NONE = 1,                                                   
+	MCA_ADAPTER_DISABLED = 2,                                               
+	MCA_ADAPTER_ERROR = 3                                                   
+} MCA_AdapterStatus;    
+
 struct MCA_adapter {
-	unsigned char pos[8];	/* POS registers */
-	char name[32];		/* name of the device - provided by driver */
-	char procname[8];	/* name of /proc/mca file */
-	MCA_ProcFn procfn;	/* /proc info callback */
-	void* dev;		/* device/context info for callback */
+	MCA_AdapterStatus status;	/* is there a valid adapter? */
+	int id;				/* adapter id value */
+	unsigned char pos[8];		/* POS registers */
+	int driver_loaded;		/* is there a driver installed? */
+					/* 0 - No, 1 - Yes */
+	char name[48];			/* adapter-name provided by driver */
+	char procname[8];		/* name of /proc/mca file */
+	MCA_ProcFn procfn;		/* /proc info callback */
+	void* dev;			/* device/context info for callback */
 };
 
 struct MCA_info {
-	/* one for each of the 8 possible slots, plus one for integrated SCSI
-	and one for integrated video. */
+/* one for each of the 8 possible slots, plus one for integrated SCSI
+   and one for integrated video. */
+
 	struct MCA_adapter slot[MCA_NUMADAPTERS];
+
+/* two potential addresses for integrated SCSI adapter - this will      
+ * track which one we think it is
+ */                                       
+
+	unsigned char which_scsi;  
 };
 
 /* The mca_info structure pointer. If MCA bus is present, the function
@@ -49,70 +86,145 @@
  * adapters into setup mode, allocates and fills an MCA_info structure,
  * and points this pointer to the structure. Otherwise the pointer 
  * is set to zero.
-*/
+ */
+
 static struct MCA_info* mca_info = 0;
 
-/*MCA registers*/
-#define MCA_MOTHERBOARD_SETUP_REG  0x94
-#define MCA_ADAPTER_SETUP_REG      0x96
-#define MCA_POS_REG(n)             (0x100+(n))
+/* MCA registers */
+
+#define MCA_MOTHERBOARD_SETUP_REG	0x94
+#define MCA_ADAPTER_SETUP_REG		0x96
+#define MCA_POS_REG(n)			(0x100+(n))
 
 #define MCA_ENABLED	0x01	/* POS 2, set if adapter enabled */
 
 /*--------------------------------------------------------------------*/
 
 #ifdef CONFIG_PROC_FS
+
 static void mca_do_proc_init( void );
 static int mca_default_procfn( char* buf, int slot );
 
 static ssize_t proc_mca_read( struct file*, char*, size_t, loff_t *);
+
 static struct file_operations proc_mca_operations = {
-	NULL, proc_mca_read,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+	NULL,			/* array_lseek */
+	proc_mca_read,		/* array_read */
+	NULL,			/* array_write */
+	NULL,			/* array_readdir */
+	NULL,			/* array_poll */
+	NULL,			/* array_ioctl */
+	NULL,			/* mmap */
+	NULL,			/* no special open code */
+	NULL,			/* flush */
+	NULL,			/* no special release code */
+	NULL			/* can't fsync */
 };
+
 static struct inode_operations proc_mca_inode_operations = {
-	&proc_mca_operations,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+	&proc_mca_operations,	/* default base directory file-ops */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	NULL,			/* readpage */
+	NULL,			/* writepage */
+	NULL,			/* bmap */
+	NULL,			/* truncate */
+	NULL			/* permission */
 };
 #endif
 
 /*--------------------------------------------------------------------*/
 
+/* Build the status info for the adapter */
+
+static void mca_configure_adapter_status( int slot ) {
+	mca_info->slot[slot].status = MCA_ADAPTER_NONE;
+
+	mca_info->slot[slot].id = mca_info->slot[slot].pos[0]
+		+ (mca_info->slot[slot].pos[1] << 8);
+
+	if( !mca_info->slot[slot].id ) {
+
+		/* id = 0x0000 usually indicates hardware failure,
+		 * however, ZP Gu (zpg@castle.net> reports that his 9556
+		 * has 0x0000 as id and everything still works.
+		 */
+
+		mca_info->slot[slot].status = MCA_ADAPTER_ERROR;
+
+		return;
+	} else if( mca_info->slot[slot].id != 0xffff ) {
+
+		/* 0xffff usually indicates that there's no adapter,
+		 * however, some integrated adapters may have 0xffff as
+		 * their id and still be valid. Examples are on-board
+		 * VGA of the 55sx, the integrated SCSI of the 56 & 57,
+		 * and possibly also the 95 ULTIMEDIA.
+		 */
+
+		mca_info->slot[slot].status = MCA_ADAPTER_NORMAL;
+	}
+
+	if( (mca_info->slot[slot].id == 0xffff ||
+	     mca_info->slot[slot].id == 0x0000) && slot >= MCA_MAX_SLOT_NR ) {
+		int j;
+
+		for( j = 2; j < 8; j++ ) {
+			if( mca_info->slot[slot].pos[j] != 0xff ) {
+				mca_info->slot[slot].status = MCA_ADAPTER_NORMAL;
+				break;
+			}
+		}
+	}
+
+	if( !(mca_info->slot[slot].pos[2] & MCA_ENABLED) ) {
+
+		/* enabled bit is in pos 2 */
+
+		mca_info->slot[slot].status = MCA_ADAPTER_DISABLED;
+	}
+} /* mca_configure_adapter_status */
+
+/*--------------------------------------------------------------------*/
+
 __initfunc(void mca_init(void))
 {
 	unsigned int  i, j;
-	int foundscsi = 0;
+	unsigned long flags;
 
 	/* WARNING: Be careful when making changes here. Putting an adapter
 	 * and the motherboard simultaneously into setup mode may result in 
 	 * damage to chips (according to The Indispensible PC Hardware Book 
 	 * by Hans-Peter Messmer). Also, we disable system interrupts (so  	
 	 * that we are not disturbed in the middle of this).
-	*/
-
-	/*
-	 *	Make sure the MCA bus is present
 	 */
+
+	/* Make sure the MCA bus is present */
 	
 	if (!MCA_bus)
 		return;
+	printk( "Micro Channel bus detected.\n" );
+	save_flags( flags );
 	cli();
 
-	/*
-	 *	Allocate MCA_info structure (at address divisible by 8)
-	 */ 
+	/* Allocate MCA_info structure (at address divisible by 8) */
 
 	mca_info = kmalloc(sizeof(struct MCA_info), GFP_ATOMIC);
 
-	/*
-	 *	Make sure adapter setup is off
-	 */
+	/* Make sure adapter setup is off */
 
 	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
-	/*
-	 *	Put motherboard into video setup mode, read integrated video 
+	/* Put motherboard into video setup mode, read integrated video 
 	 * pos registers, and turn motherboard setup off.
 	 */
 
@@ -121,6 +233,7 @@
 	for (j=0; j<8; j++) {
 		mca_info->slot[MCA_INTEGVIDEO].pos[j] = inb_p(MCA_POS_REG(j)); 
 	}
+	mca_configure_adapter_status(MCA_INTEGVIDEO);
 
 	/* Put motherboard into scsi setup mode, read integrated scsi
 	 * pos registers, and turn motherboard setup off.
@@ -132,51 +245,57 @@
 	 * a good bet that only one could be valid at a time.  This could
 	 * screw up though if one is used for something else on the other
 	 * machine.
-	*/
+	 */
 
 	outb_p(0xf7, MCA_MOTHERBOARD_SETUP_REG);
 	mca_info->slot[MCA_INTEGSCSI].name[0] = 0;
 	for (j=0; j<8; j++)  {
 		if( (mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff ) 
 		{
-	  		/* 0xff all across means no device.  0x00 means something's
-	  		broken, but a device is probably there.  However, if you get
-	  		0x00 from a motherboard register it won't matter what we
-	  		find.  For the record, on the 57SLC, the integrated SCSI
-	  		adapter has 0xffff for the adapter ID, but nonzero for
-	  		other registers.  */
-			foundscsi = 1;
+			/* 0xff all across means no device.  0x00 means something's
+			 * broken, but a device is probably there.  However, if you get
+			 * 0x00 from a motherboard register it won't matter what we
+			 * find.  For the record, on the 57SLC, the integrated SCSI
+			 * adapter has 0xffff for the adapter ID, but nonzero for
+			 * other registers.
+			 */
+
+			mca_info->which_scsi = 0xf7;
 		}
 	}
-	if( !foundscsi ) 
-	{
-		/* 
-		 *	Didn't find it at 0xfd, try somewhere else... 
-		 */
+	if( !mca_info->which_scsi ) { 
+
+		/* Didn't find it at 0xf7, try somewhere else... */
+		mca_info->which_scsi = 0xfd;
+
 		outb_p(0xfd, MCA_MOTHERBOARD_SETUP_REG);
 		for (j=0; j<8; j++) 
 			mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j)); 
 	}
-
+	mca_configure_adapter_status(MCA_INTEGSCSI);
+	
 	/* turn off motherboard setup */
+
 	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
 
-	/*
-	 *	Now loop over MCA slots: put each adapter into setup mode, and
-	 *	read its pos registers. Then put adapter setup off.
+	/* Now loop over MCA slots: put each adapter into setup mode, and
+	 * read its pos registers. Then put adapter setup off.
 	 */
 
 	for (i=0; i<MCA_MAX_SLOT_NR; i++) {
 		outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG);
-		for (j=0; j<8; j++)  mca_info->slot[i].pos[j]=inb_p(MCA_POS_REG(j)); 
+		for (j=0; j<8; j++) {
+			mca_info->slot[i].pos[j]=inb_p(MCA_POS_REG(j)); 
+		}
 		mca_info->slot[i].name[0] = 0;
+		mca_info->slot[i].driver_loaded = 0;
+		mca_configure_adapter_status(i);
 	}
 	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
-	/*
-	 *	Enable interrupts and return memory start
-	 */
-	sti();
+	/* Enable interrupts and return memory start */
+
+	restore_flags( flags );
 
 	request_region(0x60,0x01,"system control port B (MCA)");
 	request_region(0x90,0x01,"arbitration (MCA)");
@@ -193,29 +312,89 @@
 
 /*--------------------------------------------------------------------*/
 
-int mca_find_adapter( int id, int start ) 
+static void mca_handle_nmi_slot( int slot, int check_flag )
 {
-	int slot_id = 0;
-	unsigned char status = 0;
+        if( slot < MCA_MAX_SLOT_NR ) {                                          
+                printk( "NMI: caused by MCA adapter in slot %d (%s)\n", slot+1,
+                        mca_info->slot[slot].name );                            
+        } else if( slot == MCA_INTEGSCSI ) {                                    
+                printk( "NMI: caused by MCA integrated SCSI adapter (%s)\n",    
+                        mca_info->slot[slot].name );                            
+        } else if( slot == MCA_INTEGVIDEO ) {                                   
+                printk( "NMI: caused by MCA integrated video adapter (%s)\n",   
+                        mca_info->slot[slot].name );                            
+        }                                                                       
+                                                                                
+        /* more info available in pos 6 and 7? */                               
+
+        if( check_flag ) {                                                      
+                unsigned char pos6, pos7;                                       
+                                                                                
+                pos6 = mca_read_pos( slot, 6 );                                 
+                pos7 = mca_read_pos( slot, 7 );                                 
+                                                                                
+                printk( "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7 );      
+        }                                                                       
+                                                                                
+} /* mca_handle_nmi_slot */                                                     
+                                                                                
+/*--------------------------------------------------------------------*/        
+
+void mca_handle_nmi( void )
+{
+
+	int i;
+        unsigned char pos5;                                                     
+                                                                                
+        /* First try - scan the various adapters and see if a specific          
+         * adapter was responsible for the error
+	 */                                
+
+        for( i = 0; i < MCA_NUMADAPTERS; i += 1 ) {                             
+                                                                                
+                /* bit 7 of POS 5 is reset when this adapter has a hardware     
+                 * error.  bit 7 it reset if there's error information
+                 * available in pos 6 and 7. */                                              
+                                                                                
+                pos5 = mca_read_pos( i, 5 );                                    
+                                                                                
+                if( !(pos5 & 0x80) ) {                                          
+                        mca_handle_nmi_slot( i, !(pos5 & 0x40) );               
+                        return;                                                 
+                }                                                               
+        }                                                                       
+                                                                                
+        /* if I recall correctly, there's a whole bunch of other things that    
+         * we can do to check for NMI problems, but that's all I know about
+	 * at the moment.
+	 */                                                          
+
+        printk( "NMI generated from unknown source!\n" );                       
+} /* mca_handle_nmi */                                                          
 
+/*--------------------------------------------------------------------*/
+
+int mca_find_adapter( int id, int start ) 
+{
 	if( mca_info == 0 || id == 0 || id == 0xffff ) {
 		return MCA_NOTFOUND;
 	}
 
 	for( ; start >= 0 && start < MCA_NUMADAPTERS; start += 1 ) {
-		slot_id = (mca_info->slot[start].pos[1] << 8)
-			+ mca_info->slot[start].pos[0];
-		status = mca_info->slot[start].pos[2];
 
 		/* not sure about this.  There's no point in returning
-		adapters that aren't enabled, since they can't actually
-		be used.  However, they might be needed for statistical
-		purposes or something... */
-		if( !(status & MCA_ENABLED) ) {
+		 * adapters that aren't enabled, since they can't actually
+		 * be used.  However, they might be needed for statistical
+		 * purposes or something... But if that is the case, the
+		 * user is free to write a routine that manually iterates
+		 * through the adapters.
+		 */
+
+		if( mca_info->slot[start].status == MCA_ADAPTER_DISABLED ) {
 			continue;
 		}
 
-		if( id == slot_id ) {
+		if( id == mca_info->slot[start].id ) {
 			return start;
 		}
 	}
@@ -225,6 +404,37 @@
 
 /*--------------------------------------------------------------------*/
 
+int mca_find_unused_adapter( int id, int start ) 
+{
+	if( mca_info == 0 || id == 0 || id == 0xffff ) {
+		return MCA_NOTFOUND;
+	}
+
+	for( ; start >= 0 && start < MCA_NUMADAPTERS; start += 1 ) {
+
+		/* not sure about this.  There's no point in returning
+		 * adapters that aren't enabled, since they can't actually
+		 * be used.  However, they might be needed for statistical
+		 * purposes or something... But if that is the case, the
+		 * user is free to write a routine that manually iterates
+		 * through the adapters.
+		 */
+
+		if( mca_info->slot[start].status == MCA_ADAPTER_DISABLED ||
+		    mca_info->slot[start].driver_loaded ) {
+			continue;
+		}
+
+		if( id == mca_info->slot[start].id ) {
+			return start;
+		}
+	}
+
+	return MCA_NOTFOUND;
+} /* mca_find_unused_adapter() */	
+
+/*--------------------------------------------------------------------*/
+
 unsigned char mca_read_stored_pos( int slot, int reg ) 
 {
 	if( slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == 0 ) return 0;
@@ -237,57 +447,97 @@
 unsigned char mca_read_pos( int slot, int reg ) 
 {
 	unsigned int byte = 0;
+	unsigned long flags;
 
-	if( slot < 0 || slot >= MCA_MAX_SLOT_NR || mca_info == 0 ) return 0;
+	if( slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == 0 ) return 0;
 	if( reg < 0 || reg >= 8 ) return 0;
 
+	save_flags( flags );
 	cli();
 
-	/*make sure motherboard setup is off*/
+	/* make sure motherboard setup is off */
+
 	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
 
 	/* read in the appropriate register */
-	outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG);
-	byte = inb_p(MCA_POS_REG(reg)); 
-	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
-	sti();
+	if( slot == MCA_INTEGSCSI && mca_info->which_scsi ) {
+
+		/* disable adapter setup, enable motherboard setup */
+
+		outb_p(0, MCA_ADAPTER_SETUP_REG);
+		outb_p(mca_info->which_scsi, MCA_MOTHERBOARD_SETUP_REG);
+
+		byte = inb_p(MCA_POS_REG(reg));
+		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
+	} else if( slot == MCA_INTEGVIDEO ) {
+
+		/* disable adapter setup, enable motherboard setup */
+
+		outb_p(0, MCA_ADAPTER_SETUP_REG);
+		outb_p(0xdf, MCA_MOTHERBOARD_SETUP_REG);
+
+		byte = inb_p(MCA_POS_REG(reg));
+		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
+	} else if( slot < MCA_MAX_SLOT_NR ) {
+
+		/* make sure motherboard setup is off */
+
+		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
+
+		/* read the appropriate register */
+
+		outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG);
+		byte = inb_p(MCA_POS_REG(reg));
+		outb_p(0, MCA_ADAPTER_SETUP_REG);
+	}
 
 	/* make sure the stored values are consistent, while we're here */
+
 	mca_info->slot[slot].pos[reg] = byte;
 
+	restore_flags( flags );
+
 	return byte;
 } /* mca_read_pos() */
 
 /*--------------------------------------------------------------------*/
+
 /* Note that this a technically a Bad Thing, as IBM tech stuff says
-	you should only set POS values through their utilities.
-	However, some devices such as the 3c523 recommend that you write
-	back some data to make sure the configuration is consistent.
-	I'd say that IBM is right, but I like my drivers to work.
-	This function can't do checks to see if multiple devices end up
-	with the same resources, so you might see magic smoke if someone
-	screws up.  */
+ * you should only set POS values through their utilities.
+ * However, some devices such as the 3c523 recommend that you write
+ * back some data to make sure the configuration is consistent.
+ * I'd say that IBM is right, but I like my drivers to work.
+ * This function can't do checks to see if multiple devices end up
+ * with the same resources, so you might see magic smoke if someone
+ * screws up.
+ */
 
 void mca_write_pos( int slot, int reg, unsigned char byte ) 
 {
+	unsigned long flags;
+
 	if( slot < 0 || slot >= MCA_MAX_SLOT_NR ) return;
 	if( reg < 0 || reg >= 8 ) return;
 	if (mca_info == 0 )  return;
 
+	save_flags( flags );
 	cli();
 
-	/*make sure motherboard setup is off*/
+	/* make sure motherboard setup is off */
+
 	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
 
 	/* read in the appropriate register */
+
 	outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG);
 	outb_p( byte, MCA_POS_REG(reg) );
 	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
-	sti();
+	restore_flags( flags );
 
 	/* update the global register list, while we have the byte */
+
 	mca_info->slot[slot].pos[reg] = byte;
 } /* mca_write_pos() */
 
@@ -298,8 +548,14 @@
 	if( mca_info == 0 ) return;
 
 	if( slot >= 0 && slot < MCA_NUMADAPTERS ) {
-		strncpy( mca_info->slot[slot].name, name,
-			sizeof(mca_info->slot[slot].name) );
+		if( name != NULL ) {
+			strncpy( mca_info->slot[slot].name, name,
+				sizeof(mca_info->slot[slot].name)-1 );
+			mca_info->slot[slot].name[
+				sizeof(mca_info->slot[slot].name)-1] = 0;
+		} else {
+			mca_info->slot[slot].name[0] = 0;
+		}
 	}
 }
 
@@ -313,6 +569,23 @@
 	}
 }
 
+int mca_is_adapter_used( int slot )
+{
+	return mca_info->slot[slot].driver_loaded;
+}
+
+int mca_mark_as_used( int slot )
+{
+	if(mca_info->slot[slot].driver_loaded) return 1;
+	mca_info->slot[slot].driver_loaded = 1;
+	return 0;
+}
+
+void mca_mark_as_unused( int slot )
+{
+	mca_info->slot[slot].driver_loaded = 0;
+}
+ 
 char *mca_get_adapter_name( int slot ) 
 {
 	if( mca_info == 0 ) return 0;
@@ -328,19 +601,9 @@
 {
 	if( mca_info == 0 ) return 0;
 
-	if( slot >= MCA_MAX_SLOT_NR ) {
-		/* some integrated adapters have 0xffff for an ID, but
-		are still there. VGA, for example. */
-		int i;
-		for( i = 0; i < 8; i ++ ) {
-			if( mca_info->slot[slot].pos[i] != 0xff ) {
-				return 1;
-			}
-		}
-		return 0;
-	} else if( slot >= 0 && slot < MCA_NUMADAPTERS ) {
-		return (mca_info->slot[slot].pos[0] != 0xff ||
-			mca_info->slot[slot].pos[1] != 0xff);
+	if( slot >= 0 && slot < MCA_NUMADAPTERS ) {
+		return (( mca_info->slot[slot].status == MCA_ADAPTER_NORMAL )
+			|| (mca_info->slot[slot].status == MCA_ADAPTER_DISABLED ) );
 	}
 
 	return 0;
@@ -351,7 +614,7 @@
 	if( mca_info == 0 ) return 0;
 
 	if( slot >= 0 && slot < MCA_NUMADAPTERS ) {
-		return (mca_info->slot[slot].pos[2] & MCA_ENABLED);
+		return (mca_info->slot[slot].status == MCA_ADAPTER_NORMAL);
 	}
 
 	return 0;
@@ -367,9 +630,8 @@
 
 	if( MCA_bus && mca_info != 0 ) 
 	{
-		/*
-		 *	Format pos registers of eight MCA slots
-		 */
+		/* Format pos registers of eight MCA slots */
+
 		for (i=0; i<MCA_MAX_SLOT_NR; i++) 
 		{
 			len += sprintf(buf+len, "Slot %d: ", i+1);
@@ -378,29 +640,24 @@
 			len += sprintf( buf+len, " %s\n", mca_info->slot[i].name );
 		}    
 
-		/*
-		 *	Format pos registers of integrated video subsystem
-		 */
+		/* Format pos registers of integrated video subsystem */
 
-		len += sprintf(buf+len, "Video: ");
+		len += sprintf(buf+len, "Video : ");
 		for (j=0; j<8; j++) 
 			len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]);
 		len += sprintf( buf+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name );
 
-		/*
-		 *	Format pos registers of integrated SCSI subsystem
-		 */
+		/* Format pos registers of integrated SCSI subsystem */
 	
-		len += sprintf(buf+len, "SCSI: ");
+		len += sprintf(buf+len, "SCSI  : ");
 		for (j=0; j<8; j++) 
 			len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]);
 		len += sprintf( buf+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name );
 	} 
 	else 
 	{
-	  	/* 
-	  	 *	Leave it empty if MCA not detected
-		 *	this should never happen 
+	  	/* Leave it empty if MCA not detected - this should *never*
+		 * happen! 
 		 */
 	}
 
@@ -409,12 +666,13 @@
 
 
 /*--------------------------------------------------------------------*/
+
 __initfunc(void mca_do_proc_init( void ))
 {
 	int i = 0;
 	struct proc_dir_entry* node = 0;
 
-	if( mca_info == 0 ) return;	/* never happens */
+	if( mca_info == 0 ) return;	/* should never happen */
 
 	proc_register( &proc_mca, &(struct proc_dir_entry) {
 		PROC_MCA_REGISTERS, 3, "pos", S_IFREG|S_IRUGO,
@@ -424,7 +682,8 @@
 		PROC_MCA_MACHINE, 7, "machine", S_IFREG|S_IRUGO,
 		1, 0, 0, 0, &proc_mca_inode_operations,} );
 
-	/* initialize /proc entries for existing adapters */
+	/* initialize /proc/mca entries for existing adapters */
+
 	for( i = 0; i < MCA_NUMADAPTERS; i += 1 ) {
 		mca_info->slot[i].procfn = 0;
 		mca_info->slot[i].dev = 0;
@@ -460,6 +719,7 @@
 	int len = 0, i;
 
 	/* this really shouldn't happen... */
+
 	if( mca_info == 0 ) {
 		*buf = 0;
 		return 0;
@@ -475,7 +735,9 @@
 		len += sprintf( buf+len, "Integrated Video Adapter\n" );
 	}
 	if( mca_info->slot[slot].name[0] ) {
+
 		/* drivers might register a name without /proc handler... */
+
 		len += sprintf( buf+len, "Adapter Name: %s\n",
 			mca_info->slot[slot].name );
 	} else {
@@ -485,6 +747,8 @@
 		mca_info->slot[slot].pos[1], mca_info->slot[slot].pos[0] );
 	len += sprintf( buf+len, "Enabled: %s\nPOS: ",
 		mca_isenabled(slot) ? "Yes" : "No" );
+	len += sprintf( buf+len, "Driver Installed: %s\n",
+		mca_is_adapter_used(slot) ? "Yes" : "No" );
 	for (i=0; i<8; i++) {
 		len += sprintf(buf+len, "%02x ", mca_info->slot[slot].pos[i]);
 	}
@@ -505,13 +769,6 @@
 	return len;
 }
 
-/*
-static int mca_not_implemented( char* buf ) 
-{
-	return sprintf( buf, "Sorry, not implemented yet...\n" );
-}
-*/
-
 static int mca_fill( char* page, int pid, int type, char** start,
 	loff_t *offset, int length)
 {
@@ -540,9 +797,11 @@
 	/* if we made it here, we better have a valid slot */
 
 	/* get the standard info */
+
 	len = mca_default_procfn( page, slot );
 
 	/* do any device-specific processing, if there is any */
+
 	if( mca_info->slot[slot].procfn ) {
 		len += mca_info->slot[slot].procfn( page+len, slot,
 			mca_info->slot[slot].dev );
@@ -551,9 +810,7 @@
 	return len;
 } /* mca_fill() */
 
-/*
- *	Blatantly stolen from fs/proc/array.c, and thus is probably overkill 
- */
+/* Blatantly stolen from fs/proc/array.c, and thus is probably overkill */ 
 
 #define PROC_BLOCK_SIZE	(3*1024)
 
@@ -587,11 +844,13 @@
 	}
 	if (start != 0) {
 		/* We have had block-adjusting processing! */
+
 		copy_to_user(buf, start, length);
 		*ppos += length;
 		count = length;
 	} else {
 		/* Static 4kB (or whatever) block capacity */
+
 		if (*ppos >= length) {
 			free_page(page);
 			return 0;
diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.1.125/linux/arch/i386/kernel/setup.c	Fri Oct  9 13:27:05 1998
+++ linux/arch/i386/kernel/setup.c	Wed Oct 14 11:39:25 1998
@@ -431,9 +431,9 @@
 	    "486 SX/2", NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, 
 	    NULL, NULL, NULL, NULL, NULL }},
 	{ X86_VENDOR_INTEL,	5,
-	  { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75+",
+	  { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75 - 200",
 	    "OverDrive PODP5V83", "Pentium MMX", NULL, NULL,
-	    "Mobile Pentium 75+", "Mobile Pentium MMX", NULL, NULL, NULL,
+	    "Mobile Pentium 75 - 200", "Mobile Pentium MMX", NULL, NULL, NULL,
 	    NULL, NULL, NULL, NULL }},
 	{ X86_VENDOR_INTEL,	6,
 	  { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", 
diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- v2.1.125/linux/arch/i386/kernel/time.c	Thu Jul 16 18:09:23 1998
+++ linux/arch/i386/kernel/time.c	Fri Oct  9 12:16:19 1998
@@ -12,7 +12,29 @@
  *      precision CMOS clock update
  * 1996-05-03    Ingo Molnar
  *      fixed time warps in do_[slow|fast]_gettimeoffset()
+ * 1998-09-05    (Various)
+ *	More robust do_fast_gettimeoffset() algorithm implemented
+ *	(works with APM, Cyrix 6x86MX and Centaur C6),
+ *	monotonic gettimeofday() with fast_get_timeoffset(),
+ *	drift-proof precision TSC calibration on boot
+ *	(C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
+ *	Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
+ *	ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
  */
+
+/* What about the "updated NTP code" stuff in 2.0 time.c? It's not in
+ * 2.1, perhaps it should be ported, too.
+ *
+ * What about the BUGGY_NEPTUN_TIMER stuff in do_slow_gettimeoffset()?
+ * Whatever it fixes, is it also fixed in the new code from the Jumbo
+ * patch, so that that code can be used instead?
+ *
+ * The CPU Hz should probably be displayed in check_bugs() together
+ * with the CPU vendor and type. Perhaps even only in MHz, though that
+ * takes away some of the fun of the new code :)
+ *
+ * - Michael Krause */
+
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -41,100 +63,51 @@
 #include "irq.h"
 
 extern int setup_x86_irq(int, struct irqaction *);
-extern volatile unsigned long lost_ticks;
 
-/* change this if you have some constant time drift */
-#define USECS_PER_JIFFY (1000020/HZ)
+unsigned long cpu_hz;	/* Detected as we calibrate the TSC */
+
+/* Number of usecs that the last interrupt was delayed */
+static int delay_at_last_interrupt;
+
+static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
 
-#ifndef	CONFIG_APM	/* cycle counter may be unreliable */
-/* Cycle counter value at the previous timer interrupt.. */
-static struct {
-	unsigned long low;
-	unsigned long high;
-} init_timer_cc, last_timer_cc;
+/* Cached *multiplier* to convert TSC counts to microseconds.
+ * (see the equation below).
+ * Equal to 2^32 * (1 / (clocks per usec) ).
+ * Initialized in time_init.
+ */
+static unsigned long fast_gettimeoffset_quotient=0;
 
 static unsigned long do_fast_gettimeoffset(void)
 {
 	register unsigned long eax asm("ax");
 	register unsigned long edx asm("dx");
-	unsigned long tmp, quotient, low_timer;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies=0;
-
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value. 
-	 * It has to be recalculated once each jiffy.
-	 */
-	static unsigned long cached_quotient=0;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-	low_timer = last_timer_cc.low;
 
-	if (last_jiffies != tmp) {
-		last_jiffies = tmp;
-
-		/* Get last timer tick in absolute kernel time */
-		eax = low_timer;
-		edx = last_timer_cc.high;
-		__asm__("subl "SYMBOL_NAME_STR(init_timer_cc)",%0\n\t"
-			"sbbl "SYMBOL_NAME_STR(init_timer_cc)"+4,%1"
-			:"=a" (eax), "=d" (edx)
-			:"0" (eax), "1" (edx));
-
-		/*
-		 * Divide the 64-bit time with the 32-bit jiffy counter,
-		 * getting the quotient in clocks.
-		 *
-		 * Giving quotient = "1/(average internal clocks per usec)*2^32"
-		 * we do this '1/...' trick to get the 'mull' into the critical 
-		 * path. 'mull' is much faster than divl (10 vs. 41 clocks)
-		 */
-		__asm__("divl %2"
-			:"=a" (eax), "=d" (edx)
-			:"r" (tmp),
-			 "0" (eax), "1" (edx));
-
-		edx = USECS_PER_JIFFY;
-		tmp = eax;
-		eax = 0;
-
-		__asm__("divl %2"
-			:"=a" (eax), "=d" (edx)
-			:"r" (tmp),
-			 "0" (eax), "1" (edx));
-		cached_quotient = eax;
-		quotient = eax;
-	}
-
-	/* Read the time counter */
-	__asm__("rdtsc" : "=a" (eax), "=d" (edx));
+	/* Read the Time Stamp Counter */
+	__asm__("rdtsc"
+		:"=a" (eax), "=d" (edx));
 
 	/* .. relative to previous jiffy (32 bits is enough) */
 	edx = 0;
-	eax -= low_timer;
+	eax -= last_tsc_low;	/* tsc_low delta */
 
 	/*
-	 * Time offset = (USECS_PER_JIFFY * time_low) * quotient.
-	 */
+         * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient.
+         *             = (tsc_low delta) / (clocks_per_usec)
+         *             = (tsc_low delta) / (clocks_per_jiffy / usecs_per_jiffy)
+	 *
+	 * Using a mull instead of a divl saves up to 31 clock cycles
+	 * in the critical path.
+         */
 
 	__asm__("mull %2"
 		:"=a" (eax), "=d" (edx)
-		:"r" (quotient),
+		:"r" (fast_gettimeoffset_quotient),
 		 "0" (eax), "1" (edx));
 
-	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (edx >= USECS_PER_JIFFY)
-		edx = USECS_PER_JIFFY-1;
-
-	return edx;
+	/* our adjusted time offset in microseconds */
+	return edx + delay_at_last_interrupt;
 }
-#endif
 
 /* This function must be called with interrupts disabled 
  * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
@@ -249,20 +222,11 @@
 	return count;
 }
 
-#ifndef CONFIG_APM
-/*
- * this is only used if we have fast gettimeoffset:
- */
-static void do_x86_get_fast_time(struct timeval * tv)
-{
-	do_gettimeofday(tv);
-}
-#endif
-
 static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
 
 /*
- * This version of gettimeofday has near microsecond resolution.
+ * This version of gettimeofday has microsecond resolution
+ * and better than microsecond precision on fast x86 machines with TSC.
  */
 void do_gettimeofday(struct timeval *tv)
 {
@@ -272,20 +236,11 @@
 	cli();
 	*tv = xtime;
 	tv->tv_usec += do_gettimeoffset();
-
-	/*
-	 * xtime is atomically updated in timer_bh. lost_ticks is
-	 * nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (lost_ticks)
-		tv->tv_usec += USECS_PER_JIFFY;
-
-	restore_flags(flags);
-
 	if (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
 		tv->tv_sec++;
 	}
+	restore_flags(flags);
 }
 
 void do_settimeofday(struct timeval *tv)
@@ -311,13 +266,15 @@
 	sti();
 }
 
-
 /*
  * In order to set the CMOS clock precisely, set_rtc_mmss has to be
  * called 500 ms after the second nowtime has started, because when
  * nowtime is written into the registers of the CMOS clock, it will
  * jump to the next second precisely 500 ms later. Check the Motorola
  * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you'll only notice that after reboot!
  */
 static int set_rtc_mmss(unsigned long nowtime)
 {
@@ -354,8 +311,12 @@
 		}
 		CMOS_WRITE(real_seconds,RTC_SECONDS);
 		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
 		retval = -1;
+	}
 
 	/* The following flags have to be released exactly in this order,
 	 * otherwise the DS12887 (popular MC146818A clone with integrated
@@ -431,21 +392,37 @@
 #endif
 }
 
-#ifndef	CONFIG_APM	/* cycle counter may be unreliable */
 /*
  * This is the same as the above, except we _also_ save the current
- * cycle counter value at the time of the timer interrupt, so that
+ * Time Stamp Counter value at the time of the timer interrupt, so that
  * we later on can estimate the time of day more exactly.
  */
 static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	int count, flags;
+
+	/* It is important that these two operations happen almost at the
+	 * same time. We do the RDTSC stuff first, since it's faster. To
+         * avoid any inconsistencies, we disable interrupts locally.
+         */
+	
+	__save_flags(flags);
+	__cli(); 
 	/* read Pentium cycle counter */
 	__asm__("rdtsc"
-		:"=a" (last_timer_cc.low),
-		 "=d" (last_timer_cc.high));
+		:"=a" (last_tsc_low):: "eax", "edx");
+
+	outb_p(0x00, 0x43);     /* latch the count ASAP */
+
+	count = inb_p(0x40);    /* read the latched count */
+	count |= inb(0x40) << 8;
+
+	count = ((LATCH-1) - count) * TICK_SIZE;
+	delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+	__restore_flags(flags);
+       
 	timer_interrupt(irq, NULL, regs);
 }
-#endif
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
@@ -520,6 +497,80 @@
 
 static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
 
+/* ------ Calibrate the TSC ------- 
+ * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
+ * Too much 64-bit arithmetic here to do this cleanly in C, and for
+ * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
+ * output busy loop as low as possible. We avoid reading the CTC registers
+ * directly because of the awkward 8-bit access mechanism of the 82C54
+ * device.
+ */
+
+__initfunc(static unsigned long calibrate_tsc(void))
+{
+       unsigned long retval;
+
+       __asm__( /* set the Gate high, program CTC channel 2 for mode 0
+		 * (interrupt on terminal count mode), binary count, 
+		 * load 5 * LATCH count, (LSB and MSB)
+		 * to begin countdown, read the TSC and busy wait.
+		 * BTW LATCH is calculated in timex.h from the HZ value
+		 */
+
+	       /* Set the Gate high, disable speaker */
+	       "inb  $0x61, %%al\n\t" /* Read port */
+	       "andb $0xfd, %%al\n\t" /* Turn off speaker Data */
+	       "orb  $0x01, %%al\n\t" /* Set Gate high */
+	       "outb %%al, $0x61\n\t" /* Write port */
+
+	       /* Now let's take care of CTC channel 2 */
+	       "movb $0xb0, %%al\n\t" /* binary, mode 0, LSB/MSB, ch 2*/
+	       "outb %%al, $0x43\n\t" /* Write to CTC command port */
+	       "movb $0x0c, %%al\n\t"
+	       "outb %%al, $0x42\n\t" /* LSB of count */
+	       "movb $0xe9, %%al\n\t"
+	       "outb %%al, $0x42\n\t" /* MSB of count */
+
+               /* Read the TSC; counting has just started */
+               "rdtsc\n\t"
+               /* Move the value for safe-keeping. */
+               "movl %%eax, %%ebx\n\t"
+               "movl %%edx, %%ecx\n\t"
+
+	       /* Busy wait. Only 50 ms wasted at boot time. */
+               "0: inb $0x61, %%al\n\t" /* Read Speaker Output Port */
+	       "testb $0x20, %%al\n\t" /* Check CTC channel 2 output (bit 5) */
+               "jz 0b\n\t"
+
+               /* And read the TSC.  5 jiffies (50.00077ms) have elapsed. */
+               "rdtsc\n\t"
+
+               /* Great.  So far so good.  Store last TSC reading in
+                * last_tsc_low (only 32 lsb bits needed) */
+               "movl %%eax, last_tsc_low\n\t"
+               /* And now calculate the difference between the readings. */
+               "subl %%ebx, %%eax\n\t"
+               "sbbl %%ecx, %%edx\n\t" /* 64-bit subtract */
+	       /* but probably edx = 0 at this point (see below). */
+               /* Now we have 5 * (TSC counts per jiffy) in eax.  We want
+                * to calculate TSC->microsecond conversion factor. */
+
+               /* Note that edx (high 32-bits of difference) will now be 
+                * zero iff CPU clock speed is less than 85 GHz.  Moore's
+                * law says that this is likely to be true for the next
+                * 12 years or so.  You will have to change this code to
+                * do a real 64-by-64 divide before that time's up. */
+               "movl %%eax, %%ecx\n\t"
+               "xorl %%eax, %%eax\n\t"
+               "movl %1, %%edx\n\t"
+               "divl %%ecx\n\t" /* eax= 2^32 / (1 * TSC counts per microsecond) */
+	       /* Return eax for the use of fast_gettimeoffset */
+               "movl %%eax, %0\n\t"
+               : "=r" (retval)
+               : "r" (5 * 1000020/HZ)
+               : /* we clobber: */ "ax", "bx", "cx", "dx", "cc", "memory");
+       return retval;
+}
 
 __initfunc(void time_init(void))
 {
@@ -527,36 +578,36 @@
 	xtime.tv_usec = 0;
 
 /*
- * If we have APM enabled we can't currently depend
- * on the cycle counter, because a suspend to disk
- * will reset it. Somebody should come up with a
- * better solution than to just disable the fast time
- * code..
- */
-#ifndef CONFIG_APM
-	/* If we have the CPU hardware time counters, use them */
-	if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) { 
+ * If we have APM enabled or the CPU clock speed is variable
+ * (CPU stops clock on HLT or slows clock to save power)
+ * then the TSC timestamps may diverge by up to 1 jiffy from
+ * 'real time' but nothing will break.
+ * The most frequent case is that the CPU is "woken" from a halt
+ * state by the timer interrupt itself, so we get 0 error. In the
+ * rare cases where a driver would "wake" the CPU and request a
+ * timestamp, the maximum error is < 1 jiffy. But timestamps are
+ * still perfectly ordered.
+ * Note that the TSC counter will be reset if APM suspends
+ * to disk; this won't break the kernel, though, 'cuz we're
+ * smart.  See devices/char/apm_bios.c.
+ */
+	if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
 		do_gettimeoffset = do_fast_gettimeoffset;
-		do_get_fast_time = do_x86_get_fast_time;
-
-		if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-		    boot_cpu_data.x86 == 5 &&
-		    boot_cpu_data.x86_model == 0) {
-			/* turn on cycle counters during power down */
-			__asm__ __volatile__ (" movl $0x83, %%ecx \n \
-				rdmsr \n \
-				orl $1,%%eax \n \
-				wrmsr \n " 
-                                      : : : "ax", "cx", "dx" );
-				udelay(500);
-		}
-
-		/* read Pentium cycle counter */
-		__asm__("rdtsc"
-			:"=a" (init_timer_cc.low),
-			 "=d" (init_timer_cc.high));
+		do_get_fast_time = do_gettimeofday;
 		irq0.handler = pentium_timer_interrupt;
+		fast_gettimeoffset_quotient = calibrate_tsc();
+		
+		/* report CPU clock rate in Hz.
+		 * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
+		 * clock/second. Our precision is about 100 ppm.
+		 */
+		{	unsigned long eax=0, edx=1000000;
+			__asm__("divl %2"
+	       		:"=a" (cpu_hz), "=d" (edx)
+               		:"r" (fast_gettimeoffset_quotient),
+                	"0" (eax), "1" (edx));
+			printk("Detected %ld Hz processor.\n", cpu_hz);
+		}
 	}
-#endif
 	setup_x86_irq(0, &irq0);
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/Makefile linux/arch/mips/Makefile
--- v2.1.125/linux/arch/mips/Makefile	Fri May  8 23:14:42 1998
+++ linux/arch/mips/Makefile	Tue Oct 20 13:52:54 1998
@@ -1,10 +1,4 @@
-#
-# arch/mips/Makefile
-#
-# This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" and "archdep" for cleaning up and making dependencies for
-# this architecture
+# $Id: Makefile,v 1.13 1998/08/17 10:16:23 ralf Exp $
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
@@ -13,7 +7,10 @@
 # Copyright (C) 1994, 1995, 1996 by Ralf Baechle
 # DECStation modifications by Paul M. Antoine, 1996
 #
-# $Id: Makefile,v 1.14 1998/05/01 01:33:20 ralf Exp $
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
 #
 
 #
@@ -39,7 +36,7 @@
 CROSS_COMPILE  = $(tool-prefix)
 endif
 
-LINKFLAGS	= -static -N
+LINKFLAGS	= -static #-N
 MODFLAGS	+= -mlong-calls
 
 #
@@ -74,7 +71,7 @@
 CFLAGS		:= $(CFLAGS) -mcpu=r6000 -mips2
 endif
 ifdef CONFIG_CPU_R4300
-CFLAGS		:= $(CFLAGS) -mcpu=r4600 -Wa,-mcpu=vr4300 -mips2
+CFLAGS		:= $(CFLAGS) -mcpu=r4300 -mips2
 endif
 ifdef CONFIG_CPU_R4X00
 CFLAGS		:= $(CFLAGS) -mcpu=r4600 -mips2
@@ -169,6 +166,8 @@
 	@$(MAKEBOOT) clean
 	$(MAKE) -C arch/$(ARCH)/kernel clean
 	$(MAKE) -C arch/$(ARCH)/tools clean
+
+archmrproper:
 
 archdep:
 	@$(MAKEBOOT) dep
diff -u --recursive --new-file v2.1.125/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.1.125/linux/arch/mips/config.in	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/config.in	Tue Oct 20 13:52:54 1998
@@ -98,6 +98,11 @@
   bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
   bool 'Kernel module loader' CONFIG_KMOD
 fi
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
+fi
+
 endmenu
 
 source drivers/block/Config.in
@@ -189,6 +194,9 @@
 
 source fs/nls/Config.in
 
+comment 'Console drivers'
+source drivers/video/Config.in
+
 mainmenu_option next_comment
 comment 'Sound'
 
@@ -211,4 +219,5 @@
   bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE
 fi
 bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
diff -u --recursive --new-file v2.1.125/linux/arch/mips/defconfig linux/arch/mips/defconfig
--- v2.1.125/linux/arch/mips/defconfig	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/defconfig	Tue Oct 20 13:52:54 1998
@@ -48,7 +48,9 @@
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
 
 #
 # Block devices
@@ -173,7 +175,8 @@
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_JAZZ_ESP is not set
+CONFIG_JAZZ_ESP=y
+CONFIG_JAZZ_ESP=y
 
 #
 # Network device support
@@ -195,10 +198,12 @@
 # CONFIG_CS89x0 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DEC_ELCP is not set
+# CONFIG_DEC_ELCP is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEXPRESS_PRO100 is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
 # CONFIG_NET_POCKET is not set
 # CONFIG_FDDI is not set
 # CONFIG_DLCI is not set
@@ -206,6 +211,7 @@
 # CONFIG_SLIP is not set
 # CONFIG_NET_RADIO is not set
 # CONFIG_TR is not set
+# CONFIG_HOSTESS_SV11 is not set
 # CONFIG_WAN_DRIVERS is not set
 # CONFIG_LAPBETHER is not set
 # CONFIG_X25_ASY is not set
@@ -243,11 +249,9 @@
 # CONFIG_SERIAL_CONSOLE is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_UNIX98_PTYS is not set
 # CONFIG_MOUSE is not set
 # CONFIG_QIC02_TAPE is not set
-# CONFIG_APM is not set
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
 # CONFIG_VIDEO_DEV is not set
@@ -286,7 +290,9 @@
 # CONFIG_ROMFS_FS is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_UFS_FS is not set
-CONFIG_DEVPTS_FS=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SMD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_MAC_PARTITION is not set
 CONFIG_NLS=y
 
@@ -321,6 +327,10 @@
 # CONFIG_NLS_KOI8_R is not set
 
 #
+# Console drivers
+#
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -329,4 +339,6 @@
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
+# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/Makefile linux/arch/mips/jazz/Makefile
--- v2.1.125/linux/arch/mips/jazz/Makefile	Thu Jun 26 12:33:37 1997
+++ linux/arch/mips/jazz/Makefile	Tue Oct 20 13:52:54 1998
@@ -13,11 +13,7 @@
 
 all: jazz.o
 O_TARGET := jazz.o
-O_OBJS	 := hw-access.o int-handler.o jazzdma.o reset.o setup.o
-
-ifdef CONFIG_VIDEO_G364
-O_OBJS += g364.o
-endif
+O_OBJS	 := hw-access.o int-handler.o jazzdma.o reset.o rtc-jazz.o setup.o
 
 int-handler.o: int-handler.S
 
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/floppy-jazz.c linux/arch/mips/jazz/floppy-jazz.c
--- v2.1.125/linux/arch/mips/jazz/floppy-jazz.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/jazz/floppy-jazz.c	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,166 @@
+/* $Id: floppy-jazz.c,v 1.1 1998/05/07 18:38:29 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Low-level floppy stuff for Jazz family machines.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <asm/addrspace.h>
+#include <asm/vector.h>
+#include <asm/jazz.h>
+#include <asm/jazzdma.h>
+#include <asm/keyboard.h>
+#include <asm/pgtable.h>
+
+static unsigned char jazz_fd_inb(unsigned int port)
+{
+	unsigned char c;
+
+	c = *(volatile unsigned char *) port;
+	udelay(1);
+
+	return c;
+}
+
+static void jazz_fd_outb(unsigned char value, unsigned int port)
+{
+	*(volatile unsigned char *) port = value;
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static void jazz_fd_enable_dma(int channel)
+{
+	vdma_enable(JAZZ_FLOPPY_DMA);
+}
+
+static void jazz_fd_disable_dma(int channel)
+{
+	vdma_disable(JAZZ_FLOPPY_DMA);
+}
+
+static int jazz_fd_request_dma(int channel)
+{
+	return 0;
+}
+
+static void jazz_fd_free_dma(int channel)
+{
+}
+
+static void jazz_fd_clear_dma_ff(int channel)
+{
+}
+
+static void jazz_fd_set_dma_mode(int channel, char mode)
+{
+	vdma_set_mode(JAZZ_FLOPPY_DMA, mode);
+}
+
+static void jazz_fd_set_dma_addr(int channel, unsigned int a)
+{
+	vdma_set_addr(JAZZ_FLOPPY_DMA, vdma_phys2log(PHYSADDR(a)));
+}
+
+static void jazz_fd_set_dma_count(int channel, unsigned int count)
+{
+	vdma_set_count(JAZZ_FLOPPY_DMA, count);
+}
+
+static int jazz_fd_get_dma_residue(int channel)
+{
+	return vdma_get_residue(JAZZ_FLOPPY_DMA);
+}
+
+static void jazz_fd_enable_irq(int irq)
+{
+}
+
+static void jazz_fd_disable_irq(int irq)
+{
+}
+
+static unsigned long jazz_fd_getfdaddr1(void)
+{
+	return JAZZ_FDC_BASE;
+}
+
+/* Pure 2^n version of get_order */
+extern inline int __get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+extern inline unsigned long jazz_fd_dma_mem_alloc(unsigned long size)
+{
+	int order = __get_order(size);
+	unsigned long mem;
+
+	mem = __get_dma_pages(GFP_KERNEL, order);
+	if(!mem)
+		return 0;
+	vdma_alloc(PHYSADDR(mem), size);	/* XXX error checking */
+
+	return mem;
+}
+
+extern inline void jazz_fd_dma_mem_free(unsigned long addr,
+                                        unsigned long size)
+{       
+	vdma_free(PHYSADDR(addr));
+	free_pages(addr, __get_order(size));	
+}
+
+static void std_fd_drive_type(unsigned long n)
+{
+	/* XXX This is wrong for machines with ED 2.88mb disk drives like the
+	   Olivetti M700.  Anyway, we should suck this from the ARC
+	   firmware.  */
+	if (n == 0)
+		return 4;	/* 3,5", 1.44mb */
+
+	return 0;
+}
+
+struct fd_ops jazz_fd_ops = {
+	/*
+	 * How to access the floppy controller's ports
+	 */
+	jazz_fd_inb,
+	jazz_fd_outb,
+	/*
+	 * How to access the floppy DMA functions.
+	 */
+	jazz_fd_enable_dma,
+	jazz_fd_disable_dma,
+	jazz_fd_request_dma,
+	jazz_fd_free_dma,
+	jazz_fd_clear_dma_ff,
+	jazz_fd_set_dma_mode,
+	jazz_fd_set_dma_addr,
+	jazz_fd_set_dma_count,
+	jazz_fd_get_dma_residue,
+	jazz_fd_enable_irq,
+	jazz_fd_disable_irq,
+	jazz_fd_getfdaddr1,
+	jazz_fd_dma_mem_alloc,
+	jazz_fd_dma_mem_free,
+	jazz_fd_drive_type
+};
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/g364.c linux/arch/mips/jazz/g364.c
--- v2.1.125/linux/arch/mips/jazz/g364.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/jazz/g364.c	Wed Dec 31 16:00:00 1969
@@ -1,444 +0,0 @@
-/*
- *  linux/drivers/char/g364.c
- *
- *  Copyright (C) 1996  Wayne Hodgen
- *
- *  Based on and using chunks of Jay Estabrooks tga.c
- *
- * This module exports the console io support for Inmos's G364 controller
- * used in Mips Magnums and clones. Based on the hardware desc for the
- * Olivetti M700-10 ie. an Inmos G364 based card in a dedicated video slot,
- * 2MB dual ported VRAM with a 64 bit data path, 256 color lookup table,
- * palette of 16.7M and a user definable 64x64 hardware cursor.
- *
- * $Id: g364.c,v 1.7 1998/05/01 01:33:35 ralf Exp $
- */
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/kd.h>
-#include <linux/malloc.h>
-#include <linux/major.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/consolemap.h>
-#include <linux/selection.h>
-#include <linux/console_struct.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/types.h>
-
-extern void register_console(void (*proc)(const char *));
-extern void console_print(const char *);
-unsigned video_res_x;
-
-/* 
- * Various defines for the G364
- */
-#define G364_MEM_BASE   0xe4400000
-#define G364_PORT_BASE  0xe4000000
-#define ID_REG 		0xe4000000  	/* Read only */
-#define BOOT_REG 	0xe4080000
-#define TIMING_REG 	0xe4080108 	/* to 0x080170 - DON'T TOUCH! */
-#define MASK_REG 	0xe4080200
-#define CTLA_REG 	0xe4080300
-#define CURS_TOGGLE 	0x800000
-#define BIT_PER_PIX	0x700000	/* bits 22 to 20 of Control A */
-#define DELAY_SAMPLE    0x080000
-#define PORT_INTER	0x040000
-#define PIX_PIPE_DEL	0x030000	/* bits 17 and 16 of Control A */
-#define PIX_PIPE_DEL2	0x008000	/* same as above - don't ask me why */
-#define TR_CYCLE_TOG	0x004000
-#define VRAM_ADR_INC	0x003000	/* bits 13 and 12 of Control A */
-#define BLANK_OFF	0x000800
-#define FORCE_BLANK	0x000400
-#define BLK_FUN_SWTCH	0x000200
-#define BLANK_IO	0x000100
-#define BLANK_LEVEL	0x000080
-#define A_VID_FORM	0x000040
-#define D_SYNC_FORM	0x000020
-#define FRAME_FLY_PAT	0x000010
-#define OP_MODE		0x000008
-#define INTL_STAND	0x000004
-#define SCRN_FORM	0x000002
-#define ENABLE_VTG	0x000001	
-#define TOP_REG 	0xe4080400
-#define CURS_PAL_REG 	0xe4080508 	/* to 0x080518 */
-#define CHKSUM_REG 	0xe4080600 	/* to 0x080610 - unused */
-#define CURS_POS_REG 	0xe4080638
-#define CLR_PAL_REG 	0xe4080800	/* to 0x080ff8 */
-#define CURS_PAT_REG 	0xe4081000	/* to 0x081ff8 */
-#define MON_ID_REG 	0xe4100000 	/* unused */
-#define RESET_REG 	0xe4180000  	/* Write only */
-
-/*
- * built-in font management constants
- *
- * NOTE: the built-in font is 8x16, and the video resolution
- * is either 1280x1024 @ 60Hz or 1024x768 @ 60 or 78Hz.
- */
-#define FONTSIZE_X 	8 	/*  8 pixels wide */
-#define FONTSIZE_Y 	16 	/* 16 pixels high */
-
-unsigned char g364_font[] = {
-#include "g364.fnt"
-};
-
-#ifdef CONFIG_REMOTE_DEBUG
-/* #define DEBUG_G364 */
-
-extern int putDebugChar(char c);
-
-void
-putDebugString(char *d_str)
-{
-	while (*d_str != '\0') {
-		putDebugChar(*d_str);
-		d_str++;
-	}
-	if (*--d_str != '\n')
-		putDebugChar('\n');
-}
-#endif
-
-void g364_clear_screen(void);
-
-int cursor_initialised=0;
-
-__initfunc(unsigned long
-con_type_init(unsigned long kmem_start, const char **display_desc))
-{
-        can_do_color = 1;
-
-        /*
-        * fake the screen memory with some CPU memory
-        */
-        video_mem_base = kmem_start;
-        kmem_start += video_screen_size;
-        video_mem_term = kmem_start;
-        video_type = VIDEO_TYPE_MIPS_G364;
-	video_res_x = video_num_columns * FONTSIZE_X;
-
-        *display_desc = "G364";
-
-	return kmem_start;
-}
-
-__initfunc(void
-con_type_init_finish(void))
-{
-}
-
-void
-__set_origin(unsigned short offset)
-{
-  /*
-   * should not be called, but if so, do nothing...
-   */
-}
-
-/*
- * Hide the cursor from view, during blanking, usually...
- */
-void
-hide_cursor(void)
-{
-	*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
-}
-
-void
-init_g364_cursor(void)
-{
-	volatile unsigned int *ptr = (unsigned int *) CURS_PAL_REG;
-        int i;
-
-        *ptr |= 0x00ffffff;
-	ptr[2] |= 0x00ffffff;
-	ptr[4] |= 0x00ffffff;
-
-        /*
-	 * first set the whole cursor to transparent
-	 */
-        for (i = 0; i < 512; i++)
-	        *(unsigned short *)(CURS_PAT_REG+i*8) = 0;
-
-        /*
-	 * switch the last to lines to cursor palette 3
-	 * we assume here, that FONTSIZE_X is 8
-	 */
-        *(unsigned short *)(CURS_PAT_REG + (FONTSIZE_Y-2)*64) = 0xffff;
-        *(unsigned short *)(CURS_PAT_REG + (FONTSIZE_Y-1)*64) = 0xffff;			    
-	cursor_initialised = 1;
-}
-
-/*
- * Set the cursor on.
- */
-void
-set_cursor(int currcons)
-{
-        unsigned int idx, xt, yt, row, col;
-    
-	if (!cursor_initialised)
-		init_g364_cursor();
-
-	if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
-		return;
-
-	*(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
-    
-        if (__real_origin != __origin)
-	        __set_origin (__real_origin);
-    
-        if (deccm) {
-	    idx = (pos - video_mem_base) >> 1;
-	    col = idx % video_num_columns;
-	    row = (idx - col) / video_num_columns;
-	    
-	    xt = col * FONTSIZE_X;
-	    yt = row * FONTSIZE_Y;
-	    *(unsigned int *)CURS_POS_REG = (xt << 12) | yt;
-	} else
-	       hide_cursor();
-}
-
-/*
- * NOTE: get_scrmem() and set_scrmem() are here only because
- * the VGA version of set_scrmem() has some direct VGA references.
- */
-void
-get_scrmem(int currcons)
-{
-        memcpyw((unsigned short *)vc_scrbuf[currcons],
-                (unsigned short *)origin, video_screen_size);
-        origin = video_mem_start = (unsigned long)vc_scrbuf[currcons];
-        scr_end = video_mem_end = video_mem_start + video_screen_size;
-        pos = origin + y*video_size_row + (x<<1);
-}
-
-void
-set_scrmem(int currcons, long offset)
-{
-        if (video_mem_term - video_mem_base < offset + video_screen_size)
-          offset = 0;   /* strange ... */
-        memcpyw((unsigned short *)(video_mem_base + offset),
-                (unsigned short *) origin, video_screen_size);
-        video_mem_start = video_mem_base;
-        video_mem_end = video_mem_term;
-        origin = video_mem_base + offset;
-        scr_end = origin + video_screen_size;
-        pos = origin + y*video_size_row + (x<<1);
-}
-
-/*
- * Fill out later
- */
-void
-set_palette(void)
-{
-	int i, j;
-	volatile unsigned int *ptr = (volatile unsigned int *) CLR_PAL_REG;
-
-	for (i = 0; i < 16; i++,ptr+=2) {
-		j = color_table[i];
-		*ptr = ((default_red[j] << 16) |
-			 (default_grn[j] << 8) |
-			 (default_blu[j]));
-	}
-}
-
-/*
- * NOTE:
- * this is here, and not in console.c, because the VGA version
- * tests the controller type to see if color can be done. We *KNOW*
- * that we can do color on the G364.
- *
- */
-
-int
-set_get_cmap(unsigned char * arg, int set)
-{
-	int i;
-
-	for (i=0; i<16; i++) {
-		if (set) {
-			if (!access_ok(VERIFY_READ, (void *)arg, 16*3)) goto fault;
-			if (__get_user(default_red[i], arg++)) goto fault;
-			if (__get_user(default_grn[i], arg++)) goto fault;
-			if (__get_user(default_blu[i], arg++)) goto fault;
-                } else {
-			if (!access_ok(VERIFY_WRITE, (void *)arg, 16*3)) goto fault;
-                        if (__put_user(default_red[i], arg++)) goto fault;
-                        if (__put_user(default_grn[i], arg++)) goto fault;
-                        if (__put_user(default_blu[i], arg++)) goto fault;
-                }
-        }
-        if (set) {
-                for (i=0; i<MAX_NR_CONSOLES; i++)
-                    if (vc_cons_allocated(i)) {
-                        int j, k ;
-                        for (j=k=0; j<16; j++) {
-                            vc_cons[i].d->vc_palette[k++] = default_red[j];
-                            vc_cons[i].d->vc_palette[k++] = default_grn[j];
-                            vc_cons[i].d->vc_palette[k++] = default_blu[j];
-                        }
-                    }
-                set_palette() ;
-        }
-
-        return 0;
-
-fault:
-	return -EFAULT;
-}
-
-/*
- * Adjust the screen to fit a font of a certain height
- *
- * Returns < 0 for error, 0 if nothing changed, and the number
- * of lines on the adjusted console if changed.
- *
- * for now, we only support the built-in font...
- */
-int
-con_adjust_height(unsigned long fontheight)
-{
-        return -EINVAL;
-}
-
-/*
- * PIO_FONT support.
- *
- * for now, we will use/allow *only* our built-in font...
- */
-int
-set_get_font(char * arg, int set, int ch512)
-{
-        return -EINVAL;
-}
-
-/*
- * print a character to a graphics console.
- */
-void
-g364_blitc(unsigned short charattr, unsigned long addr)
-{
-  int row, col, temp;
-  register unsigned long long *dst, *font_row;
-  register int i;
-  char c;
-
-  /*
-   * calculate (row,col) from addr and video_mem_base
-   */
-  temp = (addr - video_mem_base) >> 1;
-  col = temp % 128;
-  row = (temp - col) / 128;
-
-  /*
-   * calculate destination address
-   */
-  dst = (unsigned long long *) ( G364_MEM_BASE
-                           + ( row * video_res_x * FONTSIZE_Y )
-                           + ( col * FONTSIZE_X ) );
-
-  c = charattr & 0x00ff;
-  if (c == 0x20) {
-    for (i=0; i < FONTSIZE_Y; i++, dst += video_num_columns)
-      *dst = 0x00000000;
-  } else {
-    font_row = (unsigned long long *) &g364_font[(c << 7)];
-    for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += video_num_columns)
-      *dst = *font_row;
-  }
-}
-
-/*
- * print a character to a graphics console. Colour version, slower!
- */
-void
-g364_blitc_colour(unsigned short charattr, unsigned long addr)
-{
-  int row, col, temp, c, attrib;
-  register unsigned int fgmask, bgmask;
-  register unsigned long long *dst, *font_row;
-  register int i, stride;
-
-  c = charattr & 0x00ff;
-  attrib = (charattr >> 8) & 0x00ff;
-
-  /*
-   * extract foreground and background indices
-   * NOTE: we always treat blink/underline bits as color for now...
-   */
-  fgmask = attrib & 0x0f;
-  bgmask = (attrib >> 4) & 0x0f;
-
-  /* i = (c & 0xff) << 7;  NOTE: assumption of 128 bytes per character bitmap */
-
-  /*
-   * calculate (row,col) from addr and video_mem_base
-   */
-  temp = (addr - video_mem_base) >> 1;
-  col = temp % 128;
-  row = (temp - col) / 128;
-  stride = video_res_x / 8;
-
-  /*
-   * calculate destination address
-   */
-  dst = (unsigned long long *) ( G364_MEM_BASE
-                           + ( row * video_res_x * FONTSIZE_Y )
-                           + ( col * FONTSIZE_X ) );
-
-  font_row = (unsigned long long *) &g364_font[((c & 0xff) << 7)];
-
-  for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += stride) {
-    *dst = *font_row;
-  }
-}
-
-/*
- * dummy routines for the VESA blanking code, which is VGA only,
- * so we don't have to carry that stuff around for the G364...
- */
-void
-vesa_powerdown(void)
-{
-}
-
-void
-vesa_blank(void)
-{
-}
-
-void
-vesa_unblank(void)
-{
-}
-
-void
-set_vesa_blanking(const unsigned long arg)
-{
-}
-
-/*
- * FIXME: how can we probe for the video board?
- */
-__initfunc(int con_is_present())
-{
-	return;
-}
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/g364.fnt linux/arch/mips/jazz/g364.fnt
--- v2.1.125/linux/arch/mips/jazz/g364.fnt	Thu Jun 26 12:33:37 1997
+++ linux/arch/mips/jazz/g364.fnt	Wed Dec 31 16:00:00 1969
@@ -1,4097 +0,0 @@
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x00,0x07,0x07,0x07,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x00,0x07,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x00,
-0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
-0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x07,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
-0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x07,
-0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x07,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
-0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07,
-0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,
-0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
-0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07,
-0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
-0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07,
-0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
-0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,
-0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x07,0x00,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
-0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x07,
-0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x07,
-0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x07,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x00,
-0x07,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x07,
-0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x00,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x07,
-0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x07,
-0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x07,
-0x00,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,
-0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
-0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x07,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
-0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x07,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
-0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
-0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
-0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
-0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
-0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
-0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/hw-access.c linux/arch/mips/jazz/hw-access.c
--- v2.1.125/linux/arch/mips/jazz/hw-access.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/jazz/hw-access.c	Tue Oct 20 13:52:54 1998
@@ -1,11 +1,12 @@
-/* $Id: hw-access.c,v 1.5 1998/05/07 00:39:27 ralf Exp $
+/* $Id: hw-access.c,v 1.11 1998/09/16 22:50:39 ralf Exp $
+ *
  * Low-level hardware access stuff for Jazz family machines.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -13,141 +14,10 @@
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <asm/addrspace.h>
-#include <asm/vector.h>
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
 #include <asm/keyboard.h>
 #include <asm/pgtable.h>
-#include <asm/mc146818rtc.h>
-
-static unsigned char
-fd_inb(unsigned int port)
-{
-	unsigned char c;
-
-	c = *(volatile unsigned char *) port;
-	udelay(1);
-
-	return c;
-}
-
-static void
-fd_outb(unsigned char value, unsigned int port)
-{
-	*(volatile unsigned char *) port = value;
-}
-
-/*
- * How to access the floppy DMA functions.
- */
-static void
-fd_enable_dma(int channel)
-{
-	vdma_enable(JAZZ_FLOPPY_DMA);
-}
-
-static void
-fd_disable_dma(int channel)
-{
-	vdma_disable(JAZZ_FLOPPY_DMA);
-}
-
-static int
-fd_request_dma(int channel)
-{
-	return 0;
-}
-
-static void
-fd_free_dma(int channel)
-{
-}
-
-static void
-fd_clear_dma_ff(int channel)
-{
-}
-
-static void
-fd_set_dma_mode(int channel, char mode)
-{
-	vdma_set_mode(JAZZ_FLOPPY_DMA, mode);
-}
-
-static void
-fd_set_dma_addr(int channel, unsigned int a)
-{
-	vdma_set_addr(JAZZ_FLOPPY_DMA, vdma_phys2log(PHYSADDR(a)));
-}
-
-static void
-fd_set_dma_count(int channel, unsigned int count)
-{
-	vdma_set_count(JAZZ_FLOPPY_DMA, count);
-}
-
-static int
-fd_get_dma_residue(int channel)
-{
-	return vdma_get_residue(JAZZ_FLOPPY_DMA);
-}
-
-static void
-fd_enable_irq(int irq)
-{
-}
-
-static void
-fd_disable_irq(int irq)
-{
-}
-
-void
-jazz_fd_cacheflush(const void *addr, size_t size)
-{
-	flush_cache_all();
-}
-
-static unsigned char
-rtc_read_data(unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	return *(char *)JAZZ_RTC_BASE;
-}
-
-static void
-rtc_write_data(unsigned char data, unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	*(char *)JAZZ_RTC_BASE = data;
-}
-
-struct feature jazz_feature = {
-	/*
-	 * How to access the floppy controller's ports
-	 */
-	fd_inb,
-	fd_outb,
-	/*
-	 * How to access the floppy DMA functions.
-	 */
-	fd_enable_dma,
-	fd_disable_dma,
-	fd_request_dma,
-	fd_free_dma,
-	fd_clear_dma_ff,
-	fd_set_dma_mode,
-	fd_set_dma_addr,
-	fd_set_dma_count,
-	fd_get_dma_residue,
-	fd_enable_irq,
-	fd_disable_irq,
-	/*
-	 * How to access the RTC functions.
-	 */
-	rtc_read_data,
-	rtc_write_data
-};
 
 static volatile keyboard_hardware *jazz_kh = 
 	(keyboard_hardware *) JAZZ_KEYBOARD_ADDRESS;
@@ -190,6 +60,31 @@
 	kbd_write_output = jazz_write_output;
 	kbd_write_command = jazz_write_command;
 	kbd_read_status = jazz_read_status;
+	request_irq(JAZZ_KEYBOARD_IRQ, keyboard_interrupt,
+	            0, "keyboard", NULL);
 	request_region(0x60, 16, "keyboard");
-	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_KEYBOARD);
+	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
+	                  r4030_read_reg16(JAZZ_IO_IRQ_ENABLE)
+	                  | JAZZ_IE_KEYBOARD);
+}
+
+int jazz_ps2_request_irq(void)
+{
+    extern void aux_interrupt(int, void *, struct pt_regs *);
+    int ret;
+    
+    ret = request_irq(JAZZ_MOUSE_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL);
+    if (!ret)
+	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 
+			  r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | 
+			  JAZZ_IE_MOUSE);
+    return ret;
+}
+
+void jazz_ps2_free_irq(void)
+{
+    r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 
+		      r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | 
+		      JAZZ_IE_MOUSE);
+    free_irq(JAZZ_MOUSE_IRQ, NULL);
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/int-handler.S linux/arch/mips/jazz/int-handler.S
--- v2.1.125/linux/arch/mips/jazz/int-handler.S	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/jazz/int-handler.S	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: int-handler.S,v 1.6 1998/05/08 01:44:08 ralf Exp $
+/* $Id: int-handler.S,v 1.6 1998/08/28 15:55:19 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -261,7 +261,12 @@
 		li	a0,JAZZ_KEYBOARD_IRQ
 		b	loc_call
 
-loc_mouse:	PANIC("Unimplemented loc_mouse handler")
+/*
+ * Mouse interrupt handler
+ */
+loc_mouse:	li	s1,~JAZZ_IE_MOUSE
+		li	a0,JAZZ_MOUSE_IRQ
+		b	loc_call
 
 /*
  * Serial port 1 IRQ
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/reset.c linux/arch/mips/jazz/reset.c
--- v2.1.125/linux/arch/mips/jazz/reset.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/jazz/reset.c	Tue Oct 20 13:52:54 1998
@@ -3,7 +3,7 @@
  *
  *  Reset a Jazz machine.
  *
- *  $Id: reset.c,v 1.2 1998/05/01 01:33:40 ralf Exp $
+ *  $Id: reset.c,v 1.2 1998/03/04 12:17:40 ralf Exp $
  */
 
 #include <linux/sched.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/rtc-jazz.c linux/arch/mips/jazz/rtc-jazz.c
--- v2.1.125/linux/arch/mips/jazz/rtc-jazz.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/jazz/rtc-jazz.c	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,36 @@
+/* $Id: rtc-jazz.c,v 1.3 1998/08/28 15:55:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * RTC routines for Jazz style attached Dallas chip.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/io.h>
+#include <asm/jazz.h>
+
+static unsigned char jazz_rtc_read_data(unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	return *(char *)JAZZ_RTC_BASE;
+}
+
+static void jazz_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	*(char *)JAZZ_RTC_BASE = data;
+}
+
+static int jazz_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops jazz_rtc_ops = {
+	&jazz_rtc_read_data,
+	&jazz_rtc_write_data,
+	&jazz_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/setup.c linux/arch/mips/jazz/setup.c
--- v2.1.125/linux/arch/mips/jazz/setup.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/jazz/setup.c	Tue Oct 20 13:52:54 1998
@@ -1,21 +1,24 @@
-/*
+/* $Id: setup.c,v 1.14 1998/09/16 22:50:40 ralf Exp $
+ *
  * Setup pointers to hardware-dependent routines.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997 by Ralf Baechle
- *
- * $Id: setup.c,v 1.7 1998/06/10 07:21:07 davem Exp $
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
  */
 #include <linux/config.h>
 #include <linux/hdreg.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/kbd_ll.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/mc146818rtc.h>
 #include <asm/bootinfo.h>
 #include <asm/keyboard.h>
 #include <asm/ide.h>
@@ -23,7 +26,6 @@
 #include <asm/jazz.h>
 #include <asm/ptrace.h>
 #include <asm/reboot.h>
-#include <asm/vector.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 
@@ -38,8 +40,6 @@
 static struct irqaction irq2  = { no_action, 0, 0, "cascade", NULL, NULL};
 
 extern asmlinkage void jazz_handle_int(void);
-extern asmlinkage void jazz_fd_cacheflush(const void *addr, size_t size);
-extern struct feature jazz_feature;
 extern void jazz_keyboard_setup(void);
 
 extern void jazz_machine_restart(char *command);
@@ -47,6 +47,7 @@
 extern void jazz_machine_power_off(void);
 
 extern struct ide_ops std_ide_ops;
+extern struct rtc_ops jazz_rtc_ops;
 
 void (*board_time_init)(struct irqaction *irq);
 
@@ -110,9 +111,7 @@
 	add_wired_entry (0x01800017, 0x01000017, 0xe4000000, PM_4M);
 
 	irq_setup = jazz_irq_setup;
-	fd_cacheflush = jazz_fd_cacheflush;
 	keyboard_setup = jazz_keyboard_setup;
-	feature = &jazz_feature;			// Will go away
 	mips_io_port_base = JAZZ_PORT_BASE;
 	isa_slot_offset = 0xe3000000;
 	request_region(0x00,0x20,"dma1");
@@ -129,4 +128,6 @@
 #ifdef CONFIG_BLK_DEV_IDE
 	ide_ops = &std_ide_ops;
 #endif
+	conswitchp = &fb_con;
+	rtc_ops = &jazz_rtc_ops;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile
--- v2.1.125/linux/arch/mips/kernel/Makefile	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/Makefile	Tue Oct 20 13:52:54 1998
@@ -15,7 +15,7 @@
 O_OBJS	:= branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \
 	   ioport.o pci.o reset.o setup.o syscall.o sysmips.o ipc.o \
 	   r4k_switch.o r4k_misc.o r4k_fpu.o r2300_switch.o r2300_misc.o \
-	   r2300_fpu.o r6000_fpu.o scall_o32.o unaligned.o
+	   r2300_fpu.o r6000_fpu.o scall_o32.o softfp.o unaligned.o
 OX_OBJS := mips_ksyms.o
 
 ifdef CONFIG_MIPS_FPE_MODULE
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/entry.S linux/arch/mips/kernel/entry.S
--- v2.1.125/linux/arch/mips/kernel/entry.S	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/entry.S	Tue Oct 20 13:52:54 1998
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1994, 1995 by Ralf Baechle
  *
- * $Id: entry.S,v 1.10 1998/07/26 03:02:06 davem Exp $
+ * $Id: entry.S,v 1.15 1998/10/14 20:26:26 ralf Exp $
  */
 
 /*
@@ -59,8 +59,7 @@
 
 		andi	t1, t0, 0x10
 		beqz	t1, return		# -> yes
-#error Change this to current->need_resched --DaveM
-		 lw	t1, need_resched
+		 lw	t1, TASK_NEED_RESCHED($28)
 		bnez	t1, reschedule
 		lw	v0, TASK_SIGPENDING($28)
 		 move	a0, zero
@@ -101,8 +100,6 @@
 		STI
 #define __BUILD_clear_cli(exception)                                    \
 		CLI
-#define __BUILD_clear_kmode(exception)                                  \
-		KMODE
 #define __BUILD_clear_fpe(exception)                                    \
 		cfc1	a1,fcr31;                                       \
 		li	a2,~(0x3f<<12);                                 \
@@ -112,7 +109,7 @@
 #define __BUILD_clear_ade(exception)                                    \
 		MFC0	t0,CP0_BADVADDR;                                \
 		REG_S	t0,PT_BVADDR(sp);                               \
-		STI
+		KMODE
 #define __BUILD_silent(exception)
 
 #define fmt "Got %s at %08lx.\n"
@@ -146,8 +143,8 @@
 		 nop;                                                   \
 		END(handle_##exception)
 
-		BUILD_HANDLER(adel,ade,kmode,silent)		/* #4  */
-		BUILD_HANDLER(ades,ade,kmode,silent)		/* #5  */
+		BUILD_HANDLER(adel,ade,ade,silent)		/* #4  */
+		BUILD_HANDLER(ades,ade,ade,silent)		/* #5  */
 		BUILD_HANDLER(ibe,ibe,cli,verbose)		/* #6  */
 		BUILD_HANDLER(dbe,dbe,cli,verbose)		/* #7  */
 		BUILD_HANDLER(bp,bp,sti,silent)			/* #9  */
@@ -155,10 +152,8 @@
 		BUILD_HANDLER(cpu,cpu,sti,silent)		/* #11 */
 		BUILD_HANDLER(ov,ov,sti,silent)			/* #12 */
 		BUILD_HANDLER(tr,tr,sti,silent)			/* #13 */
-		BUILD_HANDLER(vcei,vcei,sti,verbose)		/* #14 */
 		BUILD_HANDLER(fpe,fpe,fpe,silent)		/* #15 */
 		BUILD_HANDLER(watch,watch,sti,verbose)		/* #23 */
-		BUILD_HANDLER(vced,vced,sti,verbose)		/* #31 */
 		BUILD_HANDLER(reserved,reserved,sti,verbose)	/* others */
 
 /*
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/fpe.c linux/arch/mips/kernel/fpe.c
--- v2.1.125/linux/arch/mips/kernel/fpe.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/fpe.c	Tue Oct 20 13:52:54 1998
@@ -6,7 +6,7 @@
  *
  * Copyright (C) 1997 Ralf Baechle
  *
- * $Id: fpe.c,v 1.2 1998/05/01 01:33:48 ralf Exp $
+ * $Id: fpe.c,v 1.2 1998/03/27 08:53:39 ralf Exp $
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/gdb-low.S linux/arch/mips/kernel/gdb-low.S
--- v2.1.125/linux/arch/mips/kernel/gdb-low.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/gdb-low.S	Tue Oct 20 13:52:54 1998
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1995 Andreas Busse
  *
- * $Id: gdb-low.S,v 1.4 1998/05/01 01:33:50 ralf Exp $
+ * $Id: gdb-low.S,v 1.3 1997/12/02 05:51:05 ralf Exp $
  */
 
 #include <linux/sys.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/gdb-stub.c linux/arch/mips/kernel/gdb-stub.c
--- v2.1.125/linux/arch/mips/kernel/gdb-stub.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/gdb-stub.c	Tue Oct 20 13:52:54 1998
@@ -12,7 +12,7 @@
  *
  *  Copyright (C) 1995 Andreas Busse
  *
- * $Id: gdb-stub.c,v 1.7 1998/05/01 01:33:51 ralf Exp $
+ * $Id: gdb-stub.c,v 1.4 1997/12/02 05:51:06 ralf Exp $
  */
 
 /*
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S
--- v2.1.125/linux/arch/mips/kernel/head.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/head.S	Tue Oct 20 13:52:54 1998
@@ -1,19 +1,25 @@
-/*
- *  arch/mips/kernel/head.S
+/* $Id: head.S,v 1.13 1998/10/14 20:26:27 ralf Exp $
+ *
+ * arch/mips/kernel/head.S
  *
- *  Copyright (C) 1994, 1995 Waldorf Electronics, 1996 Paul M. Antoine
- *  Written by Ralf Baechle and Andreas Busse
- *  Modified for DECStation and hence R3000 support by Paul M. Antoine
- *  Further modifications by David S. Miller
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *  Head.S contains the MIPS exception handler and startup code.
+ * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Further modifications by David S. Miller
  *
- * $Id: head.S,v 1.9 1998/05/01 01:33:53 ralf Exp $
+ * Head.S contains the MIPS exception handler and startup code.
  */
 #include <linux/config.h>
 #include <linux/tasks.h>
 
 #include <asm/asm.h>
+#include <asm/cacheops.h>
 #include <asm/current.h>
 #include <asm/offset.h>
 #include <asm/processor.h>
@@ -29,10 +35,10 @@
 	/*
 	 * Reserved space for exception handlers.
 	 * Necessary for machines which link their kernels at KSEG0.
-	 * FIXME: We could overwrite some of the useless handlers
-	 * with those actually being used.
+	 * FIXME: Use the initcode feature to get rid of unused handler
+	 * variants.
 	 */
-	.fill	520
+	.fill	0x280
 /*	
  * This is space for the interrupt handlers.
  * After trap_init() they are located at virtual address KSEG0.
@@ -317,16 +323,48 @@
 	NESTED(except_vec3_r4000, 0, sp)
 	.set	noat
 	mfc0	k1, CP0_CAUSE
-
-	/* XXX Have to check for VCE's _before_ we do a load or store. */
-
-	la	k0, exception_handlers
 	andi	k1, k1, 0x7c
+	li	k0, 31<<2
+	beq	k1, k0, handle_vced
+	 li	k0, 14<<2
+	beq	k1, k0, handle_vcei
+	 la	k0, exception_handlers
 	addu	k0, k0, k1
 	lw	k0, (k0)
 	nop
 	jr	k0
 	 nop
+
+/*
+ * Big shit, we now may have two dirty primary cache lines for the same
+ * physical address.  We can savely invalidate the line pointed to by
+ * c0_badvaddr because after return from this exception handler the load /
+ * store will be re-executed.
+ */
+handle_vced:
+	mfc0	k0, CP0_BADVADDR
+ li k1, -4
+ and k0, k1
+	mtc0	zero, CP0_TAGLO
+ //	nop;nop
+	cache	Index_Store_Tag_D,(k0)
+ //	nop;nop
+	cache	Hit_Writeback_Inv_SD,(k0)
+	lui	k0, %hi(vced_count)
+	lw	k1, %lo(vced_count)(k0)
+	addiu	k1, 1
+	sw	k1, %lo(vced_count)(k0)
+	eret
+
+handle_vcei:
+	mfc0	k0, CP0_BADVADDR
+	cache	Hit_Writeback_Inv_SD,(k0)		# also cleans pi
+	lui	k0, %hi(vcei_count)
+	lw	k1, %lo(vcei_count)(k0)
+	addiu	k1, 1
+	sw	k1, %lo(vcei_count)(k0)
+	eret
+
 	END(except_vec3_r4000)
 	.set	at
 
@@ -779,32 +817,35 @@
 		.word  	0			# no. wired TLB entries
 		.word	0			# dummy
 
-			.text
-
-			.org	0x1000
-			EXPORT(swapper_pg_dir)
-
-			.org	0x2000
-			EXPORT(empty_bad_page)
+/*
+ * This buffer is reserved for the use of the cache error handler.
+ */
+		.data
+		EXPORT(cache_error_buffer)
+		.fill	32*4,1,0
 
-			.org	0x3000
-			EXPORT(empty_bad_page_table)
+EXPORT(kernelsp)
+		PTR	0
+		.text
 
-			.org	0x4000
-			EXPORT(empty_zero_page)
+		.org	0x1000
+EXPORT(swapper_pg_dir)
 
-			.org	0x5000
-			EXPORT(invalid_pte_table)
+		.org	0x2000
+EXPORT(empty_bad_page)
 
-			.org	0x6000
+		.org	0x3000
+EXPORT(empty_bad_page_table)
 
-			/*
-			 * init_task_union follows here in the .text segment.
-			 * Keep this aligned to a 8kb boundary!
-			 */
-			.data
-			EXPORT(cache_error_buffer)
-			.fill	32*4,1,0
+		.org	0x4000
+EXPORT(invalid_pte_table)
 
-			EXPORT(kernelsp)
-			PTR	0
+		.org	0x5000
+/* XXX This label is required to keep GAS trying to be too clever ...
+   Bug?  */
+dummy:
+/*
+ * Align to 8kb boundary for init_task_union which follows in the
+ * .text segment.
+ */
+		.align	13
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irix5sys.h linux/arch/mips/kernel/irix5sys.h
--- v2.1.125/linux/arch/mips/kernel/irix5sys.h	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/irix5sys.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,5 @@
-/* $Id: irix5sys.h,v 1.3 1998/05/01 01:33:55 ralf Exp $
+/* $Id: irix5sys.h,v 1.2 1998/08/17 10:16:25 ralf Exp $
+ *
  * irix5sys.h: 32-bit IRIX5 ABI system call table.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -34,7 +35,7 @@
 SYS(irix_gtime, 0)			/* 1013  time()		       V*/
 SYS(irix_unimp, 0)			/* 1014  (XXX IRIX 4 mknod)    V*/
 SYS(sys_chmod, 2)			/* 1015  chmod()	       V*/
-SYS(irix_chown, 3)			/* 1016  chown()	       V*/
+SYS(sys_chown, 3)			/* 1016  chown()	       V*/
 SYS(irix_brk, 1)			/* 1017  break()	       V*/
 SYS(irix_unimp, 0)			/* 1018  (XXX IRIX 4 stat)     V*/
 SYS(sys_lseek, 3)			/* 1019  lseek()     XXX64bit HV*/
@@ -196,7 +197,7 @@
 SYS(irix_fstatvfs, 2)			/* 1175  fstatvfs()	       V*/
 SYS(irix_unimp, 0)			/* 1176  XXX getpmsg()	      DC*/
 SYS(irix_unimp, 0)			/* 1177  XXX putpmsg()	      DC*/
-SYS(irix_lchown, 3)			/* 1178  lchown()	       V*/
+SYS(sys_lchown, 3)			/* 1178  lchown()	       V*/
 SYS(irix_priocntl, 0)			/* 1179  priocntl()	      DC*/
 SYS(irix_sigqueue, 4)			/* 1180  sigqueue()	      IV*/
 SYS(sys_readv, 3)			/* 1181  readv()	       V*/
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
--- v2.1.125/linux/arch/mips/kernel/irixelf.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/irixelf.c	Tue Oct 20 13:52:54 1998
@@ -378,8 +378,8 @@
 
 	/* Now fill out the bss section.  First pad the last page up
 	 * to the page boundary, and then perform a mmap to make sure
-	 * that there are zeromapped pages up to and including the last
-	 * bss page.
+	 * that there are zero-mapped pages up to and including the
+	 * last bss page.
 	 */
 #ifdef DEBUG_ELF
 	printk("padzero(%08lx) ", (unsigned long) (elf_bss));
@@ -1254,10 +1254,9 @@
 	notes[1].type = NT_PRPSINFO;
 	notes[1].datasz = sizeof(psinfo);
 	notes[1].data = &psinfo;
-	psinfo.pr_state = current->state;
-	psinfo.pr_sname =
-		((current->state < 0 || current->state > 5) ?
-		('.') : ("RSDZTD"[current->state]));
+	i = current->state ? ffz(~current->state) + 1 : 0;
+	psinfo.pr_state = i;
+	psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
 	psinfo.pr_zomb = psinfo.pr_sname == 'Z';
 	psinfo.pr_nice = current->priority-15;
 	psinfo.pr_flag = current->flags;
@@ -1286,7 +1285,7 @@
 	notes[2].datasz = sizeof(*current);
 	notes[2].data = current;
 	
-	/* Try to dump the fpu. */
+	/* Try to dump the FPU. */
 	prstatus.pr_fpvalid = dump_fpu (&fpu);
 	if (!prstatus.pr_fpvalid) {
 		numnote--;
@@ -1388,7 +1387,7 @@
 	return has_dumped;
 }
 
-__initfunc(int init_irix_binfmt(void))
+int __init init_irix_binfmt(void)
 {
 	return register_binfmt(&irix_format);
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixinv.c linux/arch/mips/kernel/irixinv.c
--- v2.1.125/linux/arch/mips/kernel/irixinv.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/irixinv.c	Tue Oct 20 13:52:54 1998
@@ -5,7 +5,7 @@
  *
  * Miguel de Icaza, 1997.
  *
- * $Id: irixinv.c,v 1.2 1998/05/01 01:33:58 ralf Exp $
+ * $Id: irixinv.c,v 1.3 1998/03/27 08:53:40 ralf Exp $
  */
 #include <linux/mm.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixioctl.c linux/arch/mips/kernel/irixioctl.c
--- v2.1.125/linux/arch/mips/kernel/irixioctl.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/irixioctl.c	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: irixioctl.c,v 1.6 1998/05/01 01:33:59 ralf Exp $
+/* $Id: irixioctl.c,v 1.4 1998/03/04 12:17:41 ralf Exp $
  * irixioctl.c: A fucking mess...
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixsig.c linux/arch/mips/kernel/irixsig.c
--- v2.1.125/linux/arch/mips/kernel/irixsig.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/irixsig.c	Tue Oct 20 13:52:54 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: irixsig.c,v 1.8 1998/05/01 01:34:00 ralf Exp $
+ * $Id: irixsig.c,v 1.11 1998/03/26 07:39:09 ralf Exp $
  */
 
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c
--- v2.1.125/linux/arch/mips/kernel/irq.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/irq.c	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.13 1998/05/08 01:44:12 ralf Exp $
+/* $Id: irq.c,v 1.13 1998/05/28 03:17:55 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -27,7 +27,6 @@
 #include <asm/irq.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
-#include <asm/vector.h>
 
 unsigned char cache_21 = 0xff;
 unsigned char cache_A1 = 0xff;
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/mips_ksyms.c linux/arch/mips/kernel/mips_ksyms.c
--- v2.1.125/linux/arch/mips/kernel/mips_ksyms.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/mips_ksyms.c	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,12 @@
-/*
+/* $Id: mips_ksyms.c,v 1.12 1998/09/16 22:50:41 ralf Exp $
+ *
  * Export MIPS-specific functions needed for loadable modules.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997 by Ralf Baechle
- *
- * $Id: mips_ksyms.c,v 1.7 1998/05/04 09:17:52 ralf Exp $
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -27,6 +26,14 @@
 #include <asm/softirq.h>
 #include <asm/uaccess.h>
 
+extern void *__bzero(void *__s, size_t __count);
+extern long __strncpy_from_user_nocheck_asm(char *__to,
+                                            const char *__from, long __len);
+extern long __strncpy_from_user_asm(char *__to, const char *__from,
+                                    long __len);
+extern long __strlen_user_nocheck_asm(const char *s);
+extern long __strlen_user_asm(const char *s);
+
 EXPORT_SYMBOL(EISA_bus);
 
 /*
@@ -48,11 +55,19 @@
 EXPORT_SYMBOL(__mips_bh_counter);
 EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(local_irq_count);
+//EXPORT_SYMBOL(enable_irq);
+//EXPORT_SYMBOL(disable_irq);
 
 /*
  * Userspace access stuff.
  */
 EXPORT_SYMBOL(__copy_user);
+EXPORT_SYMBOL(__bzero);
+EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm);
+EXPORT_SYMBOL(__strncpy_from_user_asm);
+EXPORT_SYMBOL(__strlen_user_nocheck_asm);
+EXPORT_SYMBOL(__strlen_user_asm);
+
 
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_partial_copy);
@@ -61,7 +76,6 @@
  * Functions to control caches.
  */
 EXPORT_SYMBOL(flush_page_to_ram);
-EXPORT_SYMBOL(fd_cacheflush);
 EXPORT_SYMBOL(flush_cache_all);
 
 /*
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/pci.c linux/arch/mips/kernel/pci.c
--- v2.1.125/linux/arch/mips/kernel/pci.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/pci.c	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.11 1998/07/15 20:34:33 mj Exp $
+/* $Id: pci.c,v 1.6 1998/08/19 21:53:50 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -40,7 +40,7 @@
  * each PCI chipset configuration.  We just run the hook to the machine
  * specific implementation.
  */
-__initfunc(void pcibios_fixup (void))
+void pcibios_fixup (void)
 {
 	return pci_ops->pcibios_fixup();
 }
@@ -79,6 +79,11 @@
                                 unsigned char where, unsigned int val)
 {
 	return pci_ops->pcibios_write_config_dword(bus, dev_fn, where, val);
+}
+
+__initfunc(char *pcibios_setup(char *str))
+{
+	return str;
 }
 
 __initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/proc.c linux/arch/mips/kernel/proc.c
--- v2.1.125/linux/arch/mips/kernel/proc.c	Wed Dec 10 10:31:09 1997
+++ linux/arch/mips/kernel/proc.c	Tue Oct 20 13:52:54 1998
@@ -12,6 +12,7 @@
 #include <asm/watch.h>
 
 unsigned long unaligned_instructions;
+unsigned int vced_count, vcei_count;
 
 /*
  * BUFFER is PAGE_SIZE bytes long.
@@ -21,6 +22,7 @@
  */
 int get_cpuinfo(char *buffer)
 {
+	char fmt [64];
 	const char *cpu_name[] = CPU_NAMES;
 	const char *mach_group_names[] = GROUP_NAMES;
 	const char *mach_unknown_names[] = GROUP_UNKNOWN_NAMES;
@@ -69,6 +71,11 @@
 	               dedicated_iv_available ? "yes" : "no");
 	len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
 	               watch_available ? "yes" : "no");
+
+	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
+	        vce_available ? "%d" : "not available");
+	len += sprintf(buffer + len, fmt, 'D', vced_count);
+	len += sprintf(buffer + len, fmt, 'I', vcei_count);
 
 	return len;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
--- v2.1.125/linux/arch/mips/kernel/process.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/process.c	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,10 @@
-/*
- * linux/arch/mips/kernel/process.c
+/* $Id: process.c,v 1.11 1998/08/17 12:14:53 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1994 - 1998 by Ralf Baechle and others.
- *
- * $Id: process.c,v 1.11 1998/05/15 13:04:01 davem Exp $
  */
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -31,6 +28,8 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/elf.h>
+
+struct task_struct *last_task_used_math = NULL;
 
 asmlinkage void ret_from_sys_call(void);
 
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- v2.1.125/linux/arch/mips/kernel/ptrace.c	Wed Sep  9 14:51:06 1998
+++ linux/arch/mips/kernel/ptrace.c	Tue Oct 20 13:52:54 1998
@@ -1,8 +1,14 @@
-/* ptrace.c */
-/* By Ross Biro 1/23/92 */
-/* edited by Linus Torvalds */
-/* further hacked for MIPS by David S. Miller (dm@engr.sgi.com) */
-
+/* $Id: ptrace.c,v 1.11 1998/10/19 16:26:31 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ */
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -12,10 +18,12 @@
 #include <linux/smp_lock.h>
 #include <linux/user.h>
 
-#include <asm/uaccess.h>
+#include <asm/fp.h>
+#include <asm/mipsregs.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/system.h>
+#include <asm/uaccess.h>
 
 /*
  * This routine gets a long from any process space by following the page
@@ -67,6 +75,7 @@
 	 */
 	flush_cache_all();
 	retval = *(unsigned long *) page;
+	flush_cache_all();	/* VCED avoidance  */
 	return retval;
 }
 
@@ -121,10 +130,10 @@
 	}
 	/* This is a hack for non-kernel-mapped video buffers and similar */
 	if (MAP_NR(page) < MAP_NR(high_memory))
-		flush_cache_page(vma, addr);
+		flush_cache_all();
 	*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
 	if (MAP_NR(page) < MAP_NR(high_memory))
-		flush_page_to_ram(page);
+		flush_cache_all();
 	/*
 	 * We're bypassing pagetables, so we have to set the dirty bit
 	 * ourselves this should also re-instate whatever read-only mode
@@ -324,163 +333,182 @@
 	}
 
 	switch (request) {
-	/* when I and D space are separate, these will need to be fixed. */
-		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-		case PTRACE_PEEKDATA: {
-			unsigned long tmp;
+	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKDATA: {
+		unsigned long tmp;
 
-			res = read_long(child, addr, &tmp);
-			if (res < 0)
-				goto out;
-			res = put_user(tmp,(unsigned long *) data);
+		res = read_long(child, addr, &tmp);
+		if (res < 0)
 			goto out;
+		res = put_user(tmp,(unsigned long *) data);
+		goto out;
 		}
 
 	/* read the word at location addr in the USER area. */
 /* #define DEBUG_PEEKUSR */
-		case PTRACE_PEEKUSR: {
-			struct pt_regs *regs;
-			unsigned long tmp;
-
-			regs = (struct pt_regs *) ((unsigned long) child +
-			       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
-			tmp = 0;  /* Default return value. */
-			if(addr < 32 && addr >= 0) {
-				tmp = regs->regs[addr];
-			} else if(addr >= 32 && addr < 64) {
-				unsigned long long *fregs;
-
-				/* We don't want to do a FPU operation here. */
+	case PTRACE_PEEKUSR: {
+		struct pt_regs *regs;
+		unsigned long tmp;
+
+		regs = (struct pt_regs *) ((unsigned long) child +
+		       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
+		tmp = 0;  /* Default return value. */
+		if (addr < 32 && addr >= 0)
+			tmp = regs->regs[addr];
+		else if (addr >= 32 && addr < 64) {
+			unsigned long long *fregs;
+
+			if (child->used_math) {
+				if (last_task_used_math == child) {
+					enable_cp1();
+					r4xx0_save_fp(child);
+					disable_cp1();
+					last_task_used_math = NULL;
+				}
 				fregs = (unsigned long long *)
 					&child->tss.fpu.hard.fp_regs[0];
 				tmp = (unsigned long) fregs[(addr - 32)];
 			} else {
-				addr -= 64;
-				switch(addr) {
-				case 0:
-					tmp = regs->cp0_epc;
-					break;
-				case 1:
-					tmp = regs->cp0_cause;
-					break;
-				case 2:
-					tmp = regs->cp0_badvaddr;
-					break;
-				case 3:
-					tmp = regs->lo;
-					break;
-				case 4:
-					tmp = regs->hi;
-					break;
-				case 5:
-					tmp = child->tss.fpu.hard.control;
-					break;
-				case 6:	/* implementation / version register */
-					tmp = 0;
-					break;
-				default:
-					tmp = 0;
-					res = -EIO;
-					goto out;
-				};
+				tmp = -1;	/* FP not yet used  */
+			}
+		} else {
+			addr -= 64;
+			switch(addr) {
+			case 0:
+				tmp = regs->cp0_epc;
+				break;
+			case 1:
+				tmp = regs->cp0_cause;
+				break;
+			case 2:
+				tmp = regs->cp0_badvaddr;
+				break;
+			case 3:
+				tmp = regs->lo;
+				break;
+			case 4:
+				tmp = regs->hi;
+				break;
+			case 5:
+				tmp = child->tss.fpu.hard.control;
+				break;
+			case 6:	/* implementation / version register */
+				tmp = 0;	/* XXX */
+				break;
+			default:
+				tmp = 0;
+				res = -EIO;
+				goto out;
 			}
-			res = put_user(tmp, (unsigned long *) data);
-			goto out;
+		}
+		res = put_user(tmp, (unsigned long *) data);
+		goto out;
 		}
 
-      /* when I and D space are separate, this will have to be fixed. */
-		case PTRACE_POKETEXT: /* write the word at location addr. */
-		case PTRACE_POKEDATA:
-			res = write_long(child,addr,data);
-			goto out;
-
-		case PTRACE_POKEUSR: {
-			struct pt_regs *regs;
-			int res = 0;
-
-			regs = (struct pt_regs *) ((unsigned long) child +
-			       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
-			if(addr < 32 && addr >= 0) {
-				regs->regs[addr] = data;
-			} else if(addr >= 32 && addr < 64) {
-				unsigned long long *fregs;
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		res = write_long(child,addr,data);
+		goto out;
 
-				/* We don't want to do a FPU operation here. */
-				fregs = (unsigned long long *)
-					&child->tss.fpu.hard.fp_regs[0];
-				fregs[(addr - 32)] = (unsigned long long) data;
+	case PTRACE_POKEUSR: {
+		struct pt_regs *regs;
+		int res = 0;
+
+		regs = (struct pt_regs *) ((unsigned long) child +
+		       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
+		if (addr < 32 && addr >= 0)
+			regs->regs[addr] = data;
+		else if (addr >= 32 && addr < 64) {
+			unsigned long long *fregs;
+
+			if (child->used_math) {
+				if (last_task_used_math == child) {
+					enable_cp1();
+					r4xx0_save_fp(child);
+					disable_cp1();
+					last_task_used_math = NULL;
+				}
 			} else {
-				addr -= 64;
-				switch(addr) {
-				case 0:
-					regs->cp0_epc = data;
-					break;
-				case 3:
-					regs->lo = data;
-					break;
-				case 4:
-					regs->hi = data;
-					break;
-				case 5:
-					child->tss.fpu.hard.control = data;
-					break;
-				default:
-					/* The rest are not allowed. */
-					res = -EIO;
-					break;
-				};
+				/* FP not yet used  */
+				memset(&child->tss.fpu.hard, ~0,
+				       sizeof(child->tss.fpu.hard));
+				child->tss.fpu.hard.control = 0;
 			}
-			goto out;
-		}
-
-		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-		case PTRACE_CONT: { /* restart after signal. */
-			if ((unsigned long) data > _NSIG) {
+			fregs = (unsigned long long *)
+				&child->tss.fpu.hard.fp_regs[0];
+			fregs[(addr - 32)] = (unsigned long long) data;
+		} else {
+			addr -= 64;
+			switch (addr) {
+			case 0:
+				regs->cp0_epc = data;
+				break;
+			case 3:
+				regs->lo = data;
+				break;
+			case 4:
+				regs->hi = data;
+				break;
+			case 5:
+				child->tss.fpu.hard.control = data;
+				break;
+			default:
+				/* The rest are not allowed. */
 				res = -EIO;
-				goto out;
-			}
-			if (request == PTRACE_SYSCALL)
-				child->flags |= PF_TRACESYS;
-			else
-				child->flags &= ~PF_TRACESYS;
-			child->exit_code = data;
-			wake_up_process(child);
-			res = data;
-			goto out;
+				break;
+			};
+		}
+		goto out;
 		}
 
-/*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
- * exit.
- */
-		case PTRACE_KILL: {
-			if (child->state != TASK_ZOMBIE) {
-				wake_up_process(child);
-				child->exit_code = SIGKILL;
-			}
-			res = 0;
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: { /* restart after signal. */
+		if ((unsigned long) data > _NSIG) {
+			res = -EIO;
 			goto out;
 		}
+		if (request == PTRACE_SYSCALL)
+			child->flags |= PF_TRACESYS;
+		else
+			child->flags &= ~PF_TRACESYS;
+		child->exit_code = data;
+		wake_up_process(child);
+		res = data;
+		goto out;
+		}
 
-		case PTRACE_DETACH: { /* detach a process that was attached. */
-			if ((unsigned long) data > _NSIG) {
-				res = -EIO;
-				goto out;
-			}
-			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill. 
+	 * perhaps it should be put in the status that it wants to 
+	 * exit.
+	 */
+	case PTRACE_KILL: {
+		if (child->state != TASK_ZOMBIE) {
+			child->exit_code = SIGKILL;
 			wake_up_process(child);
-			child->exit_code = data;
-			REMOVE_LINKS(child);
-			child->p_pptr = child->p_opptr;
-			SET_LINKS(child);
-			res = 0;
-			goto out;
+		}
+		res = 0;
+		goto out;
 		}
 
-		default:
+	case PTRACE_DETACH: { /* detach a process that was attached. */
+		if ((unsigned long) data > _NSIG) {
 			res = -EIO;
 			goto out;
+		}
+		child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+		child->exit_code = data;
+		REMOVE_LINKS(child);
+		child->p_pptr = child->p_opptr;
+		SET_LINKS(child);
+		wake_up_process(child);
+		res = 0;
+		goto out;
+		}
+
+	default:
+		res = -EIO;
+		goto out;
 	}
 out:
 	unlock_kernel();
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r2300_fpu.S linux/arch/mips/kernel/r2300_fpu.S
--- v2.1.125/linux/arch/mips/kernel/r2300_fpu.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/r2300_fpu.S	Tue Oct 20 13:52:54 1998
@@ -10,7 +10,7 @@
  * Multi-arch abstraction and asm macros for easier reading:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r2300_fpu.S,v 1.4 1998/05/01 01:34:08 ralf Exp $
+ * $Id: r2300_fpu.S,v 1.3 1997/12/01 16:54:20 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/fpregdef.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r2300_misc.S linux/arch/mips/kernel/r2300_misc.S
--- v2.1.125/linux/arch/mips/kernel/r2300_misc.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/r2300_misc.S	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: r2300_misc.S,v 1.2 1998/05/01 01:34:10 ralf Exp $
+/* $Id: r2300_misc.S,v 1.1.1.1 1997/06/01 03:16:42 ralf Exp $
  * r2300_misc.S: Misc. exception handling code for R3000/R2000.
  *
  * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r2300_switch.S linux/arch/mips/kernel/r2300_switch.S
--- v2.1.125/linux/arch/mips/kernel/r2300_switch.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/r2300_switch.S	Tue Oct 20 13:52:54 1998
@@ -6,7 +6,7 @@
  * Multi-cpu abstraction and macros for easier reading:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r2300_switch.S,v 1.2 1998/05/01 01:34:14 ralf Exp $
+ * $Id: r2300_switch.S,v 1.4 1998/04/04 13:59:38 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r4k_fpu.S linux/arch/mips/kernel/r4k_fpu.S
--- v2.1.125/linux/arch/mips/kernel/r4k_fpu.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/r4k_fpu.S	Tue Oct 20 13:52:54 1998
@@ -10,7 +10,7 @@
  * Multi-arch abstraction and asm macros for easier reading:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r4k_fpu.S,v 1.4 1998/05/01 01:34:15 ralf Exp $
+ * $Id: r4k_fpu.S,v 1.4 1998/04/04 13:59:38 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/fpregdef.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r4k_misc.S linux/arch/mips/kernel/r4k_misc.S
--- v2.1.125/linux/arch/mips/kernel/r4k_misc.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/r4k_misc.S	Tue Oct 20 13:52:54 1998
@@ -6,7 +6,7 @@
  * Multi-cpu abstraction and reworking:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r4k_misc.S,v 1.4 1998/05/01 01:34:17 ralf Exp $
+ * $Id: r4k_misc.S,v 1.3 1997/09/07 04:51:07 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/current.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r4k_switch.S linux/arch/mips/kernel/r4k_switch.S
--- v2.1.125/linux/arch/mips/kernel/r4k_switch.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/r4k_switch.S	Tue Oct 20 13:52:54 1998
@@ -1,12 +1,12 @@
-/*
- * r4k_switch.S: R4xx0 specific task switching code.
+/* $Id: r4k_switch.S,v 1.4 1998/07/14 09:15:33 ralf Exp $
  *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * Multi-cpu abstraction and macros for easier reading:
+ * Copyright (C) 1994, 1995, 1996, 1998 by Ralf Baechle
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r4k_switch.S,v 1.2 1998/05/01 01:34:19 ralf Exp $
+ * Copyright (C) 1994, 1995, 1996, by Andreas Busse
  */
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
@@ -28,12 +28,8 @@
 	.set	mips3
 	.align	5
 	LEAF(r4xx0_resume)
-	mfc0	t1, CP0_STATUS			# fp exception boundary
-	sll	t0, t1, 2
-	bgez	t0, 1f
-	 nop
-	cfc1	zero, fcr31
-1:	sw	t1, THREAD_STATUS($28)
+	mfc0	t1, CP0_STATUS
+	sw	t1, THREAD_STATUS($28)
 	CPU_SAVE_NONSCRATCH($28)
 	sw	ra, THREAD_REG31($28)
 
@@ -114,7 +110,7 @@
  * We initialize fcr31 to rounding to nearest, no exceptions.
  */
 
-#define FPU_DEFAULT  0x00000600
+#define FPU_DEFAULT  0x00000000
 
 LEAF(r4xx0_init_fpu)
 	mfc0	t0, CP0_STATUS
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r6000_fpu.S linux/arch/mips/kernel/r6000_fpu.S
--- v2.1.125/linux/arch/mips/kernel/r6000_fpu.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/r6000_fpu.S	Tue Oct 20 13:52:54 1998
@@ -10,7 +10,7 @@
  * Multi-arch abstraction and asm macros for easier reading:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r6000_fpu.S,v 1.4 1998/05/01 01:34:20 ralf Exp $
+ * $Id: r6000_fpu.S,v 1.3 1997/12/01 16:56:56 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/fpregdef.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/scall_o32.S linux/arch/mips/kernel/scall_o32.S
--- v2.1.125/linux/arch/mips/kernel/scall_o32.S	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/scall_o32.S	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,10 @@
-/*
- * arch/mips/kernel/scall_o32.S
+/* $Id: scall_o32.S,v 1.5 1998/08/19 21:53:50 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1997, 1998 by Ralf Baechle
- *
- * $Id: scall_o32.S,v 1.2 1998/07/26 03:02:07 davem Exp $
  */
 #include <asm/asm.h>
 #include <linux/errno.h>
@@ -73,8 +70,7 @@
 
 9:	lw	t0,PT_STATUS(sp)	# returning to kernel mode?
 	andi	t1, t0, 0x10
-#error Change this to current->need_resched --DaveM
-	lw	t2, need_resched
+	lw	t2, TASK_NEED_RESCHED($28)
 	beqz	t1, o32_return		# -> yes
 	bnez	t2, o32_reschedule
 	lw	v0, TASK_SIGPENDING($28)
@@ -105,9 +101,13 @@
 	SAVE_STATIC
 	sw	t2,PT_R1(sp)
 	jal	syscall_trace
-	sw	t2,PT_R1(sp)
+	lw	t2,PT_R1(sp)
 
-	jalr	t2			# Do The Real Thing (TM)
+	lw	a0, PT_R4(sp)		# Restore argument registers
+	lw	a1, PT_R5(sp)
+	lw	a2, PT_R6(sp)
+	lw	a3, PT_R7(sp)
+	jalr	t2
 
 	li	t0, -EMAXERRNO - 1	# error?
 	sltu	t0, t0, v0
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
--- v2.1.125/linux/arch/mips/kernel/setup.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/setup.c	Tue Oct 20 13:52:54 1998
@@ -1,11 +1,12 @@
-/*
- *  linux/arch/mips/kernel/setup.c
+/* $Id: setup.c,v 1.12 1998/08/18 20:45:06 ralf Exp $
  *
- *  Copyright (C) 1995  Linus Torvalds
- *  Copyright (C) 1995, 1996  Ralf Baechle
- *  Copyright (C) 1996  Stoned Elipot
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * $Id: setup.c,v 1.10 1998/06/10 07:21:10 davem Exp $
+ * Copyright (C) 1995  Linus Torvalds
+ * Copyright (C) 1995, 1996, 1997, 1998  Ralf Baechle
+ * Copyright (C) 1996  Stoned Elipot
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -37,23 +38,13 @@
 #include <asm/cachectl.h>
 #include <asm/ide.h>
 #include <asm/io.h>
-#include <asm/vector.h>
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #ifdef CONFIG_SGI
 #include <asm/sgialib.h>
 #endif
 
-/*
- * How to handle the machine's features
- */
-struct feature *feature;
-
-/*
- * What to do to keep the caches consistent with memory
- * We don't use the normal cacheflush routine to keep Tyne caches happier.
- */
-void (*fd_cacheflush)(const void *addr, size_t size);
+struct mips_cpuinfo boot_cpu_data = { NULL, NULL, 0 };
 
 /*
  * Not all of the MIPS CPUs have the "wait" instruction available.  This
@@ -88,13 +79,21 @@
 struct drive_info_struct drive_info = DEFAULT_DRIVE_INFO;
 struct screen_info screen_info = DEFAULT_SCREEN_INFO;
 
+#ifdef CONFIG_BLK_DEV_FD
+extern struct fd_ops no_fd_ops;
+struct fd_ops *fd_ops;
+#endif
+
 #ifdef CONFIG_BLK_DEV_IDE
 extern struct ide_ops no_ide_ops;
 struct ide_ops *ide_ops;
 #endif
 
+extern struct rtc_ops no_rtc_ops;
+struct rtc_ops *rtc_ops;
+
 /*
- * setup informations
+ * Setup information
  *
  * These are intialized so they are in the .data section
  */
@@ -150,15 +149,12 @@
 	panic("Unknown machtype in init_IRQ");
 }
 
-__initfunc(static void default_fd_cacheflush(const void *addr, size_t size))
-{
-}
-
 __initfunc(void setup_arch(char **cmdline_p,
            unsigned long * memory_start_p, unsigned long * memory_end_p))
 {
 	unsigned long memory_end;
 	tag* atag;
+	void cobalt_setup(void);
 	void decstation_setup(void);
 	void deskstation_setup(void);
 	void jazz_setup(void);
@@ -179,13 +175,24 @@
 
 	/* Save defaults for configuration-dependent routines.  */
 	irq_setup = default_irq_setup;
-	fd_cacheflush = default_fd_cacheflush;
+
+#ifdef CONFIG_BLK_DEV_FD
+	fd_ops = &no_fd_ops;
+#endif
+
 #ifdef CONFIG_BLK_DEV_IDE
 	ide_ops = &no_ide_ops;
 #endif
 
+	rtc_ops = &no_rtc_ops;
+
 	switch(mips_machgroup)
 	{
+#ifdef CONFIG_COBALT_MICRO_SERVER
+	case MACH_GROUP_COBALT:
+		cobalt_setup();
+		break;
+#endif
 #ifdef CONFIG_MIPS_JAZZ
 	case MACH_GROUP_JAZZ:
 		jazz_setup();
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c
--- v2.1.125/linux/arch/mips/kernel/signal.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/signal.c	Tue Oct 20 13:52:54 1998
@@ -1,10 +1,9 @@
-/*
+/* $Id: signal.c,v 1.24 1998/09/16 22:50:42 ralf Exp $
+ *
  *  linux/arch/mips/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1994, 1995, 1996  Ralf Baechle
- *
- * $Id: signal.c,v 1.13 1998/06/10 07:21:12 davem Exp $
+ *  Copyright (C) 1994, 1995, 1996, 1997, 1998  Ralf Baechle
  *
  * XXX Handle lazy fp context switches correctly.
  */
@@ -23,6 +22,7 @@
 #include <asm/asm.h>
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
+#include <asm/stackframe.h>
 #include <asm/uaccess.h>
 
 #define DEBUG_SIG 0
@@ -43,6 +43,7 @@
 {
 	sigset_t *uset, saveset, newset;
 
+	save_static(&regs);
 	uset = (sigset_t *) regs.regs[4];
 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
 		return -EFAULT;
@@ -53,7 +54,8 @@
 	current->blocked = newset;
 	spin_unlock_irq(&current->sigmask_lock);
 
-	regs.regs[2] = -EINTR;
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
@@ -67,6 +69,7 @@
 {
 	sigset_t *uset, saveset, newset;
 
+	save_static(&regs);
 	uset = (sigset_t *) regs.regs[4];
 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
 		return -EFAULT;
@@ -77,7 +80,8 @@
 	current->blocked = newset;
 	spin_unlock_irq(&current->sigmask_lock);
 
-	regs.regs[2] = -EINTR;
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
@@ -116,6 +120,14 @@
 	}
 
 	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	struct pt_regs *regs = (struct pt_regs *) &uss;
+
+	return do_sigaltstack(uss, uoss, regs->regs[29]);
 }
 
 /*
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/softfp.S linux/arch/mips/kernel/softfp.S
--- v2.1.125/linux/arch/mips/kernel/softfp.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/kernel/softfp.S	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,667 @@
+/* $Id: softfp.S,v 1.1 1998/07/14 09:33:48 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ *
+ * For now it's just a crude hack good enough to run certain fp programs like
+ * Mozilla.
+ * XXX: Handle MIPS II/III/IV/V enhancements, exceptions, ...
+ */
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+#ifndef __KERNEL__
+#define printk printf
+#endif
+
+#define LOCK_KERNEL
+#define UNLOCK_KERNEL
+
+/*
+ * This duplicates definitions from <linux/kernel.h>.
+ */
+#define KERN_EMERG      "<0>"   /* system is unusable                   */
+#define KERN_ALERT      "<1>"   /* action must be taken immediately     */
+#define KERN_CRIT       "<2>"   /* critical conditions                  */
+#define KERN_ERR        "<3>"   /* error conditions                     */
+#define KERN_WARNING    "<4>"   /* warning conditions                   */
+#define KERN_NOTICE     "<5>"   /* normal but significant condition     */
+#define KERN_INFO       "<6>"   /* informational                        */
+#define KERN_DEBUG      "<7>"   /* debug-level messages                 */
+
+/*
+ * This duplicates definitions from <asm/signal.h>
+ */
+#define SIGILL           4      /* Illegal instruction (ANSI).  */
+
+/*
+ * Definitions about the instruction format
+ */
+#define fd_shift	6
+#define fr_shift	21
+#define fs_shift	11
+#define ft_shift	16
+
+/*
+ * NaNs as use by the MIPS architecture
+ */
+#define S_QNaN		0x7fbfffff
+#define D_QNaN		0x7ff7ffffffffffff
+#define W_QNaN		0x7fffffff
+#define L_QNaN		0x7fffffffffffffff
+
+/*
+ * Checking for NaNs
+ */
+#define S_is_QNaN(reg,res)						\
+	sll	res, reg, S_F_size - S_F_bits
+#define D_is_QNaN(reg1,reg2,res)					\
+	sll	res, reg1, (D_F_size - 32) - (D_F_bits - 32);		\
+	or	res, reg2
+
+/*
+ * Checking for Denorms
+ */
+#define S_is_Denorm(reg,res)						\
+	li	res, 1 << (S_F_bits - 1);				\
+	and	reg, res
+
+/*
+ * Some constants that define the properties of single precission numbers.
+ */
+#define S_M_prec	24
+#define S_E_max		127
+#define S_E_min		-126
+#define S_E_bias	127
+#define S_E_bits	8
+#define S_F_bits	23
+#define S_F_size	32
+
+/* Set temp0, if exponent of reg is S_E_max + 1.  */
+#define S_is_E_max(reg,temp0,temp1)					\
+	li	temp0, (S_E_max + 1 + S_E_bias) << S_F_bits;		\
+	and	temp1, temp0, reg;					\
+	seq	temp0, temp1			/* temp0 != 0 if NaN */
+
+/* Clear temp0, if exponent of reg is S_E_min - 1.  */
+#define S_is_E_min(reg,temp0)						\
+	li	temp0, (S_E_min - 1 + S_E_bias) << S_F_bits;		\
+	and	temp0, reg	/* temp0 == 0 if denorm or zero */
+
+/* Set temp0 if reg is a NaN assuming S_is_E_max is true  */
+#define S_get_F(reg,temp0)						\
+	li	temp0, (1 << S_F_bits) - 1;				\
+	and	temp0, reg			/* temp0 != 0 if NaN */
+
+/* Set res if fraction of reg is != 0.  */
+#define S_is_Inf(reg,res)						\
+	li	res, (1 << S_F_bits) - 1;				\
+	and	res, reg			/* temp0 == 0 if Inf */
+
+
+/*
+ * Some constants that define the properties of double precission numbers.
+ */
+#define D_M_prec	53
+#define D_E_max		1023
+#define D_E_min		-1022
+#define D_E_bias	1023
+#define D_E_bits	8
+#define D_F_bits	52
+#define D_F_size	64
+
+/* Set temp0, if exponent of reg1/reg2 is D_E_max.  */
+#define D_is_E_max(reg1,reg2,temp0,temp1)				\
+	li	temp0, (D_E_max + 1 + D_E_bias) << (D_F_bits - 32);	\
+	and	temp1, temp0, reg1;					\
+	seq	temp0, temp1			/* temp0 != 0 if NaN */
+
+/* Clear temp0, if exponent of reg is D_E_min.  */
+#define D_is_E_min(reg1,reg2,res)					\
+	li	res, (D_E_min + 1 + D_E_bias) << (D_F_bits - 32);	\
+	and	res, reg1	/* temp0 == 0 if NaN or zero */
+
+/* Set res if reg is a NaN assuming S_is_E_max is true  */
+#define D_get_F(reg1,reg2,res)						\
+	li	res, (1 << (D_F_bits - 32)) - 1;			\
+	and	res, reg1			/* temp0 != 0 if NaN */
+
+/* Set temp0 if reg1/reg2 is a NaN  */
+#define D_is_NAN(reg1,reg2,temp0,temp1)					\
+	li	temp0, (1 << (D_F_bits - 32) - 1;			\
+	and	temp0, reg1;						\
+	or	temp0, reg2;						\
+	sne	temp0, zero, temp0		/* temp0 != 0 if NaN */
+
+/* Set res if fraction of reg1/reg2 is != 0.  */
+#define D_is_Inf(reg1,reg2,res)						\
+	li	res, (1 << (D_F_bits - 32)) - 1;			\
+	and	res, reg1;						\
+	or	res, reg2			/* temp0 == 0 if Inf */
+
+/* Complain about yet unhandled instruction.  */
+#define BITCH(insn)							\
+insn:	LOCK_KERNEL;							\
+	la	a1, 8f;							\
+	TEXT(#insn);							\
+	la	a1, nosim;						\
+	UNLOCK_KERNEL;							\
+	j	done
+
+	.data
+nosim: .asciz	KERN_DEBUG "Don't know how to simulate %s instruction\n"
+	.previous
+
+/*
+ * When we come here, we've saved some of the integer registers and
+ * reenabled interrupts.
+ */
+LEAF(simfp)
+	.set	noreorder
+	.cpload	$25
+	.set	reorder
+
+	subu	sp, 16
+	.cprestore 20
+	sw	ra, 16(sp)
+
+	/* For now we assume that we get the opcode to simulate passed in as
+	   an argument.  */
+	move	t0, a0
+
+	/*
+	 * First table lookup using insn[5:0]
+	 */
+	la	t1, lowtab
+	andi	t2, t0, 0x3f
+	sll	t2, t2, 2
+	addu	t1, t2
+	lw	t1, (t1)
+	jr	t1
+	END(simfp)
+
+/*
+ * We only decode the lower 3 of the 5 bit in the fmt field.  That way we
+ * can keep the jump table significantly shorter.
+ */
+#define FMT_switch(insn,opc,temp0,temp1)				\
+insn:	srl	temp0, opc, 19;						\
+	andi	temp0, 0x1c;						\
+	la	temp1, insn ## .tab;					\
+	addu	temp0, temp1;						\
+	lw	temp0, (temp0);						\
+	jr	temp0;							\
+									\
+	.data;								\
+insn ## .tab:								\
+	.word	insn ## .s, insn ## .d, unimp, unimp;			\
+	.word	insn ## .w, insn ## .l, unimp, unimp;			\
+	.previous
+
+	BITCH(add)
+	BITCH(sub)
+	BITCH(mul)
+	BITCH(div)
+	BITCH(sqrt)
+	BITCH(abs)
+	BITCH(mov)
+	BITCH(neg)
+	BITCH(round.l)
+	BITCH(trunc.l)
+	BITCH(ceil.l)
+	BITCH(floor.l)
+	BITCH(round.w)
+	BITCH(trunc.w)
+	BITCH(ceil.w)
+	BITCH(floor.w)
+	BITCH(cvt.s)
+	BITCH(cvt.d)
+
+/* ------------------------------------------------------------------------ */
+
+FMT_switch(cvt.w,t0,t1,t2)
+
+/* Convert a single fp to a fixed point integer.  */
+cvt.w.s:
+	srl	t1, t0, fs_shift	# Get source register
+	andi	t1, 31
+	jal	s_get_fpreg
+
+	S_is_E_max(t1,t2,t3)
+	beqz	t2, 3f
+	/* Might be a NaN or Inf.  */
+	S_get_F(t1,t2)
+	beqz	t2, 2f
+
+	/* It's a NaN.  IEEE says undefined.  */
+	/* Is it a QNaN?  Then the result is a QNaN as well.  */
+	S_is_QNaN(t1,t2)
+	bltz	t2, 1f
+
+	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
+	   For now we don't signal and supply a QNaN for result.  */
+
+1:	li	t2, W_QNaN
+	srl	t1, t0, fd_shift	# Put result register
+	andi	t1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	S_is_Inf(t1,t2)
+	bnez	t2, 2f
+
+	/* It's +/- Inf.  Set register to +/- max. integer.  */
+	/* XXX Send invalid operation exception instead, if enabled.  */
+	srl	t1, t1, 31		# Extract sign bit
+	li	t2, 0x7fffffff
+	addu	t2, t1
+
+	srl	t1, t0, fd_shift	# Put result register
+	andi	t1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+3:	
+
+	/* But then it might be a denorm or zero?  */
+	S_is_E_min(t1,t2)
+	bnez	t2, 2f
+
+	/* Ok, it's a denorm or zero.  */
+	S_get_F(t1,t2)
+	beqz	t2, 1f
+
+	/* It's a denorm.  */
+	/* XXX Should be signaling inexact exception, if enabled.  */
+	/* Fall through.  */
+1:
+	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
+	move	t2, zero
+	srl	t1, t0, fd_shift	# Put result register
+	andi	t1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	/* XXX Ok, it's a normal number.  We don't handle that case yet.
+	   If we have fp hardware this case is unreached.  Add this for
+	   full fp simulation.  */
+
+	/* Done, return.  */
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+/* Convert a double fp to a fixed point integer.  */
+cvt.w.d:
+	srl	t1, t0, fs_shift	# Get source register
+	andi	t1, 31
+	jal	d_get_fpreg
+
+	D_is_E_max(t1,t2,t3,t4)
+	beqz	t3, 3f
+
+	/* Might be a NaN or Inf.  */
+	D_get_F(t1,t2,t3)
+	or	t3, t2
+	beqz	t3, 2f
+
+	/* It's a NaN.  IEEE says undefined.  */
+	/* Is it a QNaN?  Then the result is a QNaN as well.  */
+	D_is_QNaN(t1,t2,t3)
+	bltz	t3, 1f
+
+	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
+	   For now we don't signal and supply a QNaN for result.  */
+
+1:	li	t2, W_QNaN
+	srl	t1, t0, fd_shift	# Put result register
+	andi	t1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	D_is_Inf(t1,t2,t3)
+	bnez	t3, 2f
+
+	/* It's +/- Inf.  Set register to +/- max. integer.  */
+	/* XXX Send invalid operation exception instead, if enabled.  */
+	srl	t1, t1, 31		# Extract sign bit
+	li	t2, 0x7fffffff
+	addu	t2, t1
+
+	srl	t1, t0, fd_shift	# Put result register
+	andi	t1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+3:	
+
+	/* But then it might be a denorm or zero?  */
+	D_is_E_min(t1,t2,t3)
+	bnez	t3, 2f
+
+	/* Ok, it's a denorm or zero.  */
+	D_get_F(t1,t2,t3)
+	or	t3, t2
+	beqz	t3, 1f
+
+	/* It's a denorm.  */
+	/* XXX Should be signaling inexact exception, if enabled.  */
+	/* Fall through.  */
+1:
+	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
+	move	t2, zero
+	srl	t1, t0, fd_shift	# Put result register
+	andi	t1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	/* XXX Ok, it's a normal number.  We don't handle that case yet.
+	   If we have fp hardware this case is only reached if the value
+	   of the source register exceeds the range which is representable
+	   in a single precission register.  For now we kludge by returning
+	   +/- maxint and don't signal overflow. */
+
+	srl	t1, t1, 31		# Extract sign bit
+	li	t2, 0x7fffffff
+	addu	t2, t1
+
+	srl	t1, t0, fd_shift	# Put result register
+	andi	t1, 31
+	jal	s_put_fpreg
+
+	/* Done, return.  */
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+cvt.w.w = unimp				# undefined result
+cvt.w.l = unimp				# undefined result
+
+/* MIPS III extension, no need to handle for 32bit OS.  */
+cvt.l = unimp
+
+/* ------------------------------------------------------------------------ */
+
+	BITCH(c.f)
+	BITCH(c.un)
+	BITCH(c.eq)
+	BITCH(c.ueq)
+	BITCH(c.olt)
+	BITCH(c.ult)
+	BITCH(c.ole)
+	BITCH(c.ule)
+	BITCH(c.sf)
+	BITCH(c.ngle)
+	BITCH(c.seq)
+	BITCH(c.ngl)
+	BITCH(c.lt)
+	BITCH(c.nge)
+	BITCH(c.le)
+	BITCH(c.ngt)
+
+/* Get the single precission register which's number is in t1.  */
+s_get_fpreg:
+	.set	noat
+	sll	AT, t1, 2
+	sll	t1, 3
+	addu	t1, AT
+	la	AT, 1f
+	addu	AT, t1
+	jr	AT
+	.set	at
+
+1:	mfc1	t1, $0
+	jr	ra
+	mfc1	t1, $1
+	jr	ra
+	mfc1	t1, $2
+	jr	ra
+	mfc1	t1, $3
+	jr	ra
+	mfc1	t1, $4
+	jr	ra
+	mfc1	t1, $5
+	jr	ra
+	mfc1	t1, $6
+	jr	ra
+	mfc1	t1, $7
+	jr	ra
+	mfc1	t1, $8
+	jr	ra
+	mfc1	t1, $9
+	jr	ra
+	mfc1	t1, $10
+	jr	ra
+	mfc1	t1, $11
+	jr	ra
+	mfc1	t1, $12
+	jr	ra
+	mfc1	t1, $13
+	jr	ra
+	mfc1	t1, $14
+	jr	ra
+	mfc1	t1, $15
+	jr	ra
+	mfc1	t1, $16
+	jr	ra
+	mfc1	t1, $17
+	jr	ra
+	mfc1	t1, $18
+	jr	ra
+	mfc1	t1, $19
+	jr	ra
+	mfc1	t1, $20
+	jr	ra
+	mfc1	t1, $21
+	jr	ra
+	mfc1	t1, $22
+	jr	ra
+	mfc1	t1, $23
+	jr	ra
+	mfc1	t1, $24
+	jr	ra
+	mfc1	t1, $25
+	jr	ra
+	mfc1	t1, $26
+	jr	ra
+	mfc1	t1, $27
+	jr	ra
+	mfc1	t1, $28
+	jr	ra
+	mfc1	t1, $29
+	jr	ra
+	mfc1	t1, $30
+	jr	ra
+	mfc1	t1, $31
+	jr	ra
+
+/*
+ * Put the value in t2 into the single precission register which's number
+ * is in t1.
+ */
+s_put_fpreg:
+	.set	noat
+	sll	AT, t1, 2
+	sll	t1, 3
+	addu	t1, AT
+	la	AT, 1f
+	addu	AT, t1
+	jr	AT
+	.set	at
+	
+1:	mtc1	t2, $0
+	jr	ra
+	mtc1	t2, $1
+	jr	ra
+	mtc1	t2, $2
+	jr	ra
+	mtc1	t2, $3
+	jr	ra
+	mtc1	t2, $4
+	jr	ra
+	mtc1	t2, $5
+	jr	ra
+	mtc1	t2, $6
+	jr	ra
+	mtc1	t2, $7
+	jr	ra
+	mtc1	t2, $8
+	jr	ra
+	mtc1	t2, $9
+	jr	ra
+	mtc1	t2, $10
+	jr	ra
+	mtc1	t2, $11
+	jr	ra
+	mtc1	t2, $12
+	jr	ra
+	mtc1	t2, $13
+	jr	ra
+	mtc1	t2, $14
+	jr	ra
+	mtc1	t2, $15
+	jr	ra
+	mtc1	t2, $16
+	jr	ra
+	mtc1	t2, $17
+	jr	ra
+	mtc1	t2, $18
+	jr	ra
+	mtc1	t2, $19
+	jr	ra
+	mtc1	t2, $20
+	jr	ra
+	mtc1	t2, $21
+	jr	ra
+	mtc1	t2, $22
+	jr	ra
+	mtc1	t2, $23
+	jr	ra
+	mtc1	t2, $24
+	jr	ra
+	mtc1	t2, $25
+	jr	ra
+	mtc1	t2, $26
+	jr	ra
+	mtc1	t2, $27
+	jr	ra
+	mtc1	t2, $28
+	jr	ra
+	mtc1	t2, $29
+	jr	ra
+	mtc1	t2, $30
+	jr	ra
+	mtc1	t2, $31
+	jr	ra
+
+/* Get the double precission register which's number is in t1 into t1/t2.  */
+d_get_fpreg:
+	.set	noat
+	sll	t1, 3
+	la	AT, 1f
+	addu	AT, t1
+	jr	AT
+	.set	at
+
+1:	mfc1	t1, $0
+	mfc1	t2, $1
+	jr	ra
+	mfc1	t1, $2
+	mfc1	t2, $3
+	jr	ra
+	mfc1	t1, $4
+	mfc1	t2, $5
+	jr	ra
+	mfc1	t1, $6
+	mfc1	t2, $7
+	jr	ra
+	mfc1	t1, $8
+	mfc1	t2, $9
+	jr	ra
+	mfc1	t1, $10
+	mfc1	t2, $11
+	jr	ra
+	mfc1	t1, $12
+	mfc1	t2, $13
+	jr	ra
+	mfc1	t1, $14
+	mfc1	t2, $15
+	jr	ra
+	mfc1	t1, $16
+	mfc1	t2, $17
+	jr	ra
+	mfc1	t1, $18
+	mfc1	t2, $19
+	jr	ra
+	mfc1	t1, $20
+	mfc1	t2, $21
+	jr	ra
+	mfc1	t1, $22
+	mfc1	t2, $23
+	jr	ra
+	mfc1	t1, $24
+	mfc1	t2, $25
+	jr	ra
+	mfc1	t1, $26
+	mfc1	t2, $27
+	jr	ra
+	mfc1	t1, $28
+	mfc1	t2, $29
+	jr	ra
+	mfc1	t1, $30
+	mfc1	t2, $31
+	jr	ra
+
+/*
+ * Send an invalid operation exception.
+ */
+invalid:
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+/*
+ * Done, just skip over the current instruction
+ */
+done:
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+unimp:
+	/* We've run into an yet unknown instruction.  This happens either
+	   on new, yet unsupported CPU types or when the faulting instruction
+	   is being executed for cache but has been overwritten in memory.  */
+	LOCK_KERNEL
+	move	a0, t0
+	PRINT(KERN_DEBUG "FP support: unknown fp op %08lx, ")
+	PRINT("please mail to ralf@gnu.org.\n")
+
+	li	a0, SIGILL			# Die, sucker ...
+	move	a1, $28
+	jal	force_sig
+	UNLOCK_KERNEL
+
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+/*
+ * Jump table for the lowest 6 bits of a cp1 instruction.
+ */
+	.data
+lowtab:	.word	add,   sub,   mul,   div,   sqrt,  abs,   mov,   neg
+	.word	round.l,trunc.l,ceil.l,floor.l,round.w,trunc.w,ceil.w,floor.w
+	.word	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
+	.word	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
+	.word	cvt.s, cvt.d, unimp, unimp, cvt.w, cvt.l, unimp, unimp
+	.word	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
+	.word	c.f,   c.un,  c.eq,  c.ueq, c.olt, c.ult, c.ole, c.ule
+	.word	c.sf,  c.ngle,c.seq, c.ngl, c.lt,  c.nge, c.le, c.ngt
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/syscall.c linux/arch/mips/kernel/syscall.c
--- v2.1.125/linux/arch/mips/kernel/syscall.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/syscall.c	Tue Oct 20 13:52:54 1998
@@ -1,17 +1,14 @@
-/*
- * MIPS specific syscall handling functions and syscalls
+/* $Id: syscall.c,v 1.10 1998/08/20 14:38:40 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996 by Ralf Baechle
+ * Copyright (C) 1995 - 1998 by Ralf Baechle
  *
  * TODO:  Implement the compatibility syscalls.
  *        Don't waste that much memory for empty entries in the syscall
  *        table.
- *
- * $Id: syscall.c,v 1.12 1998/07/26 03:02:09 davem Exp $
  */
 #undef CONF_PRINT_SYSCALLS
 #undef CONF_DEBUG_IRIX
@@ -82,14 +79,15 @@
 
 asmlinkage int sys_idle(void)
 {
+	unsigned long start_idle = 0;
         int ret = -EPERM;
 
 	lock_kernel();
 	if (current->pid != 0)
 		goto out;
 	/* endless idle loop with no priority at all */
-	current->priority = -100;
-	current->counter = -100;
+	current->priority = 0;
+	current->counter = 0;
 	for (;;) {
 		/*
 		 * R4[36]00 have wait, R4[04]00 don't.
@@ -99,13 +97,20 @@
 		 *        same for logic clocked with the processor generated
 		 *        clocks.
 		 */
+		if (!start_idle) {
+			check_pgt_cache();
+			start_idle = jiffies;
+		}
 		if (wait_available && !current->need_resched)
 			__asm__(".set\tmips3\n\t"
 				"wait\n\t"
 				".set\tmips0");
 		run_task_queue(&tq_scheduler);
+		if (current->need_resched)
+			start_idle = 0;
 		schedule();
 	}
+	ret = 0;
 out:
 	unlock_kernel();
 	return ret;
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h
--- v2.1.125/linux/arch/mips/kernel/syscalls.h	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/syscalls.h	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,10 @@
-/*
- * List of Linux/MIPS syscalls.
+/* $Id: syscalls.h,v 1.16 1998/09/16 22:50:43 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996 by Ralf Baechle
- *
- * $Id: syscalls.h,v 1.14 1998/05/07 00:39:37 ralf Exp $
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
 
 /*
@@ -16,7 +13,7 @@
  * accepts.  Syscalls that receive a pointer to the saved registers are
  * marked as having zero arguments.
  *
- * The binary compatibility calls are still missing in this list.
+ * The binary compatibility calls are in a separate list.
  */
 SYS(sys_syscall, 0)				/* 4000 */
 SYS(sys_exit, 1)
@@ -40,7 +37,7 @@
 SYS(sys_lseek, 3)
 SYS(sys_getpid, 0)				/* 4020 */
 SYS(sys_mount, 5)
-SYS(sys_umount, 1)
+SYS(sys_oldumount, 1)
 SYS(sys_setuid, 1)
 SYS(sys_getuid, 0)
 SYS(sys_stime, 1)				/* 4025 */
@@ -70,7 +67,7 @@
 SYS(sys_geteuid, 0)
 SYS(sys_getegid, 0)				/* 4050 */
 SYS(sys_acct, 0)
-SYS(sys_ni_syscall, 0)
+SYS(sys_umount, 2)
 SYS(sys_ni_syscall, 0)
 SYS(sys_ioctl, 3)
 SYS(sys_fcntl, 3)				/* 4055 */
@@ -168,7 +165,7 @@
 SYS(sys_cacheflush, 3)
 SYS(sys_cachectl, 3)
 SYS(sys_sysmips, 4)
-SYS(sys_setup, 1)				/* 4150 */
+SYS(sys_ni_syscall, 0)				/* 4150 */
 SYS(sys_getsid, 1)
 SYS(sys_fdatasync, 0)
 SYS(sys_sysctl, 1)
@@ -222,3 +219,9 @@
 SYS(sys_pwrite, 4)
 SYS(sys_chown, 3)
 SYS(sys_getcwd, 2)
+SYS(sys_capget, 2)
+SYS(sys_capset, 2)				/* 4205 */
+SYS(sys_sigaltstack, 2)
+SYS(sys_sendfile, 3)
+SYS(sys_ni_syscall, 0)
+SYS(sys_ni_syscall, 0)
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- v2.1.125/linux/arch/mips/kernel/sysirix.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/sysirix.c	Tue Oct 20 13:52:54 1998
@@ -1,10 +1,10 @@
-/*
+/* $Id: sysirix.c,v 1.12 1998/08/17 10:16:27 ralf Exp $
+ *
  * sysirix.c: IRIX system call emulation.
  *
  * Copyright (C) 1996 David S. Miller
  * Copyright (C) 1997 Miguel de Icaza
- *
- * $Id: sysirix.c,v 1.10 1998/05/08 21:01:33 davem Exp $
+ * Copyright (C) 1997, 1998 Ralf Baechle
  */
 
 #include <linux/kernel.h>
@@ -1638,96 +1638,6 @@
 out:
 	unlock_kernel();
 	return error;
-}
-
-#define NOFOLLOW_LINKS  0
-#define FOLLOW_LINKS    1
-
-static inline int chown_common(uid_t user, gid_t group, struct dentry *dentry)
-{
-	struct inode * inode;
-	int error;
-	struct iattr newattrs;
-
-	error = PTR_ERR(dentry);
-	if (IS_ERR(dentry))
-		goto out;
-	inode = dentry->d_inode;
-
-	error = -EROFS;
-	if (IS_RDONLY(inode))
-		goto dput_and_out;
-
-	error = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		goto dput_and_out;
-
-	if (user == (uid_t) -1)
-		user = inode->i_uid;
-	if (group == (gid_t) -1)
-		group = inode->i_gid;
-	newattrs.ia_mode = inode->i_mode;
-	newattrs.ia_uid = user;
-	newattrs.ia_gid = group;
-	newattrs.ia_valid =  ATTR_UID | ATTR_GID | ATTR_CTIME;
-	/*
-	 * If the owner has been changed, remove the setuid bit
-	 */
-	if (inode->i_mode & S_ISUID) {
-		newattrs.ia_mode &= ~S_ISUID;
-		newattrs.ia_valid |= ATTR_MODE;
-	}
-	/*
-	 * If the group has been changed, remove the setgid bit
-	 *
-	 * Don't remove the setgid bit if no group execute bit.
-	 * This is a file marked for mandatory locking.
-	 */
-	if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) {
-		newattrs.ia_mode &= ~S_ISGID;
-		newattrs.ia_valid |= ATTR_MODE;
-	}
-	if (inode->i_sb->dq_op) {
-		inode->i_sb->dq_op->initialize(inode, -1);
-		error = -EDQUOT;
-		if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0))
-			goto dput_and_out;
-		error = notify_change(dentry, &newattrs);
-		if (error)
-			inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
-	} else
-		error = notify_change(dentry, &newattrs);
-
-dput_and_out:
-	dput(dentry);
-out:
-	return error;
-}
-
-asmlinkage int irix_chown(const char *filename, int uid, int gid)
-{
-	int retval;
-	struct dentry *dentry;
-
-	lock_kernel();
-	/* Do follow any and all links... */
-	dentry = namei(filename);
-	retval = chown_common(uid, gid, dentry);
-	unlock_kernel();
-	return retval;
-}
-
-asmlinkage int irix_lchown(const char *filename, int uid, int gid)
-{
-	int retval;
-	struct dentry *dentry;
-
-	lock_kernel();
-	/* Do _not_ follow any links... */
-	dentry = lnamei(filename);
-	retval = chown_common(uid, gid, dentry);
-	unlock_kernel();
-	return retval;
 }
 
 asmlinkage int irix_priocntl(struct pt_regs *regs)
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/sysmips.c linux/arch/mips/kernel/sysmips.c
--- v2.1.125/linux/arch/mips/kernel/sysmips.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/sysmips.c	Tue Oct 20 13:52:54 1998
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
  *
- * $Id: sysmips.c,v 1.8 1998/05/08 21:01:35 davem Exp $
+ * $Id: sysmips.c,v 1.4 1998/05/07 15:20:05 ralf Exp $
  */
 #include <linux/errno.h>
 #include <linux/linkage.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c
--- v2.1.125/linux/arch/mips/kernel/time.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/time.c	Tue Oct 20 13:52:54 1998
@@ -6,7 +6,7 @@
  * This file contains the time handling details for PC-style clocks as
  * found in some MIPS systems.
  *
- * $Id: time.c,v 1.9 1998/06/10 07:21:13 davem Exp $
+ * $Id: time.c,v 1.6 1998/08/17 13:57:44 ralf Exp $
  */
 #include <linux/errno.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c
--- v2.1.125/linux/arch/mips/kernel/traps.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/kernel/traps.c	Tue Oct 20 13:52:54 1998
@@ -1,14 +1,11 @@
-/*
- * arch/mips/kernel/traps.c
+/* $Id: traps.c,v 1.20 1998/10/14 20:26:26 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright 1994, 1995, 1996, 1997 by Ralf Baechle
+ * Copyright 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
  * Modified for R3000 by Paul M. Antoine, 1995, 1996
- *
- * $Id: traps.c,v 1.10 1998/05/04 09:17:57 ralf Exp $
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -20,7 +17,6 @@
 #include <asm/branch.h>
 #include <asm/cachectl.h>
 #include <asm/jazz.h>
-#include <asm/vector.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/bootinfo.h>
@@ -28,8 +24,6 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#undef CONF_DEBUG_EXCEPTIONS
-
 static inline void console_verbose(void)
 {
 	extern int console_loglevel;
@@ -61,9 +55,7 @@
 extern asmlinkage void handle_cpu(void);
 extern asmlinkage void handle_ov(void);
 extern asmlinkage void handle_tr(void);
-extern asmlinkage void handle_vcei(void);
 extern asmlinkage void handle_fpe(void);
-extern asmlinkage void handle_vced(void);
 extern asmlinkage void handle_watch(void);
 extern asmlinkage void handle_reserved(void);
 
@@ -71,6 +63,7 @@
 
 char watch_available = 0;
 char dedicated_iv_available = 0;
+char vce_available = 0;
 
 void (*ibe_board_handler)(struct pt_regs *regs);
 void (*dbe_board_handler)(struct pt_regs *regs);
@@ -159,10 +152,9 @@
 	}
 	else
 		printk("(Bad address in epc)\n");
-	do_exit(SIGSEGV);
 }
 
-void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+void die(const char * str, struct pt_regs * regs, unsigned long err)
 {
 	if (user_mode(regs))	/* Just return if in user mode.  */
 		return;
@@ -173,6 +165,12 @@
 	do_exit(SIGSEGV);
 }
 
+void die_if_kernel(const char * str, struct pt_regs * regs, unsigned long err)
+{
+	if (!user_mode(regs))
+		die(str, regs, err);
+}
+
 static void default_be_board_handler(struct pt_regs *regs)
 {
 	/*
@@ -183,31 +181,21 @@
 
 void do_ibe(struct pt_regs *regs)
 {
-	lock_kernel();
 show_regs(regs); while(1);
 	ibe_board_handler(regs);
-	unlock_kernel();
 }
 
 void do_dbe(struct pt_regs *regs)
 {
-	lock_kernel();
 show_regs(regs); while(1);
 	dbe_board_handler(regs);
-	unlock_kernel();
 }
 
 void do_ov(struct pt_regs *regs)
 {
-	lock_kernel();
-#ifdef CONF_DEBUG_EXCEPTIONS
-	show_regs(regs);
-#endif
 	if (compute_return_epc(regs))
-		goto out;
+		return;
 	force_sig(SIGFPE, current);
-out:
-	unlock_kernel();
 }
 
 #ifdef CONFIG_MIPS_FPE_MODULE
@@ -235,6 +223,9 @@
  */
 void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
+	unsigned long pc;
+	unsigned int insn;
+
 #ifdef CONFIG_MIPS_FPE_MODULE
 	if (fpe_handler != NULL) {
 		fpe_handler(regs, fcr31);
@@ -242,9 +233,6 @@
 	}
 #endif
 	lock_kernel();
-#ifdef CONF_DEBUG_EXCEPTIONS
-	show_regs(regs);
-#endif
 	if (fcr31 & 0x20000) {
 		/* Retry instruction with flush to zero ...  */
 		if (!(fcr31 & (1<<24))) {
@@ -258,13 +246,22 @@
 				: "r" (fcr31));
 			goto out;
 		}
-		printk("Unimplemented exception at 0x%08lx in %s.\n",
-		       regs->cp0_epc, current->comm);
+		pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
+		if (get_user(insn, (unsigned int *)pc)) {
+			/* XXX Can this happen?  */
+			force_sig(SIGSEGV, current);
+		}
+
+		printk(KERN_DEBUG "Unimplemented exception for insn %08x at 0x%08lx in %s.\n",
+		       insn, regs->cp0_epc, current->comm);
+		simfp(insn);
 	}
 
 	if (compute_return_epc(regs))
 		goto out;
-	force_sig(SIGFPE, current);
+	//force_sig(SIGFPE, current);
+	printk(KERN_DEBUG "Should send SIGFPE to %s\n", current->comm);
+
 out:
 	unlock_kernel();
 }
@@ -286,72 +283,53 @@
 	return 0;
 }
 
-static inline void
-do_bp_and_tr(struct pt_regs *regs, char *exc, unsigned int trapcode)
-{
-	/*
-	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
-	 * insns, even for break codes that indicate arithmetic failures.
-	 * Wiered ...)
-	 */
-	force_sig(SIGTRAP, current);
-#ifdef CONF_DEBUG_EXCEPTIONS
-	show_regs(regs);
-#endif
-}
 
 void do_bp(struct pt_regs *regs)
 {
 	unsigned int opcode, bcode;
 
-	lock_kernel();
 	/*
 	 * There is the ancient bug in the MIPS assemblers that the break
 	 * code starts left to bit 16 instead to bit 6 in the opcode.
 	 * Gas is bug-compatible ...
 	 */
-#ifdef CONF_DEBUG_EXCEPTIONS
-	printk("BREAKPOINT at %08lx\n", regs->cp0_epc);
-#endif
 	if (get_insn_opcode(regs, &opcode))
-		goto out;
+		return;
 	bcode = ((opcode >> 16) & ((1 << 20) - 1));
 
-	do_bp_and_tr(regs, "bp", bcode);
-
-	if (compute_return_epc(regs))
-		goto out;
-out:
-	unlock_kernel();
+	/*
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
+	 * insns, even for break codes that indicate arithmetic failures.
+	 * Wiered ...)
+	 */
+	force_sig(SIGTRAP, current);
 }
 
 void do_tr(struct pt_regs *regs)
 {
 	unsigned int opcode, bcode;
 
-	lock_kernel();
 	if (get_insn_opcode(regs, &opcode))
-		goto out;
+		return;
 	bcode = ((opcode >> 6) & ((1 << 20) - 1));
 
-	do_bp_and_tr(regs, "tr", bcode);
-out:
-	unlock_kernel();
+	/*
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
+	 * insns, even for break codes that indicate arithmetic failures.
+	 * Wiered ...)
+	 */
+	force_sig(SIGTRAP, current);
 }
 
 void do_ri(struct pt_regs *regs)
 {
 	lock_kernel();
-#ifdef CONF_DEBUG_EXCEPTIONS
-	show_regs(regs);
-#endif
 	printk("[%s:%ld] Illegal instruction at %08lx ra=%08lx\n",
 	       current->comm, current->pid, regs->cp0_epc, regs->regs[31]);
+	unlock_kernel();
 	if (compute_return_epc(regs))
-		goto out;
+		return;
 	force_sig(SIGILL, current);
-out:
-	unlock_kernel();
 }
 
 void do_cpu(struct pt_regs *regs)
@@ -364,7 +342,7 @@
 
 	regs->cp0_status |= ST0_CU1;
 	if (last_task_used_math == current)
-		goto out;
+		return;
 
 	if (current->used_math) {		/* Using the FPU again.  */
 		r4xx0_lazy_fpu_switch(last_task_used_math);
@@ -377,56 +355,27 @@
 	return;
 
 bad_cid:
-	lock_kernel();
 	force_sig(SIGILL, current);
-	unlock_kernel();
-out:
-}
-
-void do_vcei(struct pt_regs *regs)
-{
-	lock_kernel();
-	/*
-	 * Only possible on R4[04]00[SM]C. No handler because I don't have
-	 * such a cpu.  Theory says this exception doesn't happen.
-	 */
-	panic("Caught VCEI exception - should not happen");
-	unlock_kernel();
-}
-
-void do_vced(struct pt_regs *regs)
-{
-	lock_kernel();
-	/*
-	 * Only possible on R4[04]00[SM]C. No handler because I don't have
-	 * such a cpu.  Theory says this exception doesn't happen.
-	 */
-	panic("Caught VCE exception - should not happen");
-	unlock_kernel();
 }
 
 void do_watch(struct pt_regs *regs)
 {
-	lock_kernel();
 	/*
 	 * We use the watch exception where available to detect stack
 	 * overflows.
 	 */
 	show_regs(regs);
 	panic("Caught WATCH exception - probably caused by stack overflow.");
-	unlock_kernel();
 }
 
 void do_reserved(struct pt_regs *regs)
 {
-	lock_kernel();
 	/*
 	 * Game over - no way to handle this if it ever occurs.
 	 * Most probably caused by a new unknown cpu type or
 	 * after another deadly hard/software error.
 	 */
 	panic("Caught reserved exception - should not happen.");
-	unlock_kernel();
 }
 
 static inline void watch_init(unsigned long cputype)
@@ -545,11 +494,8 @@
 	case CPU_R4400MC:
 	case CPU_R4000SC:
 	case CPU_R4400SC:
-		/* XXX The following won't work because we _cannot_
-		 * XXX perform any load/store before the VCE handler.
-		 */
-		set_except_vector(14, handle_vcei);
-		set_except_vector(31, handle_vced);
+		vce_available = 1;
+		/* Fall through ...  */
 	case CPU_R4000PC:
 	case CPU_R4400PC:
 	case CPU_R4200:
@@ -565,13 +511,16 @@
 		else
 			memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
 
-		/*
-		 * The idea is that this special r4000 general exception
-		 * vector will check for VCE exceptions before calling
-		 * out of the exception array.  XXX TODO
-		 */
+		/* Cache error vector  */
 		memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
-		memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80);
+
+		if (vce_available) {
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
+			       0x180);
+		} else {
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
+			       0x100);
+		}
 
 		save_fp_context = r4k_save_fp_context;
 		restore_fp_context = r4k_restore_fp_context;
diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/unaligned.c linux/arch/mips/kernel/unaligned.c
--- v2.1.125/linux/arch/mips/kernel/unaligned.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/kernel/unaligned.c	Tue Oct 20 13:52:54 1998
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1996, 1998 by Ralf Baechle
  *
- * $Id: unaligned.c,v 1.4 1998/06/10 07:21:15 davem Exp $
+ * $Id: unaligned.c,v 1.5 1998/08/17 13:57:44 ralf Exp $
  *
  * This file contains exception handler for address error exception with the
  * special capability to execute faulting instructions in software.  The
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/Makefile linux/arch/mips/lib/Makefile
--- v2.1.125/linux/arch/mips/lib/Makefile	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/lib/Makefile	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.8 1998/05/08 01:44:18 ralf Exp $
+# $Id: Makefile,v 1.12 1998/05/28 03:17:57 ralf Exp $
 #
 # Makefile for MIPS-specific library files..
 #
@@ -9,12 +9,8 @@
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
 L_TARGET = lib.a
-L_OBJS	= csum_partial.o csum_partial_copy.o dump_tlb.o ide-std.o ide-no.o \
-	  memset.o memcpy.o strlen_user.o strncpy_user.o tags.o watch.o
-
-#
-# Debug console, works without other support from the kernel
-#
-L_OBJS += tinycon.o
+L_OBJS	= csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \
+	  floppy-no.o ide-std.o ide-no.o rtc-std.o rtc-no.o memset.o memcpy.o \
+	  strlen_user.o strncpy_user.o tags.o watch.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/csum_partial.S linux/arch/mips/lib/csum_partial.S
--- v2.1.125/linux/arch/mips/lib/csum_partial.S	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/lib/csum_partial.S	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: csum_partial.S,v 1.2 1998/05/08 01:44:20 ralf Exp $
+/* $Id: csum_partial.S,v 1.3 1998/05/07 14:17:45 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/csum_partial_copy.S linux/arch/mips/lib/csum_partial_copy.S
--- v2.1.125/linux/arch/mips/lib/csum_partial_copy.S	Thu Aug  6 14:06:28 1998
+++ linux/arch/mips/lib/csum_partial_copy.S	Wed Dec 31 16:00:00 1969
@@ -1,519 +0,0 @@
-/* $Id: csum_partial_copy.S,v 1.2 1998/05/07 00:39:47 ralf Exp $
- *
- * Unified implementation of csum_copy_partial, csum_copy_partial_from_user
- * and csum_copy_partial_nocheck.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998 Ralf Baechle
- */
-#include <asm/asm.h>
-#include <asm/offset.h>
-#include <asm/regdef.h>
-
-/*
- * The fixup routine for csum_partial_copy_from_user depends on copying
- * strictly in increasing order.  Gas expands ulw/usw macros in the wrong order
- * for little endian machines, so we cannot depend on them.
- */
-#ifdef __MIPSEB__
-#define ulwL	lwl
-#define ulwU	lwr
-#endif
-#ifdef __MIPSEL__
-#define ulwL	lwr
-#define ulwU	lwl
-#endif
-
-#define EX(insn,reg,addr,handler)			\
-9:	insn	reg, addr;				\
-	.section __ex_table,"a"; 			\
-	PTR	9b, handler; 				\
-	.previous
-
-#define UEX(insn,reg,addr,handler)			\
-9:	insn ## L reg, addr;				\
-10:	insn ## U reg, 3 + addr;			\
-	.section __ex_table,"a"; 			\
-	PTR	9b, handler; 				\
-	PTR	10b, handler; 				\
-	.previous
-
-#define ADDC(sum,reg)					\
-	addu	sum, reg;				\
-	sltu	v1, sum, reg;				\
-	addu	sum, v1
-
-/* ascending order, destination aligned  */
-#define CSUM_BIGCHUNK(src, dst, offset, sum, t0, t1, t2, t3) \
-	EX(lw, t0, (offset + 0x00)(src), l_fixup);	\
-	EX(lw, t1, (offset + 0x04)(src), l_fixup);	\
-	EX(lw, t2, (offset + 0x08)(src), l_fixup);	\
-	EX(lw, t3, (offset + 0x0c)(src), l_fixup);	\
-	ADDC(sum, t0);					\
-	ADDC(sum, t1);					\
-	ADDC(sum, t2);					\
-	ADDC(sum, t3);					\
-	sw	t0, (offset + 0x00)(dst);		\
-	sw	t1, (offset + 0x04)(dst);		\
-	sw	t2, (offset + 0x08)(dst);		\
-	sw	t3, (offset + 0x0c)(dst);		\
-	EX(lw, t0, (offset + 0x10)(src), l_fixup);	\
-	EX(lw, t1, (offset + 0x14)(src), l_fixup);	\
-	EX(lw, t2, (offset + 0x18)(src), l_fixup);	\
-	EX(lw, t3, (offset + 0x1c)(src), l_fixup);	\
-	ADDC(sum, t0);					\
-	ADDC(sum, t1);					\
-	ADDC(sum, t2);					\
-	ADDC(sum, t3);					\
-	sw	t0, (offset + 0x10)(dst);		\
-	sw	t1, (offset + 0x14)(dst);		\
-	sw	t2, (offset + 0x18)(dst);		\
-	sw	t3, (offset + 0x1c)(dst)
-
-/* ascending order, destination unaligned  */
-#define UCSUM_BIGCHUNK(src, dst, offset, sum, t0, t1, t2, t3) \
-	EX(lw, t0, (offset + 0x00)(src), l_fixup);	\
-	EX(lw, t1, (offset + 0x04)(src), l_fixup);	\
-	EX(lw, t2, (offset + 0x08)(src), l_fixup);	\
-	EX(lw, t3, (offset + 0x0c)(src), l_fixup);	\
-	ADDC(sum, t0);					\
-	ADDC(sum, t1);					\
-	ADDC(sum, t2);					\
-	ADDC(sum, t3);					\
-	usw	t0, (offset + 0x00)(dst);		\
-	usw	t1, (offset + 0x04)(dst);		\
-	usw	t2, (offset + 0x08)(dst);		\
-	usw	t3, (offset + 0x0c)(dst);		\
-	EX(lw, t0, (offset + 0x00)(src), l_fixup);	\
-	EX(lw, t1, (offset + 0x04)(src), l_fixup);	\
-	EX(lw, t2, (offset + 0x08)(src), l_fixup);	\
-	EX(lw, t3, (offset + 0x0c)(src), l_fixup);	\
-	ADDC(sum, t0);					\
-	ADDC(sum, t1);					\
-	ADDC(sum, t2);					\
-	ADDC(sum, t3);					\
-	usw	t0, (offset + 0x10)(dst);		\
-	usw	t1, (offset + 0x14)(dst);		\
-	usw	t2, (offset + 0x18)(dst);		\
-	usw	t3, (offset + 0x1c)(dst)
-
-#
-# a0: source address
-# a1: destination address
-# a2: length of the area to checksum
-# a3: partial checksum
-#
-
-#define src a0
-#define dest a1
-#define sum v0
-
-	.text
-	.set	noreorder
-
-/* unknown src/dst alignment and < 8 bytes to go  */
-small_csumcpy:
-	move	a2, t2
-
-	andi	t0, a2, 4
-	beqz	t0, 1f
-	 andi	t0, a2, 2
-
-	/* Still a full word to go  */
-	UEX(ulw, t1, 0(src), l_fixup)
-	addiu	src, 4
-	usw	t1, 0(dest)
-	addiu	dest, 4
-	ADDC(sum, t1)
-
-1:	move	t1, zero
-	beqz	t0, 1f
-	 andi	t0, a2, 1
-
-	/* Still a halfword to go  */
-	ulhu	t1, (src)
-	addiu	src, 2
-	ush	t1, (dest)
-	addiu	dest, 2
-
-1:	beqz	t0, 1f
-	 sll	t1, t1, 16
-
-	lbu	t2, (src)
-	 nop
-	sb	t2, (dest)
-
-#ifdef __MIPSEB__
-	sll	t2, t2, 8
-#endif
-	or	t1, t2
-
-1:	ADDC(sum, t1)
-
-	/* fold checksum */
-	sll	v1, sum, 16
-	addu	sum, v1
-	sltu	v1, sum, v1
-	srl	sum, sum, 16
-	addu	sum, v1
-
-	/* odd buffer alignment? */
-	beqz	t7, 1f
-	 nop
-	sll	v1, sum, 8
-	srl	sum, sum, 8
-	or	sum, v1
-	andi	sum, 0xffff
-1:
-	.set	reorder
-	/* Add the passed partial csum.  */
-	ADDC(sum, a3)
-	jr	ra
-	.set	noreorder
-
-/* ------------------------------------------------------------------------- */
-
-	.align	5
-LEAF(csum_partial_copy_from_user)
-	addu	t5, src, a2			# end address for fixup
-EXPORT(csum_partial_copy_nocheck)
-EXPORT(csum_partial_copy)
-	move	sum, zero			# clear computed sum
-	move	t7, zero			# clear odd flag
-	xor	t0, dest, src
-	andi	t0, t0, 0x3
-	beqz	t0, can_align
-	 sltiu	t8, a2, 0x8
-
-	b	memcpy_u_src			# bad alignment
-	 move	t2, a2
-
-can_align:
-	bnez	t8, small_csumcpy		# < 8 bytes to copy
-	 move	t2, a2
-
-	beqz	a2, out
-	 andi	t7, src, 0x1			# odd buffer?
-
-hword_align:
-	beqz	t7, word_align
-	 andi	t8, src, 0x2
-
-	EX(lbu, t0, (src), l_fixup)
-	subu	a2, a2, 0x1
-	EX(sb, t0, (dest), l_fixup)
-#ifdef __MIPSEL__
-	sll	t0, t0, 8
-#endif
-	ADDC(sum, t0)
-	addu	src, src, 0x1
-	addu	dest, dest, 0x1
-	andi	t8, src, 0x2
-
-word_align:
-	beqz	t8, dword_align
-	 sltiu	t8, a2, 56
-
-	EX(lhu, t0, (src), l_fixup)
-	subu	a2, a2, 0x2
-	sh	t0, (dest)
-	ADDC(sum, t0)
-	sltiu	t8, a2, 56
-	addu	dest, dest, 0x2
-	addu	src, src, 0x2
-
-dword_align:
-	bnez	t8, do_end_words
-	 move	t8, a2
-
-	andi	t8, src, 0x4
-	beqz	t8, qword_align
-	 andi	t8, src, 0x8
-
-	EX(lw, t0, 0x00(src), l_fixup)
-	subu	a2, a2, 0x4
-	ADDC(sum, t0)
-	sw	t0, 0x00(dest)
-	addu	src, src, 0x4
-	addu	dest, dest, 0x4
-	andi	t8, src, 0x8
-
-qword_align:
-	beqz	t8, oword_align
-	 andi	t8, src, 0x10
-
-	EX(lw, t0, 0x00(src), l_fixup)
-	EX(lw, t1, 0x04(src), l_fixup)
-	subu	a2, a2, 0x8
-	ADDC(sum, t0)
-	ADDC(sum, t1)
-	sw	t0, 0x00(dest)
-	addu	src, src, 0x8
-	sw	t1, 0x04(dest)
-	andi	t8, src, 0x10
-	addu	dest, dest, 0x8
-
-oword_align:
-	beqz	t8, begin_movement
-	 srl	t8, a2, 0x7
-
-	EX(lw, t3, 0x08(src), l_fixup)		# assumes subblock ordering
-	EX(lw, t4, 0x0c(src), l_fixup)
-	EX(lw, t0, 0x00(src), l_fixup)
-	EX(lw, t1, 0x04(src), l_fixup)
-	ADDC(sum, t3)
-	ADDC(sum, t4)
-	ADDC(sum, t0)
-	ADDC(sum, t1)
-	sw	t3, 0x08(dest)
-	subu	a2, a2, 0x10
-	sw	t4, 0x0c(dest)
-	addu	src, src, 0x10
-	sw	t0, 0x00(dest)
-	srl	t8, a2, 0x7
-	addu	dest, dest, 0x10
-	sw	t1, -0x0c(dest)
-
-begin_movement:
-	beqz	t8, 0f
-	 andi	t2, a2, 0x40
-
-move_128bytes:
-	CSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4)
-	CSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4)
-	CSUM_BIGCHUNK(src, dest, 0x40, sum, t0, t1, t3, t4)
-	CSUM_BIGCHUNK(src, dest, 0x60, sum, t0, t1, t3, t4)
-	subu	t8, t8, 0x01
-	addu	src, src, 0x80
-	bnez	t8, move_128bytes
-	 addu	dest, dest, 0x80
-
-0:
-	beqz	t2, 1f
-	 andi	t2, a2, 0x20
-
-move_64bytes:
-	CSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4)
-	CSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4)
-	addu	src, src, 0x40
-	addu	dest, dest, 0x40
-
-1:
-	beqz	t2, do_end_words
-	 andi	t8, a2, 0x1c
-
-move_32bytes:
-	CSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4)
-	andi	t8, a2, 0x1c
-	addu	src, src, 0x20
-	addu	dest, dest, 0x20
-
-do_end_words:
-	beqz	t8, maybe_end_cruft
-	 srl	t8, t8, 0x2
-
-end_words:
-	EX(lw, t0, (src), l_fixup)
-	subu	t8, t8, 0x1
-	ADDC(sum, t0)
-	sw	t0, (dest)
-	addu	src, src, 0x4
-	bnez	t8, end_words
-	 addu	dest, dest, 0x4
-
-maybe_end_cruft:
-	andi	t2, a2, 0x3
-
-small_memcpy:
- j small_csumcpy; move a2, t2
-	beqz	t2, out
-	 move	a2, t2
-
-end_bytes:
-	EX(lb, t0, (src), l_fixup)
-	subu	a2, a2, 0x1
-	sb	t0, (dest)
-	addu	src, src, 0x1
-	bnez	a2, end_bytes
-	 addu	dest, dest, 0x1
-
-out:
-	jr	ra
-	 move	v0, sum
-
-/* ------------------------------------------------------------------------- */
-
-/* Bad, bad.  At least try to align the source  */
-
-memcpy_u_src:
-	bnez	t8, small_memcpy		# < 8 bytes?
-	 move	t2, a2
-
-	beqz	a2, out
-	 andi	t7, src, 0x1			# odd alignment?
-
-u_hword_align:
-	beqz	t7, u_word_align
-	 andi	t8, src, 0x2
-
-	EX(lbu, t0, (src), l_fixup)
-	subu	a2, a2, 0x1
-	sb	t0, (dest)
-#ifdef __MIPSEL__
-	sll	t0, t0, 8
-#endif
-	ADDC(sum, t0)
-	addu	src, src, 0x1
-	addu	dest, dest, 0x1
-	andi	t8, src, 0x2
-
-u_word_align:
-	beqz	t8, u_dword_align
-	 sltiu	t8, a2, 56
-
-	EX(lhu, t0, (src), l_fixup)
-	subu	a2, a2, 0x2
-	ush	t0, (dest)
-	ADDC(sum, t0)
-	sltiu	t8, a2, 56
-	addu	dest, dest, 0x2
-	addu	src, src, 0x2
-
-u_dword_align:
-	bnez	t8, u_do_end_words
-	 move	t8, a2
-
-	andi	t8, src, 0x4
-	beqz	t8, u_qword_align
-	 andi	t8, src, 0x8
-
-	EX(lw, t0, 0x00(src), l_fixup)
-	subu	a2, a2, 0x4
-	ADDC(sum, t0)
-	usw	t0, 0x00(dest)
-	addu	src, src, 0x4
-	addu	dest, dest, 0x4
-	andi	t8, src, 0x8
-
-u_qword_align:
-	beqz	t8, u_oword_align
-	 andi	t8, src, 0x10
-
-	EX(lw, t0, 0x00(src), l_fixup)
-	EX(lw, t1, 0x04(src), l_fixup)
-	subu	a2, a2, 0x8
-	ADDC(sum, t0)
-	ADDC(sum, t1)
-	usw	t0, 0x00(dest)
-	addu	src, src, 0x8
-	usw	t1, 0x04(dest)
-	andi	t8, src, 0x10
-	addu	dest, dest, 0x8
-
-u_oword_align:
-	beqz	t8, u_begin_movement
-	 srl	t8, a2, 0x7
-
-	EX(lw, t3, 0x08(src), l_fixup)
-	EX(lw, t4, 0x0c(src), l_fixup)
-	EX(lw, t0, 0x00(src), l_fixup)
-	EX(lw, t1, 0x04(src), l_fixup)
-	ADDC(sum, t3)
-	ADDC(sum, t4)
-	ADDC(sum, t0)
-	ADDC(sum, t1)
-	usw	t3, 0x08(dest)
-	subu	a2, a2, 0x10
-	usw	t4, 0x0c(dest)
-	addu	src, src, 0x10
-	usw	t0, 0x00(dest)
-	srl	t8, a2, 0x7
-	addu	dest, dest, 0x10
-	usw	t1, -0x0c(dest)
-
-u_begin_movement:
-	beqz	t8, 0f
-	 andi	t2, a2, 0x40
-
-u_move_128bytes:
-	UCSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4)
-	UCSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4)
-	UCSUM_BIGCHUNK(src, dest, 0x40, sum, t0, t1, t3, t4)
-	UCSUM_BIGCHUNK(src, dest, 0x60, sum, t0, t1, t3, t4)
-	subu	t8, t8, 0x01
-	addu	src, src, 0x80
-	bnez	t8, u_move_128bytes
-	 addu	dest, dest, 0x80
-
-0:
-	beqz	t2, 1f
-	 andi	t2, a2, 0x20
-
-u_move_64bytes:
-	UCSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4)
-	UCSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4)
-	addu	src, src, 0x40
-	addu	dest, dest, 0x40
-
-1:
-	beqz	t2, u_do_end_words
-	 andi	t8, a2, 0x1c
-
-u_move_32bytes:
-	UCSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4)
-	andi	t8, a2, 0x1c
-	addu	src, src, 0x20
-	addu	dest, dest, 0x20
-
-u_do_end_words:
-	beqz	t8, u_maybe_end_cruft
-	 srl	t8, t8, 0x2
-
-u_end_words:
-	EX(lw, t0, 0x00(src), l_fixup)
-	subu	t8, t8, 0x1
-	ADDC(sum, t0)
-	usw	t0, 0x00(dest)
-	addu	src, src, 0x4
-	bnez	t8, u_end_words
-	 addu	dest, dest, 0x4
-
-u_maybe_end_cruft:
-	andi	t2, a2, 0x3
-
-u_cannot_optimize:
- j small_csumcpy; move a2, t2
-	beqz	t2, out
-	 move	a2, t2
-
-u_end_bytes:
-	EX(lb, t0, (src), l_fixup)
-	subu	a2, a2, 0x1
-	sb	t0, (dest)
-	addu	src, src, 0x1
-	bnez	a2, u_end_bytes
-	 addu	dest, dest, 0x1
-
-	jr	ra
-	 move	v0, sum
-	END(csum_partial_copy_from_user)
-
-l_fixup:
-	beqz	t7, 1f				# odd buffer alignment?
-	 nop
-	sll	v1, sum, 8			# swap bytes
-	srl	sum, sum, 8
-	or	sum, v1
-	andi	sum, 0xffff
-1:	ADDC(sum, a3)				# Add csum argument.
-
-	lw	t0, THREAD_BUADDR($28)		# clear the rest of the buffer
-	 nop
-	subu	t1, t0, src			# where to start clearing
-	addu	a0, dest, t1
-	move	a1, zero			# zero fill
-	j	__bzero
-	 subu	a2, t5, t0			# a2 = bad - srcend bytes to go
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/csum_partial_copy.c linux/arch/mips/lib/csum_partial_copy.c
--- v2.1.125/linux/arch/mips/lib/csum_partial_copy.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/csum_partial_copy.c	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,75 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		MIPS specific IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Ralf Baechle, <ralf@waldorf-gmbh.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * $Id: csum_partial_copy.c,v 1.2 1998/09/16 13:29:32 ralf Exp $
+ */
+#include <net/checksum.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/string.h>
+#include <asm/uaccess.h>
+
+/*
+ * copy while checksumming, otherwise like csum_partial
+ */
+unsigned int csum_partial_copy(const char *src, char *dst, 
+                               int len, unsigned int sum)
+{
+	/*
+	 * It's 2:30 am and I don't feel like doing it real ...
+	 * This is lots slower than the real thing (tm)
+	 */
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+
+	return sum;
+}
+
+/*
+ * Copy from userspace and compute checksum.  If we catch an exception
+ * then zero the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user (const char *src, char *dst,
+                                          int len, unsigned int sum,
+                                          int *err_ptr)
+{
+	int missing;
+
+	missing = copy_from_user(dst, src, len);
+	if (missing) {
+		memset(dst + len - missing, 0, missing);
+		*err_ptr = -EFAULT;
+	}
+		
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * Copy to userspace and compute checksum.
+ */
+unsigned int csum_partial_copy_to_user (const char *src, char *dst,
+                                        int len, unsigned int sum,
+                                        int *err_ptr)
+{
+	sum = csum_partial(src, len, sum);
+
+	if (copy_to_user(dst, src, len)) {
+		*err_ptr = -EFAULT;
+		return sum;
+	}
+
+	return sum;
+}
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/floppy-no.c linux/arch/mips/lib/floppy-no.c
--- v2.1.125/linux/arch/mips/lib/floppy-no.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/floppy-no.c	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,58 @@
+/* $Id: floppy-no.c,v 1.1 1998/05/07 18:38:32 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Dummy file for machines without standard floppy drives.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/floppy.h>
+
+/*
+ * How to access the FDC's registers.
+ */
+static void no_fd_dummy(void)
+{
+	panic("no_fd_dummy called - shouldn't happen");
+}
+
+static unsigned long no_fd_getfdaddr1(void)
+{
+	return (unsigned long)-1;	/* No FDC nowhere ... */
+}
+
+static unsigned long no_fd_drive_type(unsigned long n)
+{
+	return 0;
+}
+
+struct fd_ops no_fd_ops = {
+	/*
+	 * How to access the floppy controller's ports
+	 */
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	/*
+	 * How to access the floppy DMA functions.
+	 */
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	no_fd_getfdaddr1,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	no_fd_drive_type
+};
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/floppy-std.c linux/arch/mips/lib/floppy-std.c
--- v2.1.125/linux/arch/mips/lib/floppy-std.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/floppy-std.c	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,167 @@
+/* $Id: floppy-std.c,v 1.2 1998/05/28 03:17:57 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Access the floppy hardware on PC style hardware
+ *
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/kbdcntrlr.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/dma.h>
+#include <asm/floppy.h>
+#include <asm/keyboard.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mc146818rtc.h>
+#include <asm/pgtable.h>
+
+/*
+ * How to access the FDC's registers.
+ */
+static unsigned char std_fd_inb(unsigned int port)
+{
+	return inb_p(port);
+}
+
+static void std_fd_outb(unsigned char value, unsigned int port)
+{
+	outb_p(value, port);
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static void std_fd_enable_dma(int channel)
+{
+	enable_dma(channel);
+}
+
+static void std_fd_disable_dma(int channel)
+{
+	disable_dma(channel);
+}
+
+static int std_fd_request_dma(int channel)
+{
+	return request_dma(channel, "floppy");
+}
+
+static void std_fd_free_dma(int channel)
+{
+	free_dma(channel);
+}
+
+static void std_fd_clear_dma_ff(int channel)
+{
+	clear_dma_ff(channel);
+}
+
+static void std_fd_set_dma_mode(int channel, char mode)
+{
+	set_dma_mode(channel, mode);
+}
+
+static void std_fd_set_dma_addr(int channel, unsigned int addr)
+{
+	set_dma_addr(channel, addr);
+}
+
+static void std_fd_set_dma_count(int channel, unsigned int count)
+{
+	set_dma_count(channel, count);
+}
+
+static int std_fd_get_dma_residue(int channel)
+{
+	return get_dma_residue(channel);
+}
+
+static void std_fd_enable_irq(int irq)
+{
+	enable_irq(irq);
+}
+
+static void std_fd_disable_irq(int irq)
+{
+	disable_irq(irq);
+}
+
+static unsigned long std_fd_getfdaddr1(void)
+{
+	return 0x3f0;
+}
+
+/* Pure 2^n version of get_order */
+static int __get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+static unsigned long std_fd_dma_mem_alloc(unsigned long size)
+{
+	int order = __get_order(size);
+	unsigned long mem;
+
+	mem = __get_dma_pages(GFP_KERNEL,order);
+
+	return mem;
+}
+
+static void std_fd_dma_mem_free(unsigned long addr, unsigned long size)
+{       
+	free_pages(addr, __get_order(size));	
+}
+
+static unsigned long std_fd_drive_type(unsigned long n)
+{
+	if (n == 0)
+		return 4;	/* 3,5", 1.44mb */
+
+	return 0;
+}
+
+struct fd_ops std_fd_ops = {
+	/*
+	 * How to access the floppy controller's ports
+	 */
+	std_fd_inb,
+	std_fd_outb,
+	/*
+	 * How to access the floppy DMA functions.
+	 */
+	std_fd_enable_dma,
+	std_fd_disable_dma,
+	std_fd_request_dma,
+	std_fd_free_dma,
+	std_fd_clear_dma_ff,
+	std_fd_set_dma_mode,
+	std_fd_set_dma_addr,
+	std_fd_set_dma_count,
+	std_fd_get_dma_residue,
+	std_fd_enable_irq,
+	std_fd_disable_irq,
+        std_fd_getfdaddr1,
+        std_fd_dma_mem_alloc,
+        std_fd_dma_mem_free,
+	std_fd_drive_type
+};
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/ide-no.c linux/arch/mips/lib/ide-no.c
--- v2.1.125/linux/arch/mips/lib/ide-no.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/lib/ide-no.c	Tue Oct 20 13:52:54 1998
@@ -1,5 +1,4 @@
-/*
- * arch/mips/kernel/ide-none.c
+/* $Id: ide-no.c,v 1.2 1998/05/28 03:17:57 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -9,8 +8,6 @@
  * have IDE like the Indy.
  *
  * Copyright (C) 1998 by Ralf Baechle
- *
- * $Id: ide-no.c,v 1.1 1998/05/04 09:18:13 ralf Exp $
  */
 #include <linux/hdreg.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/memcpy.S linux/arch/mips/lib/memcpy.S
--- v2.1.125/linux/arch/mips/lib/memcpy.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/lib/memcpy.S	Tue Oct 20 13:52:54 1998
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * $Id: memcpy.S,v 1.2 1998/05/04 09:18:16 ralf Exp $
+ * $Id: memcpy.S,v 1.4 1998/07/03 14:05:33 ralf Exp $
  *
  * Unified implementation of memcpy, memmove and the __copy_user backend.
  * For __rmemcpy and memmove an exception is always a kernel bug, therefore
@@ -416,6 +416,7 @@
 	addu	a0, a2				# dst = dst + len
 	addu	a1, a2				# src = src + len
 
+#if 0 /* Horror fix */
 	xor	t0, a0, a1
 	andi	t0, t0, 0x3
 	move	t7, a0
@@ -552,6 +553,7 @@
 r_small_memcpy:
 	beqz	t2, r_out
 	 move	a2, t2
+#endif /* Horror fix */
 
 r_end_bytes:
 	lb	t0, -1(a1)
@@ -565,6 +567,7 @@
 	jr	ra
 	 move	a2, zero
 
+#if 0 /* Horror fix */
 /* ------------------------------------------------------------------------- */
 
 /* Bad, bad.  At least try to align the source  */
@@ -686,6 +689,7 @@
 	jr	ra
 	 move	a2, zero
 	END(__rmemcpy)
+#endif /* Horror fix */
 
 l_fixup:					# clear the rest of the buffer
 	lw	t0, THREAD_BUADDR($28)
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/memset.S linux/arch/mips/lib/memset.S
--- v2.1.125/linux/arch/mips/lib/memset.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/lib/memset.S	Tue Oct 20 13:52:54 1998
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1998 by Ralf Baechle
  *
- * $Id: memset.S,v 1.1 1998/05/04 09:18:18 ralf Exp $
+ * $Id: memset.S,v 1.2 1998/04/25 17:01:45 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/offset.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/rtc-no.c linux/arch/mips/lib/rtc-no.c
--- v2.1.125/linux/arch/mips/lib/rtc-no.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/rtc-no.c	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,34 @@
+/* $Id: rtc-no.c,v 1.2 1998/06/25 20:19:15 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Stub RTC routines to keep Linux from crashing on machine which don't
+ * have a RTC chip.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+
+static unsigned char no_rtc_read_data(unsigned long addr)
+{
+	panic("no_rtc_read_data called - shouldn't happen.");
+}
+
+static void no_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	panic("no_rtc_write_data called - shouldn't happen.");
+}
+
+static int no_rtc_bcd_mode(void)
+{
+	panic("no_rtc_bcd_mode called - shouldn't happen.");
+}
+
+struct rtc_ops no_rtc_ops = {
+	&no_rtc_read_data,
+	&no_rtc_write_data,
+	&no_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/rtc-std.c linux/arch/mips/lib/rtc-std.c
--- v2.1.125/linux/arch/mips/lib/rtc-std.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/rtc-std.c	Tue Oct 20 13:52:54 1998
@@ -0,0 +1,35 @@
+/* $Id: rtc-std.c,v 1.2 1998/06/25 20:19:16 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * RTC routines for PC style attached Dallas chip.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/io.h>
+
+static unsigned char std_rtc_read_data(unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	return inb_p(RTC_PORT(1));
+}
+
+static void std_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	outb_p(data, RTC_PORT(1));
+}
+
+static int std_rtc_bcd_mode(void)
+{
+	return 1;
+}
+
+struct rtc_ops std_rtc_ops = {
+	&std_rtc_read_data,
+	&std_rtc_write_data,
+	&std_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/strlen_user.S linux/arch/mips/lib/strlen_user.S
--- v2.1.125/linux/arch/mips/lib/strlen_user.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/lib/strlen_user.S	Tue Oct 20 13:52:54 1998
@@ -7,7 +7,7 @@
  *
  * Copyright (c) 1996, 1998 by Ralf Baechle
  *
- * $Id: strlen_user.S,v 1.2 1998/05/04 09:18:20 ralf Exp $
+ * $Id: strlen_user.S,v 1.3 1998/05/03 11:13:45 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/offset.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/strncpy_user.S linux/arch/mips/lib/strncpy_user.S
--- v2.1.125/linux/arch/mips/lib/strncpy_user.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/lib/strncpy_user.S	Tue Oct 20 13:52:54 1998
@@ -7,7 +7,7 @@
  *
  * Copyright (c) 1996 by Ralf Baechle
  *
- * $Id: strncpy_user.S,v 1.2 1998/05/04 09:18:22 ralf Exp $
+ * $Id: strncpy_user.S,v 1.3 1998/05/03 11:13:45 ralf Exp $
  */
 #include <linux/errno.h>
 #include <asm/asm.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c
--- v2.1.125/linux/arch/mips/mm/andes.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/mm/andes.c	Tue Oct 20 13:52:54 1998
@@ -1,9 +1,8 @@
-/*
+/* $Id: andes.c,v 1.6 1998/10/16 19:22:42 ralf Exp $
+ *
  * andes.c: MMU and cache operations for the R10000 (ANDES).
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: andes.c,v 1.5 1998/05/04 09:18:26 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -13,6 +12,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/sgialib.h>
+#include <asm/mmu_context.h>
 
 extern unsigned long mips_tlb_entries;
 
@@ -104,6 +104,7 @@
 	flush_tlb_mm = andes_flush_tlb_mm;
 	flush_tlb_range = andes_flush_tlb_range;
 	flush_tlb_page = andes_flush_tlb_page;
+	andes_asid_setup();
     
         add_wired_entry = andes_add_wired_entry;
 
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c
--- v2.1.125/linux/arch/mips/mm/fault.c	Wed Sep  9 14:51:06 1998
+++ linux/arch/mips/mm/fault.c	Tue Oct 20 13:52:54 1998
@@ -1,10 +1,14 @@
-/*
- *  arch/mips/mm/fault.c
+/* $Id: fault.c,v 1.12 1998/10/19 21:27:37 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *  Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
 #include <linux/signal.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -14,16 +18,20 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/version.h>
 
 #include <asm/hardirq.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
+#include <asm/softirq.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-extern void die_if_kernel(char *, struct pt_regs *, long);
+#define development_version (LINUX_VERSION_CODE & 0x100)
+
+extern void die(char *, struct pt_regs *, unsigned long write);
 
-unsigned long asid_cache = ASID_FIRST_VERSION;
+unsigned long asid_cache;
 
 /*
  * Macro for exception fixup code to access integer registers.
@@ -43,9 +51,12 @@
 	struct mm_struct *mm = tsk->mm;
 	unsigned long fixup;
 
-	if (local_irq_count[smp_processor_id()] != 0)
-		die_if_kernel("page fault from irq handler", regs, writeaccess);
-	lock_kernel();
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || mm == &init_mm)
+		goto no_context;
 #if 0
 	printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
 	       address, writeaccess, regs->cp0_epc);
@@ -74,8 +85,7 @@
 	}
 	handle_mm_fault(tsk, vma, address, writeaccess);
 	up(&mm->mmap_sem);
-
-	goto out;
+	return;
 
 /*
  * Something tried to access memory that isn't in our memory map..
@@ -97,20 +107,22 @@
 		       (unsigned long) regs->regs[31]);
 #endif
 		force_sig(SIGSEGV, tsk);
-		goto out;
+		return;
 	}
 
-	/* Did we have an exception handler installed? */
+no_context:
+	/* Are we prepared to handle this kernel fault?  */
 	fixup = search_exception_table(regs->cp0_epc);
 	if (fixup) {
 		long new_epc;
 
 		tsk->tss.cp0_baduaddr = address;
 		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
-		       tsk->comm, regs->cp0_epc, new_epc);
+		if (development_version)
+			printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
+			       tsk->comm, regs->cp0_epc, new_epc);
 		regs->cp0_epc = new_epc;
-		goto out;
+		return;
 	}
 
 	/*
@@ -120,8 +132,6 @@
 	printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
 	       "address %08lx, epc == %08lx, ra == %08lx\n",
 	       address, regs->cp0_epc, regs->regs[31]);
-	die_if_kernel("Oops", regs, writeaccess);
+	die("Oops", regs, writeaccess);
 	do_exit(SIGKILL);
-out:
-	unlock_kernel();
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/init.c linux/arch/mips/mm/init.c
--- v2.1.125/linux/arch/mips/mm/init.c	Wed Sep  9 14:51:06 1998
+++ linux/arch/mips/mm/init.c	Tue Oct 20 13:52:54 1998
@@ -1,11 +1,10 @@
-/*
+/* $Id: init.c,v 1.13 1998/10/16 19:22:42 ralf Exp $
+ *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
- *
- * $Id: init.c,v 1.15 1998/08/04 20:48:30 davem Exp $
+ * Copyright (C) 1994 - 1998 by Ralf Baechle
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -15,10 +14,12 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/pagemap.h>
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/swapctl.h>
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
 #endif
@@ -27,17 +28,77 @@
 #include <asm/cachectl.h>
 #include <asm/dma.h>
 #include <asm/jazzdma.h>
-#include <asm/vector.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #ifdef CONFIG_SGI
 #include <asm/sgialib.h>
 #endif
+#include <asm/mmu_context.h>
+
+/*
+ * Define this to effectivly disable the userpage colouring shit.
+ */
+#define CONF_GIVE_A_SHIT_ABOUT_COLOURS
 
 extern void deskstation_tyne_dma_init(void);
 extern void show_net_buffers(void);
 
-const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
+void __bad_pte_kernel(pmd_t *pmd)
+{
+	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
+	pmd_val(*pmd) = BAD_PAGETABLE;
+}
+
+void __bad_pte(pmd_t *pmd)
+{
+	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+	pmd_val(*pmd) = BAD_PAGETABLE;
+}
+
+pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
+{
+	pte_t *page;
+
+	page = (pte_t *) __get_free_page(GFP_KERNEL);
+	if (pmd_none(*pmd)) {
+		if (page) {
+			clear_page((unsigned long)page);
+			pmd_val(*pmd) = (unsigned long)page;
+			return page + offset;
+		}
+		pmd_val(*pmd) = BAD_PAGETABLE;
+		return NULL;
+	}
+	free_page((unsigned long)page);
+	if (pmd_bad(*pmd)) {
+		__bad_pte_kernel(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
+{
+	pte_t *page;
+
+	page = (pte_t *) __get_free_page(GFP_KERNEL);
+	if (pmd_none(*pmd)) {
+		if (page) {
+			clear_page((unsigned long)page);
+			pmd_val(*pmd) = (unsigned long)page;
+			return page + offset;
+		}
+		pmd_val(*pmd) = BAD_PAGETABLE;
+		return NULL;
+	}
+	free_page((unsigned long)page);
+	if (pmd_bad(*pmd)) {
+		__bad_pte(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + offset;
+}
+
 
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
@@ -46,9 +107,50 @@
 	return 0;
 }
 
+/*
+ * We have upto 8 empty zeroed pages so we can map one of the right colour
+ * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
+ * where we have to avoid VCED / VECI exceptions for good performance at
+ * any price.  Since page is never written to after the initialization we
+ * don't have to care about aliases on other CPUs.
+ */
+unsigned long empty_zero_page, zero_page_mask;
+
+static inline unsigned long setup_zero_pages(void)
+{
+	unsigned long order, size, pg;
+
+	switch (mips_cputype) {
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+		order = 3;
+	default:
+		order = 0;
+	}
+
+	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
+	if (!empty_zero_page)
+		panic("Oh boy, that early out of memory?");
+
+	pg = MAP_NR(empty_zero_page);
+	while(pg < MAP_NR(empty_zero_page) + (1 << order)) {
+		set_bit(PG_reserved, &mem_map[pg].flags);
+		pg++;
+	}
+
+	size = PAGE_SIZE << order;
+	zero_page_mask = (size - 1) & PAGE_MASK;
+	memset((void *)empty_zero_page, 0, size);
+
+	return size;
+}
+
 int do_check_pgt_cache(int low, int high)
 {
 	int freed = 0;
+
 	if(pgtable_cache_size > high) {
 		do {
 			if(pgd_quicklist)
@@ -141,10 +243,87 @@
 	return pte_mkdirty(mk_pte(page, PAGE_SHARED));
 }
 
+#ifdef __SMP__
+spinlock_t user_page_lock = SPIN_LOCK_UNLOCKED;
+#endif
+struct upcache user_page_cache[8] __attribute__((aligned(32)));
+static unsigned long user_page_order;
+unsigned long user_page_colours;
+
+unsigned long get_user_page_slow(int which)
+{
+	unsigned long chunk;
+	struct upcache *up = &user_page_cache[0];
+	struct page *p, *res;
+	int i;
+
+	do {
+		chunk = __get_free_pages(GFP_KERNEL, user_page_order);
+	} while(chunk==0);
+
+	p = mem_map + MAP_NR(chunk);
+	res = p + which;
+	spin_lock(&user_page_lock);
+	for (i=user_page_colours; i>=0; i--,p++,up++,chunk+=PAGE_SIZE) {
+		atomic_set(&p->count, 1);
+		p->age = PAGE_INITIAL_AGE;
+
+		if (p != res) {
+			if(up->count < USER_PAGE_WATER) {
+				p->next = up->list;
+				up->list = p;
+				up->count++;
+			} else
+				free_pages(chunk, 0);
+		}
+	}
+	spin_unlock(&user_page_lock);
+
+	return page_address(res);
+}
+
+static inline void user_page_setup(void)
+{
+	unsigned long assoc = 0;
+	unsigned long dcache_log, icache_log, cache_log;
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	switch(mips_cputype) {
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+		cache_log = 3;	/* => 32k, sucks  */
+		break;
+
+        case CPU_R4600:                 /* two way set associative caches?  */
+        case CPU_R4700:
+        case CPU_R5000:
+        case CPU_NEVADA:
+		assoc = 1;
+		/* fall through */
+	default:
+		/* use bigger cache  */
+		icache_log = (config >> 9) & 7;
+		dcache_log = (config >> 6) & 7;
+		if (dcache_log > icache_log)
+			cache_log = dcache_log;
+		else
+			cache_log = icache_log;
+	}
+
+#ifdef CONF_GIVE_A_SHIT_ABOUT_COLOURS
+	cache_log = assoc = 0;
+#endif
+
+	user_page_order = cache_log - assoc;
+	user_page_colours = (1 << (cache_log - assoc)) - 1;
+}
+
 void show_mem(void)
 {
 	int i, free = 0, total = 0, reserved = 0;
-	int shared = 0;
+	int shared = 0, cached = 0;
 
 	printk("Mem-info:\n");
 	show_free_areas();
@@ -154,15 +333,19 @@
 		total++;
 		if (PageReserved(mem_map+i))
 			reserved++;
+		else if (PageSwapCache(mem_map+i))
+			cached++;
 		else if (!atomic_read(&mem_map[i].count))
 			free++;
 		else
 			shared += atomic_read(&mem_map[i].count) - 1;
 	}
 	printk("%d pages of RAM\n", total);
-	printk("%d free pages\n", free);
 	printk("%d reserved pages\n", reserved);
 	printk("%d pages shared\n", shared);
+	printk("%d pages swap cached\n",cached);
+	printk("%ld pages in page table cache\n",pgtable_cache_size);
+	printk("%d free pages\n", free);
 	show_buffers();
 #ifdef CONFIG_NET
 	show_net_buffers();
@@ -173,7 +356,9 @@
 
 __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem))
 {
+	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
+	pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
 	return free_area_init(start_mem, end_mem);
 }
 
@@ -193,9 +378,6 @@
 	max_mapnr = num_physpages = MAP_NR(end_mem);
 	high_memory = (void *)end_mem;
 
-	/* clear the zero-page */
-	clear_page((unsigned long)empty_zero_page);
-
 	/* mark usable pages in the mem_map[] */
 	start_mem = PAGE_ALIGN(start_mem);
 
@@ -232,13 +414,18 @@
 			free_page(tmp);
 	}
 	tmp = nr_free_pages << PAGE_SHIFT;
+
+	/* Setup zeroed pages.  */
+	tmp -= setup_zero_pages();
+
 	printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
 		tmp >> 10,
 		max_mapnr << (PAGE_SHIFT-10),
 		codepages << (PAGE_SHIFT-10),
 		datapages << (PAGE_SHIFT-10));
 
-	return;
+	/* Initialize allocator for colour matched mapped pages.  */
+	user_page_setup();
 }
 
 extern char __init_begin, __init_end;
@@ -277,4 +464,36 @@
 	val->totalram <<= PAGE_SHIFT;
 	val->sharedram <<= PAGE_SHIFT;
 	return;
+}
+
+/* Fixup an immediate instruction  */
+__initfunc(static void __i_insn_fixup(unsigned int **start, unsigned int **stop,
+                         unsigned int i_const))
+{
+	unsigned int **p, *ip;
+
+	for (p = start;p < stop; p++) {
+		ip = *p;
+		*ip = (*ip & 0xffff0000) | i_const;
+	}
+}
+
+#define i_insn_fixup(section, const)					  \
+do {									  \
+	extern unsigned int *__start_ ## section;			  \
+	extern unsigned int *__stop_ ## section;			  \
+	__i_insn_fixup(&__start_ ## section, &__stop_ ## section, const); \
+} while(0)
+
+/* Caller is assumed to flush the caches before the first context switch.  */
+__initfunc(void __asid_setup(unsigned int inc, unsigned int mask,
+                             unsigned int version_mask,
+                             unsigned int first_version))
+{
+	i_insn_fixup(__asid_inc, inc);
+	i_insn_fixup(__asid_mask, mask);
+	i_insn_fixup(__asid_version_mask, version_mask);
+	i_insn_fixup(__asid_first_version, first_version);
+
+	asid_cache = first_version;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c
--- v2.1.125/linux/arch/mips/mm/loadmmu.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/mm/loadmmu.c	Tue Oct 20 13:52:54 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: loadmmu.c,v 1.6 1998/05/01 01:34:54 ralf Exp $
+ * $Id: loadmmu.c,v 1.7 1998/03/27 08:53:41 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- v2.1.125/linux/arch/mips/mm/r2300.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/mm/r2300.c	Tue Oct 20 13:52:54 1998
@@ -1,9 +1,8 @@
-/*
+/* $Id: r2300.c,v 1.7 1998/10/16 19:22:43 ralf Exp $
+ *
  * r2300.c: R2000 and R3000 specific mmu/cache code.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r2300.c,v 1.5 1998/05/01 01:34:55 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -14,6 +13,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/sgialib.h>
+#include <asm/mmu_context.h>
 
 extern unsigned long mips_tlb_entries;
 
@@ -199,7 +199,7 @@
 		 "=r" (dummy2)
 		:"r" ((unsigned long) invalid_pte_table),
 		 "0" (page),
-		 "1" (PAGE_SIZE/(sizeof(pmd_t)*8)));
+		 "1" (USER_PTRS_PER_PGD/8));
 }
 
 static void r2300_update_mmu_cache(struct vm_area_struct * vma,
@@ -274,6 +274,7 @@
 	flush_tlb_mm = r2300_flush_tlb_mm;
 	flush_tlb_range = r2300_flush_tlb_range;
 	flush_tlb_page = r2300_flush_tlb_page;
+	r3000_asid_setup();
 
 	load_pgd = r2300_load_pgd;
 	pgd_init = r2300_pgd_init;
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- v2.1.125/linux/arch/mips/mm/r4xx0.c	Thu Aug  6 14:06:29 1998
+++ linux/arch/mips/mm/r4xx0.c	Tue Oct 20 13:52:55 1998
@@ -1,9 +1,13 @@
-/*
+/* $Id: r4xx0.c,v 1.30 1998/10/16 19:22:43 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r4xx0.c,v 1.13 1998/05/21 07:34:35 davem Exp $
+ * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org
  *
  * To do:
  *
@@ -37,7 +41,7 @@
 static int ic_lsize, dc_lsize;       /* LineSize in bytes */
 
 /* Secondary cache (if present) parameters. */
-static scache_size, sc_lsize;        /* Again, in bytes */
+static unsigned int scache_size, sc_lsize;	/* Again, in bytes */
 
 #include <asm/cacheops.h>
 #include <asm/r4kcache.h>
@@ -74,10 +78,7 @@
  * - a version which handles the buggy R4600 v1.x
  * - a version which handles the buggy R4600 v2.0
  * - Finally a last version without fancy cache games for the SC and MC
- *   versions of R4000 and R4400.  Cache instructions are quite expensive
- *   and I guess using them for both the primary and the second level cache
- *   wouldn't be worth the effort.
- *   This needs to be verified by benchmarking.
+ *   versions of R4000 and R4400.
  */
 
 static void r4k_clear_page_d16(unsigned long page)
@@ -241,14 +242,84 @@
 	restore_flags(flags);
 }
 
-static void r4k_clear_page(unsigned long page)
+/*
+ * The next 4 versions are optimized for all possible scache configurations
+ * of the SC / MC versions of R4000 and R4400 ...
+ *
+ * Todo: For even better performance we should have a routine optimized for
+ * every legal combination of dcache / scache linesize.  When I (Ralf) tried
+ * this the kernel crashed shortly after mounting the root filesystem.  CPU
+ * bug?  Weirdo cache instruction semantics?
+ */
+static void r4k_clear_page_s16(unsigned long page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"cache\t%3,16(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"cache\t%3,-16(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD)
+		:"$1","memory");
+}
+
+static void r4k_clear_page_s32(unsigned long page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD)
+		:"$1","memory");
+}
+
+static void r4k_clear_page_s64(unsigned long page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
 		".set\tnoat\n\t"
 		".set\tmips3\n\t"
 		"daddiu\t$1,%0,%2\n"
-		"1:\tsd\t$0,(%0)\n\t"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
 		"sd\t$0,8(%0)\n\t"
 		"sd\t$0,16(%0)\n\t"
 		"sd\t$0,24(%0)\n\t"
@@ -263,7 +334,44 @@
 		".set\treorder"
 		:"=r" (page)
 		:"0" (page),
-		 "I" (PAGE_SIZE)
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD)
+		:"$1","memory");
+}
+
+static void r4k_clear_page_s128(unsigned long page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"sd\t$0,32(%0)\n\t"
+		"sd\t$0,40(%0)\n\t"
+		"sd\t$0,48(%0)\n\t"
+		"sd\t$0,56(%0)\n\t"
+		"daddiu\t%0,128\n\t"
+		"sd\t$0,-64(%0)\n\t"
+		"sd\t$0,-56(%0)\n\t"
+		"sd\t$0,-48(%0)\n\t"
+		"sd\t$0,-40(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD)
 		:"$1","memory");
 }
 
@@ -525,7 +633,10 @@
 	restore_flags(flags);
 }
 
-static void r4k_copy_page(unsigned long to, unsigned long from)
+/*
+ * These are for R4000SC / R4400MC
+ */
+static void r4k_copy_page_s16(unsigned long to, unsigned long from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -535,7 +646,8 @@
 		".set\tnoat\n\t"
 		".set\tmips3\n\t"
 		"daddiu\t$1,%0,%8\n"
-		"1:\tlw\t%2,(%1)\n\t"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
 		"lw\t%3,4(%1)\n\t"
 		"lw\t%4,8(%1)\n\t"
 		"lw\t%5,12(%1)\n\t"
@@ -543,6 +655,7 @@
 		"sw\t%3,4(%0)\n\t"
 		"sw\t%4,8(%0)\n\t"
 		"sw\t%5,12(%0)\n\t"
+		"cache\t%9,16(%0)\n\t"
 		"lw\t%2,16(%1)\n\t"
 		"lw\t%3,20(%1)\n\t"
 		"lw\t%4,24(%1)\n\t"
@@ -551,6 +664,7 @@
 		"sw\t%3,20(%0)\n\t"
 		"sw\t%4,24(%0)\n\t"
 		"sw\t%5,28(%0)\n\t"
+		"cache\t%9,32(%0)\n\t"
 		"daddiu\t%0,64\n\t"
 		"daddiu\t%1,64\n\t"
 		"lw\t%2,-32(%1)\n\t"
@@ -561,6 +675,208 @@
 		"sw\t%3,-28(%0)\n\t"
 		"sw\t%4,-24(%0)\n\t"
 		"sw\t%5,-20(%0)\n\t"
+		"cache\t%9,-16(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
+}
+
+static void r4k_copy_page_s32(unsigned long to, unsigned long from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"cache\t%9,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
+}
+
+static void r4k_copy_page_s64(unsigned long to, unsigned long from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
+}
+
+static void r4k_copy_page_s128(unsigned long to, unsigned long from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"lw\t%2,32(%1)\n\t"
+		"lw\t%3,36(%1)\n\t"
+		"lw\t%4,40(%1)\n\t"
+		"lw\t%5,44(%1)\n\t"
+		"sw\t%2,32(%0)\n\t"
+		"sw\t%3,36(%0)\n\t"
+		"sw\t%4,40(%0)\n\t"
+		"sw\t%5,44(%0)\n\t"
+		"lw\t%2,48(%1)\n\t"
+		"lw\t%3,52(%1)\n\t"
+		"lw\t%4,56(%1)\n\t"
+		"lw\t%5,60(%1)\n\t"
+		"sw\t%2,48(%0)\n\t"
+		"sw\t%3,52(%0)\n\t"
+		"sw\t%4,56(%0)\n\t"
+		"sw\t%5,60(%0)\n\t"
+		"daddiu\t%0,128\n\t"
+		"daddiu\t%1,128\n\t"
+		"lw\t%2,-64(%1)\n\t"
+		"lw\t%3,-60(%1)\n\t"
+		"lw\t%4,-56(%1)\n\t"
+		"lw\t%5,-52(%1)\n\t"
+		"sw\t%2,-64(%0)\n\t"
+		"sw\t%3,-60(%0)\n\t"
+		"sw\t%4,-56(%0)\n\t"
+		"sw\t%5,-52(%0)\n\t"
+		"lw\t%2,-48(%1)\n\t"
+		"lw\t%3,-44(%1)\n\t"
+		"lw\t%4,-40(%1)\n\t"
+		"lw\t%5,-36(%1)\n\t"
+		"sw\t%2,-48(%0)\n\t"
+		"sw\t%3,-44(%0)\n\t"
+		"sw\t%4,-40(%0)\n\t"
+		"sw\t%5,-36(%0)\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
 		"lw\t%2,-16(%1)\n\t"
 		"lw\t%3,-12(%1)\n\t"
 		"lw\t%4,-8(%1)\n\t"
@@ -576,9 +892,11 @@
 		:"=r" (dummy1), "=r" (dummy2),
 		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE));
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
 }
 
+
 /*
  * If you think for one second that this stuff coming up is a lot
  * of bulky code eating too many kernel cache lines.  Think _again_.
@@ -628,15 +946,6 @@
 	restore_flags(flags);
 }
 
-static inline void r4k_flush_cache_all_s16d32i32(void)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	blast_dcache32(); blast_icache32(); blast_scache16();
-	restore_flags(flags);
-}
-
 static inline void r4k_flush_cache_all_s32d32i32(void)
 {
 	unsigned long flags;
@@ -714,12 +1023,8 @@
 				pmd = pmd_offset(pgd, start);
 				pte = pte_offset(pmd, start);
 
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache16_page(start);
-					if(text)
-						blast_icache16_page(start);
+				if(pte_val(*pte) & _PAGE_VALID)
 					blast_scache16_page(start);
-				}
 				start += PAGE_SIZE;
 			}
 			restore_flags(flags);
@@ -759,12 +1064,8 @@
 				pmd = pmd_offset(pgd, start);
 				pte = pte_offset(pmd, start);
 
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache16_page(start);
-					if(text)
-						blast_icache16_page(start);
+				if(pte_val(*pte) & _PAGE_VALID)
 					blast_scache32_page(start);
-				}
 				start += PAGE_SIZE;
 			}
 			restore_flags(flags);
@@ -803,12 +1104,8 @@
 				pmd = pmd_offset(pgd, start);
 				pte = pte_offset(pmd, start);
 
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache16_page(start);
-					if(text)
-						blast_icache16_page(start);
+				if(pte_val(*pte) & _PAGE_VALID)
 					blast_scache64_page(start);
-				}
 				start += PAGE_SIZE;
 			}
 			restore_flags(flags);
@@ -847,56 +1144,8 @@
 				pmd = pmd_offset(pgd, start);
 				pte = pte_offset(pmd, start);
 
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache16_page(start);
-					if(text)
-						blast_icache16_page(start);
+				if(pte_val(*pte) & _PAGE_VALID)
 					blast_scache128_page(start);
-				}
-				start += PAGE_SIZE;
-			}
-			restore_flags(flags);
-		}
-	}
-}
-
-static void r4k_flush_cache_range_s16d32i32(struct mm_struct *mm,
-					    unsigned long start,
-					    unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if(mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if(vma) {
-		if(mm->context != current->mm->context) {
-			r4k_flush_cache_all_s16d32i32();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-			int text;
-
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache32_page(start);
-					if(text)
-						blast_icache32_page(start);
-					blast_scache16_page(start);
-				}
 				start += PAGE_SIZE;
 			}
 			restore_flags(flags);
@@ -935,12 +1184,8 @@
 				pmd = pmd_offset(pgd, start);
 				pte = pte_offset(pmd, start);
 
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache32_page(start);
-					if(text)
-						blast_icache32_page(start);
+				if(pte_val(*pte) & _PAGE_VALID)
 					blast_scache32_page(start);
-				}
 				start += PAGE_SIZE;
 			}
 			restore_flags(flags);
@@ -979,12 +1224,8 @@
 				pmd = pmd_offset(pgd, start);
 				pte = pte_offset(pmd, start);
 
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache32_page(start);
-					if(text)
-						blast_icache32_page(start);
+				if(pte_val(*pte) & _PAGE_VALID)
 					blast_scache64_page(start);
-				}
 				start += PAGE_SIZE;
 			}
 			restore_flags(flags);
@@ -1023,12 +1264,8 @@
 				pmd = pmd_offset(pgd, start);
 				pte = pte_offset(pmd, start);
 
-				if(pte_val(*pte) & _PAGE_VALID) {
-					blast_dcache32_page(start);
-					if(text)
-						blast_icache32_page(start);
+				if(pte_val(*pte) & _PAGE_VALID)
 					blast_scache128_page(start);
-				}
 				start += PAGE_SIZE;
 			}
 			restore_flags(flags);
@@ -1113,16 +1350,6 @@
 	}
 }
 
-static void r4k_flush_cache_mm_s16d32i32(struct mm_struct *mm)
-{
-	if(mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s16d32i32();
-	}
-}
-
 static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
 {
 	if(mm->context != 0) {
@@ -1221,12 +1448,8 @@
 		if(text)
 			blast_icache16_page_indexed(page);
 		blast_scache16_page_indexed(page);
-	} else {
-		blast_dcache16_page(page);
-		if(text)
-			blast_icache16_page(page);
+	} else
 		blast_scache16_page(page);
-	}
 out:
 	restore_flags(flags);
 }
@@ -1278,12 +1501,8 @@
 		if(text)
 			blast_icache16_page_indexed(page);
 		blast_scache32_page_indexed(page);
-	} else {
-		blast_dcache16_page(page);
-		if(text)
-			blast_icache16_page(page);
+	} else
 		blast_scache32_page(page);
-	}
 out:
 	restore_flags(flags);
 }
@@ -1336,12 +1555,8 @@
 		if(text)
 			blast_icache16_page_indexed(page);
 		blast_scache64_page_indexed(page);
-	} else {
-		blast_dcache16_page(page);
-		if(text)
-			blast_icache16_page(page);
+	} else
 		blast_scache64_page(page);
-	}
 out:
 	restore_flags(flags);
 }
@@ -1395,70 +1610,8 @@
 		if(text)
 			blast_icache16_page_indexed(page);
 		blast_scache128_page_indexed(page);
-	} else {
-		blast_dcache16_page(page);
-		if(text)
-			blast_icache16_page(page);
+	} else
 		blast_scache128_page(page);
-	}
-out:
-	restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_s16d32i32(struct vm_area_struct *vma,
-					   unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int text;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if(mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/* If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if(!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	text = (vma->vm_flags & VM_EXEC);
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if(mm->context != current->mm->context) {
-		/* Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache32_page_indexed(page);
-		if(text)
-			blast_icache32_page_indexed(page);
-		blast_scache16_page_indexed(page);
-	} else {
-		blast_dcache32_page(page);
-		if(text)
-			blast_icache32_page(page);
-		blast_scache16_page(page);
-	}
 out:
 	restore_flags(flags);
 }
@@ -1513,12 +1666,8 @@
 		if(text)
 			blast_icache32_page_indexed(page);
 		blast_scache32_page_indexed(page);
-	} else {
-		blast_dcache32_page(page);
-		if(text)
-			blast_icache32_page(page);
+	} else
 		blast_scache32_page(page);
-	}
 out:
 	restore_flags(flags);
 }
@@ -1573,12 +1722,8 @@
 		if(text)
 			blast_icache32_page_indexed(page);
 		blast_scache64_page_indexed(page);
-	} else {
-		blast_dcache32_page(page);
-		if(text)
-			blast_icache32_page(page);
+	} else
 		blast_scache64_page(page);
-	}
 out:
 	restore_flags(flags);
 }
@@ -1631,12 +1776,8 @@
 		if(text)
 			blast_icache32_page_indexed(page);
 		blast_scache128_page_indexed(page);
-	} else {
-		blast_dcache32_page(page);
-		if(text)
-			blast_icache32_page(page);
+	} else
 		blast_scache128_page(page);
-	}
 out:
 	restore_flags(flags);
 }
@@ -1828,15 +1969,10 @@
 {
 	page &= PAGE_MASK;
 	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("cram[%08lx]", page);
 #endif
-		save_and_cli(flags);
-		blast_dcache16_page(page);
 		blast_scache16_page(page);
-		restore_flags(flags);
 	}
 }
 
@@ -1844,15 +1980,10 @@
 {
 	page &= PAGE_MASK;
 	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("cram[%08lx]", page);
 #endif
-		save_and_cli(flags);
-		blast_dcache16_page(page);
 		blast_scache32_page(page);
-		restore_flags(flags);
 	}
 }
 
@@ -1860,15 +1991,10 @@
 {
 	page &= PAGE_MASK;
 	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("cram[%08lx]", page);
 #endif
-		save_and_cli(flags);
-		blast_dcache16_page(page);
 		blast_scache64_page(page);
-		restore_flags(flags);
 	}
 }
 
@@ -1876,31 +2002,10 @@
 {
 	page &= PAGE_MASK;
 	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("cram[%08lx]", page);
 #endif
-		save_and_cli(flags);
-		blast_dcache16_page(page);
 		blast_scache128_page(page);
-		restore_flags(flags);
-	}
-}
-
-static void r4k_flush_page_to_ram_s16d32i32(unsigned long page)
-{
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
-#endif
-		save_and_cli(flags);
-		blast_dcache32_page(page);
-		blast_scache16_page(page);
-		restore_flags(flags);
 	}
 }
 
@@ -1908,15 +2013,10 @@
 {
 	page &= PAGE_MASK;
 	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("cram[%08lx]", page);
 #endif
-		save_and_cli(flags);
-		blast_dcache32_page(page);
 		blast_scache32_page(page);
-		restore_flags(flags);
 	}
 }
 
@@ -1924,15 +2024,10 @@
 {
 	page &= PAGE_MASK;
 	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("cram[%08lx]", page);
 #endif
-		save_and_cli(flags);
-		blast_dcache32_page(page);
 		blast_scache64_page(page);
-		restore_flags(flags);
 	}
 }
 
@@ -1940,15 +2035,10 @@
 {
 	page &= PAGE_MASK;
 	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("cram[%08lx]", page);
 #endif
-		save_and_cli(flags);
-		blast_dcache32_page(page);
 		blast_scache128_page(page);
-		restore_flags(flags);
 	}
 }
 
@@ -2022,20 +2112,10 @@
 r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
-	unsigned int flags;
 
 	if (size >= scache_size) {
 		flush_cache_all();
-	} else {
-		save_and_cli(flags);
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-		restore_flags(flags);
+		return;
 	}
 
 	a = addr & ~(sc_lsize - 1);
@@ -2077,20 +2157,10 @@
 r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
-	unsigned int flags;
 
 	if (size >= scache_size) {
 		flush_cache_all();
-	} else {
-		save_and_cli(flags);
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-		restore_flags(flags);
+		return;
 	}
 
 	a = addr & ~(sc_lsize - 1);
@@ -2287,7 +2357,7 @@
 	unsigned long *p = (unsigned long *) page;
 	int i;
 
-	for(i = 0; i < 1024; i+=8) {
+	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
 		p[i + 0] = (unsigned long) invalid_pte_table;
 		p[i + 1] = (unsigned long) invalid_pte_table;
 		p[i + 2] = (unsigned long) invalid_pte_table;
@@ -2344,32 +2414,9 @@
 	BARRIER;
 	if(idx < 0) {
 		tlb_write_random();
-#if 0
-		BARRIER;
-		printk("[MISS]");
-#endif
 	} else {
 		tlb_write_indexed();
-#if 0
-		BARRIER;
-		printk("[HIT]");
-#endif
 	}
-#if 0
-	if(!strcmp(current->comm, "args")) {
-		printk("<");
-		for(idx = 0; idx < NTLB_ENTRIES; idx++) {
-			BARRIER;
-			set_index(idx);	BARRIER;
-			tlb_read(); BARRIER;
-			address = get_entryhi(); BARRIER;
-			if((address & 0xff) != 0)
-				printk("[%08lx]", address);
-		}
-		printk(">");
-	}
-	BARRIER;
-#endif
 	BARRIER;
 	set_entryhi(pid);
 	BARRIER;
@@ -2465,8 +2512,8 @@
 /* Detect and size the various r4k caches. */
 __initfunc(static void probe_icache(unsigned long config))
 {
-	icache_size = 1 << (12 + ((config >> 6) & 7));
-	ic_lsize = 16 << ((config >> 4) & 1);
+	icache_size = 1 << (12 + ((config >> 9) & 7));
+	ic_lsize = 16 << ((config >> 5) & 1);
 
 	printk("Primary instruction cache %dkb, linesize %d bytes)\n",
 	       icache_size >> 10, ic_lsize);
@@ -2565,8 +2612,8 @@
 	}
 	restore_flags(flags);
 	addr -= begin;
-	printk("Secondary cache sized at %dK linesize %d\n", (int) (addr >> 10),
-	       sc_lsize);
+	printk("Secondary cache sized at %dK linesize %d\n",
+	       (int) (addr >> 10), sc_lsize);
 	scache_size = addr;
 	return 1;
 }
@@ -2621,13 +2668,10 @@
 			flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16;
 			break;
 		case 32:
-			flush_cache_all = r4k_flush_cache_all_s16d32i32;
-			flush_cache_mm = r4k_flush_cache_mm_s16d32i32;
-			flush_cache_range = r4k_flush_cache_range_s16d32i32;
-			flush_cache_page = r4k_flush_cache_page_s16d32i32;
-			flush_page_to_ram = r4k_flush_page_to_ram_s16d32i32;
-			break;
+			panic("Invalid cache configuration detected");
 		};
+		clear_page = r4k_clear_page_s16;
+		copy_page = r4k_copy_page_s16;
 		break;
 	case 32:
 		switch(dc_lsize) {
@@ -2646,6 +2690,9 @@
 			flush_page_to_ram = r4k_flush_page_to_ram_s32d32i32;
 			break;
 		};
+		clear_page = r4k_clear_page_s32;
+		copy_page = r4k_copy_page_s32;
+		break;
 	case 64:
 		switch(dc_lsize) {
 		case 16:
@@ -2663,6 +2710,9 @@
 			flush_page_to_ram = r4k_flush_page_to_ram_s64d32i32;
 			break;
 		};
+		clear_page = r4k_clear_page_s64;
+		copy_page = r4k_copy_page_s64;
+		break;
 	case 128:
 		switch(dc_lsize) {
 		case 16:
@@ -2680,10 +2730,10 @@
 			flush_page_to_ram = r4k_flush_page_to_ram_s128d32i32;
 			break;
 		};
+		clear_page = r4k_clear_page_s128;
+		copy_page = r4k_copy_page_s128;
 		break;
 	}
-	clear_page = r4k_clear_page;
-	copy_page = r4k_copy_page;
 	dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
 	dma_cache_inv = r4k_dma_cache_inv_sc;
 }
@@ -2712,14 +2762,13 @@
 	return (regs->cp0_status & ST0_KSU) == KSU_USER;
 }
 
-
 __initfunc(void ld_mmu_r4xx0(void))
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
 
 	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
 
-	set_cp0_config(CONF_REG_CM_CMASK, CONF_REG_CM_CACHABLE_NONCOHERENT);
+	set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
 
 	probe_icache(config);
 	probe_dcache(config);
@@ -2742,6 +2791,7 @@
 	flush_tlb_mm = r4k_flush_tlb_mm;
 	flush_tlb_range = r4k_flush_tlb_range;
 	flush_tlb_page = r4k_flush_tlb_page;
+	r4xx0_asid_setup();
 
 	load_pgd = r4k_load_pgd;
 	pgd_init = r4k_pgd_init;
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/r6000.c linux/arch/mips/mm/r6000.c
--- v2.1.125/linux/arch/mips/mm/r6000.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/mm/r6000.c	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,5 @@
-/* $Id: r6000.c,v 1.4 1998/05/01 01:35:06 ralf Exp $
+/* $Id: r6000.c,v 1.6 1998/10/16 19:22:44 ralf Exp $
+ *
  * r6000.c: MMU and cache routines for the R6000 processors.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -13,6 +14,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/sgialib.h>
+#include <asm/mmu_context.h>
 
 __asm__(".set mips3"); /* because we know... */
 
@@ -109,7 +111,7 @@
 		 "=r" (dummy2)
 		:"r" ((unsigned long) invalid_pte_table),
 		 "0" (page),
-		 "1" (PAGE_SIZE/(sizeof(pmd_t)*8)),
+		 "1" (USER_PTRS_PER_PGD/8),
 		 "i" (Create_Dirty_Excl_D));
 }
 
@@ -180,6 +182,7 @@
 	flush_tlb_mm = r6000_flush_tlb_mm;
 	flush_tlb_range = r6000_flush_tlb_range;
 	flush_tlb_page = r6000_flush_tlb_page;
+	r6000_asid_setup();
 
 	load_pgd = r6000_load_pgd;
 	pgd_init = r6000_pgd_init;
diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/tfp.c linux/arch/mips/mm/tfp.c
--- v2.1.125/linux/arch/mips/mm/tfp.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/mm/tfp.c	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,5 @@
-/*
+/* $Id: tfp.c,v 1.6 1998/10/16 19:22:44 ralf Exp $
+ *
  * tfp.c: MMU and cache routines specific to the r8000 (TFP).
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -13,6 +14,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/sgialib.h>
+#include <asm/mmu_context.h>
 
 extern unsigned long mips_tlb_entries;
 
@@ -104,6 +106,7 @@
 	flush_tlb_mm = tfp_flush_tlb_mm;
 	flush_tlb_range = tfp_flush_tlb_range;
 	flush_tlb_page = tfp_flush_tlb_page;
+	tfp_asid_setup();
 
         add_wired_entry = tfp_add_wired_entry;
 
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/Makefile linux/arch/mips/sgi/kernel/Makefile
--- v2.1.125/linux/arch/mips/sgi/kernel/Makefile	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/Makefile	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.2 1998/05/01 01:35:13 ralf Exp $
+# $Id: Makefile,v 1.3 1998/06/25 20:19:17 ralf Exp $
 # Makefile for the SGI specific kernel interface routines
 # under Linux.
 #
@@ -13,8 +13,8 @@
 .S.o:
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
-OBJS  = indy_mc.o indy_sc.o indy_hpc.o indy_int.o system.o indy_timer.o \
-	indyIRQ.o reset.o setup.o time.o
+OBJS  = indy_mc.o indy_sc.o indy_hpc.o indy_int.o indy_rtc.o system.o \
+	indy_timer.o indyIRQ.o reset.o setup.o time.o
 
 all: sgikern.a
 
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indyIRQ.S linux/arch/mips/sgi/kernel/indyIRQ.S
--- v2.1.125/linux/arch/mips/sgi/kernel/indyIRQ.S	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/indyIRQ.S	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,4 @@
-/* $Id: indyIRQ.S,v 1.3 1998/05/01 01:35:14 ralf Exp $
+/* $Id: indyIRQ.S,v 1.3 1998/03/21 22:39:53 ralf Exp $
  * indyIRQ.S: Interrupt exception dispatch code for FullHouse and
  *            Guiness.
  *
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_hpc.c linux/arch/mips/sgi/kernel/indy_hpc.c
--- v2.1.125/linux/arch/mips/sgi/kernel/indy_hpc.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/indy_hpc.c	Tue Oct 20 13:52:55 1998
@@ -1,15 +1,13 @@
-/*
+/* $Id: indy_hpc.c,v 1.4 1998/07/14 09:12:27 ralf Exp $
+ *
  * indy_hpc.c: Routines for generic manipulation of the HPC controllers.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: indy_hpc.c,v 1.2 1998/05/01 01:35:14 ralf Exp $
+ * Copyright (C) 1998 Ralf Baechle
  */
 #include <linux/init.h>
 
 #include <asm/addrspace.h>
-#include <asm/ptrace.h>
-#include <asm/processor.h>
 #include <asm/sgihpc.h>
 #include <asm/sgint23.h>
 #include <asm/sgialib.h>
@@ -20,27 +18,13 @@
 struct hpc3_miscregs *hpc3mregs;
 
 /* We need software copies of these because they are write only. */
-static unsigned long write1, write2;
+unsigned long sgi_hpc_write1, sgi_hpc_write2;
 
 /* Machine specific identifier knobs. */
 int sgi_has_ioc2 = 0;
 int sgi_guiness = 0;
 int sgi_boardid;
 
-void sgihpc_write1_modify(int set, int clear)
-{
-	write1 |= set;
-	write1 &= ~clear;
-	hpc3mregs->write1 = write1;
-}
-
-void sgihpc_write2_modify(int set, int clear)
-{
-	write2 |= set;
-	write2 &= ~clear;
-	hpc3mregs->write2 = write2;
-}
-
 __initfunc(void sgihpc_init(void))
 {
 	unsigned long sid, crev, brev;
@@ -96,12 +80,12 @@
 	prom_printf("\n");
 #endif
 
-	write1 = (HPC3_WRITE1_PRESET |
+	sgi_hpc_write1 = (HPC3_WRITE1_PRESET |
 		  HPC3_WRITE1_KMRESET |
 		  HPC3_WRITE1_ERESET |
 		  HPC3_WRITE1_LC0OFF);
 
-	write2 = (HPC3_WRITE2_EASEL |
+	sgi_hpc_write2 = (HPC3_WRITE2_EASEL |
 		  HPC3_WRITE2_NTHRESH |
 		  HPC3_WRITE2_TPSPEED |
 		  HPC3_WRITE2_EPSEL |
@@ -109,9 +93,9 @@
 		  HPC3_WRITE2_U1AMODE);
 
 	if(!sgi_guiness)
-		write1 |= HPC3_WRITE1_GRESET;
-	hpc3mregs->write1 = write1;
-	hpc3mregs->write2 = write2;
+		sgi_hpc_write1 |= HPC3_WRITE1_GRESET;
+	hpc3mregs->write1 = sgi_hpc_write1;
+	hpc3mregs->write2 = sgi_hpc_write2;
 
 	hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c
--- v2.1.125/linux/arch/mips/sgi/kernel/indy_int.c	Thu Aug  6 14:06:29 1998
+++ linux/arch/mips/sgi/kernel/indy_int.c	Tue Oct 20 13:52:55 1998
@@ -1,13 +1,14 @@
-/*
+/* $Id: indy_int.c,v 1.9 1998/05/28 03:18:00 ralf Exp $
+ *
  * indy_int.c: Routines for generic manipulation of the INT[23] ASIC
  *             found on INDY workstations..
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: indy_int.c,v 1.7 1998/05/07 00:39:51 ralf Exp $
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
  */
 #include <linux/config.h>
 #include <linux/init.h>
+
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
 #include <linux/signal.h>
@@ -27,7 +28,6 @@
 #include <asm/irq.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
-#include <asm/vector.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_mc.c linux/arch/mips/sgi/kernel/indy_mc.c
--- v2.1.125/linux/arch/mips/sgi/kernel/indy_mc.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/indy_mc.c	Tue Oct 20 13:52:55 1998
@@ -3,14 +3,13 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: indy_mc.c,v 1.3 1998/05/04 09:18:37 ralf Exp $
+ * $Id: indy_mc.c,v 1.3 1998/04/25 15:43:32 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
 
 #include <asm/addrspace.h>
 #include <asm/ptrace.h>
-#include <asm/processor.h>
 #include <asm/sgimc.h>
 #include <asm/sgihpc.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_rtc.c linux/arch/mips/sgi/kernel/indy_rtc.c
--- v2.1.125/linux/arch/mips/sgi/kernel/indy_rtc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/indy_rtc.c	Tue Oct 20 13:52:55 1998
@@ -0,0 +1,37 @@
+/* $Id: indy_rtc.c,v 1.1 1998/06/25 20:19:17 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * RTC routines for Indy style attached Dallas chip.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/sgihpc.h>
+
+static unsigned char indy_rtc_read_data(unsigned long addr)
+{
+	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
+
+	return rtcregs[addr];
+}
+
+static void indy_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
+
+	rtcregs[addr] = data;
+}
+
+static int indy_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops indy_rtc_ops = {
+	&indy_rtc_read_data,
+	&indy_rtc_write_data,
+	&indy_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_sc.c linux/arch/mips/sgi/kernel/indy_sc.c
--- v2.1.125/linux/arch/mips/sgi/kernel/indy_sc.c	Wed May 20 19:10:37 1998
+++ linux/arch/mips/sgi/kernel/indy_sc.c	Tue Oct 20 13:52:55 1998
@@ -1,15 +1,16 @@
-/*
+/* $Id: indy_sc.c,v 1.9 1998/08/17 12:14:55 ralf Exp $
+ *
  * indy_sc.c: Indy cache managment functions.
  *
  * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org),
  * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
- *
- * $Id: indy_sc.c,v 1.4 1998/05/04 09:12:57 ralf Exp $
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/autoconf.h>
 
 #include <asm/bcache.h>
 #include <asm/sgi.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_timer.c linux/arch/mips/sgi/kernel/indy_timer.c
--- v2.1.125/linux/arch/mips/sgi/kernel/indy_timer.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/indy_timer.c	Tue Oct 20 13:52:55 1998
@@ -1,9 +1,9 @@
-/*
+/* $Id: indy_timer.c,v 1.9 1998/06/25 20:15:02 ralf Exp $
+ *
  * indy_timer.c: Setting up the clock on the INDY 8254 controller.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: indy_timer.c,v 1.5 1998/05/01 01:35:17 ralf Exp $
+ * Copytight (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
  */
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -26,26 +26,6 @@
 #include <asm/sgihpc.h>
 #include <asm/sgint23.h>
 
-/* The layout of registers for the INDY Dallas 1286 clock chipset. */
-struct indy_clock {
-        volatile unsigned int hsec;
-        volatile unsigned int sec;
-        volatile unsigned int min;
-        volatile unsigned int malarm;
-        volatile unsigned int hr;
-        volatile unsigned int halarm;
-        volatile unsigned int day;
-        volatile unsigned int dalarm;
-        volatile unsigned int date;
-        volatile unsigned int month;
-        volatile unsigned int year;
-        volatile unsigned int cmd;
-        volatile unsigned int whsec;
-        volatile unsigned int wsec;
-        volatile unsigned int _unused0[50];
-};
-
-#define INDY_CLOCK_REGS ((struct indy_clock *)(KSEG1ADDR(0x1fbe0000)))
 
 /* Because of a bug in the i8254 timer we need to use the onchip r4k
  * counter as our system wide timer interrupt running at 100HZ.
@@ -60,7 +40,7 @@
 
 static int set_rtc_mmss(unsigned long nowtime)
 {
-	struct indy_clock *clock = INDY_CLOCK_REGS;
+	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
 	int retval = 0;
 	int real_seconds, real_minutes, clock_minutes;
 
@@ -197,7 +177,7 @@
 
 __initfunc(static unsigned long get_indy_time(void))
 {
-	struct indy_clock *clock = INDY_CLOCK_REGS;
+	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
 	unsigned int year, mon, day, hour, min, sec;
 
 	/* Freeze it. */
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/reset.c linux/arch/mips/sgi/kernel/reset.c
--- v2.1.125/linux/arch/mips/sgi/kernel/reset.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/reset.c	Tue Oct 20 13:52:55 1998
@@ -1,31 +1,200 @@
-/*
- *  Reset a SGI.
+/* $Id: reset.c,v 1.6 1998/07/09 19:57:47 ralf Exp $
+ *
+ * Reset a SGI.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1997, 1998 by Ralf Baechle
- *
- * $Id: reset.c,v 1.3 1998/05/01 01:35:18 ralf Exp $
  */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/timer.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/reboot.h>
 #include <asm/sgialib.h>
+#include <asm/sgihpc.h>
+#include <asm/sgint23.h>
+
+/*
+ * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
+ * I'm not shure if this feature is a good idea, for now it's here just to
+ * make the power button make behave just like under IRIX.
+ */
+#define POWERDOWN_TIMEOUT	120
+
+/*
+ * Blink frequency during reboot grace period and when paniced.
+ */
+#define POWERDOWN_FREQ		(HZ / 4)
+#define PANIC_FREQ		(HZ / 8)
+
+static struct timer_list power_timer, blink_timer, debounce_timer;
+static int shuting_down, has_paniced;
+
+static void sgi_machine_restart(char *command) __attribute__((noreturn));
+static void sgi_machine_halt(void) __attribute__((noreturn));
+static void sgi_machine_power_off(void) __attribute__((noreturn));
 
 /* XXX How to pass the reboot command to the firmware??? */
-void sgi_machine_restart(char *command)
+static void sgi_machine_restart(char *command)
 {
+	if (shuting_down)
+		sgi_machine_power_off();
 	prom_reboot();
 }
 
-void sgi_machine_halt(void)
+static void sgi_machine_halt(void)
 {
+	if (shuting_down)
+		sgi_machine_power_off();
 	prom_imode();
 }
 
-void sgi_machine_power_off(void)
+static void sgi_machine_power_off(void)
+{
+	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
+
+	cli();
+
+	clock->cmd |= 0x08;	/* Disable watchdog */
+	clock->whsec = 0;
+	clock->wsec = 0;
+
+	while(1) {
+		hpc3mregs->panel=0xfe;
+		/* Good bye cruel world ...  */
+
+		/* If we're still running, we probably got sent an alarm
+		   interrupt.  Read the flag to clear it.  */
+		clock->halarm;
+	}
+}
+
+static void power_timeout(unsigned long data)
+{
+	sgi_machine_power_off();
+}
+
+static void blink_timeout(unsigned long data)
 {
-	prom_powerdown();
+	/* XXX fix this for fullhouse  */
+	sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF);
+	hpc3mregs->write1 = sgi_hpc_write1;
+
+	del_timer(&blink_timer);
+	blink_timer.expires = jiffies + data;
+	add_timer(&blink_timer);
+}
+
+static void debounce(unsigned long data)
+{
+	del_timer(&debounce_timer);
+	if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent.  */
+		debounce_timer.expires = jiffies + 5; /* 0.05s  */
+		add_timer(&debounce_timer);
+
+		hpc3mregs->panel = 0xf3;
+
+		return;
+	}
+
+	if (has_paniced)
+		prom_reboot();
+
+	enable_irq(9);
+}
+
+static inline void power_button(void)
+{
+	if (has_paniced)
+		return;
+
+	if (shuting_down || kill_proc(1, SIGINT, 1)) {
+		/* No init process or button pressed twice.  */
+		sgi_machine_power_off();
+	}
+
+	shuting_down = 1;
+	blink_timer.data = POWERDOWN_FREQ;
+	blink_timeout(POWERDOWN_FREQ);
+
+	init_timer(&power_timer);
+	power_timer.function = power_timeout;
+	power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
+	add_timer(&power_timer);
+}
+
+static inline void volume_up_button(void)
+{
+	/* Later when we have sound support ... */
+}
+
+static inline void volume_down_button(void)
+{
+	/* Later when we have sound support ... */
+}
+
+static void panel_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int buttons;
+
+	buttons = hpc3mregs->panel;
+	hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */
+
+	if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */
+		disable_irq(9);
+		init_timer(&debounce_timer);
+		debounce_timer.function = debounce;
+		debounce_timer.expires = jiffies + 5;
+		add_timer(&debounce_timer);
+	}
+
+	if (!(buttons & 2))		/* Power button was pressed */
+		power_button();
+	if (!(buttons & 0x40))		/* Volume up button was pressed */
+		volume_up_button();
+	if (!(buttons & 0x10))		/* Volume down button was pressed */
+		volume_down_button();
+}
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+                      void *ptr)
+{
+	if (has_paniced)
+		return NOTIFY_DONE;
+	has_paniced = 1;
+
+	blink_timer.data = PANIC_FREQ;
+	blink_timeout(PANIC_FREQ);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	panic_event,
+	NULL,
+	0
+};
+
+void indy_reboot_setup(void)
+{
+	static int setup_done;
+
+	if (setup_done)
+		return;
+	setup_done = 1;
+
+	_machine_restart = sgi_machine_restart;
+	_machine_halt = sgi_machine_halt;
+	_machine_power_off = sgi_machine_power_off;
+
+	request_irq(9, panel_int, 0, "Front Panel", NULL);
+	init_timer(&blink_timer);
+	blink_timer.function = blink_timeout;
+	notifier_chain_register(&panic_notifier_list, &panic_block);
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/setup.c linux/arch/mips/sgi/kernel/setup.c
--- v2.1.125/linux/arch/mips/sgi/kernel/setup.c	Thu Aug  6 14:06:29 1998
+++ linux/arch/mips/sgi/kernel/setup.c	Tue Oct 20 13:52:55 1998
@@ -1,32 +1,34 @@
-/* $Id: setup.c,v 1.6 1998/05/07 00:39:53 ralf Exp $
+/* $Id: setup.c,v 1.13 1998/09/16 22:50:46 ralf Exp $
  *
  * setup.c: SGI specific setup, including init of the feature struct.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
  */
 #include <linux/init.h>
+#include <linux/kbd_ll.h>
 #include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
 #include <linux/sched.h>
+#include <linux/mc146818rtc.h>
 
 #include <asm/addrspace.h>
 #include <asm/bcache.h>
 #include <asm/keyboard.h>
+#include <asm/irq.h>
 #include <asm/reboot.h>
-#include <asm/vector.h>
 #include <asm/sgialib.h>
 #include <asm/sgi.h>
 #include <asm/sgimc.h>
 #include <asm/sgihpc.h>
 #include <asm/sgint23.h>
 
-extern int serial_console; /* in console.c, of course */
+extern int serial_console; /* in sgiserial.c  */
 
-extern void sgi_machine_restart(char *command);
-extern void sgi_machine_halt(void);
-extern void sgi_machine_power_off(void);
-
-struct feature sgi_feature = {
-};
+extern struct rtc_ops indy_rtc_ops;
+void indy_reboot_setup(void);
 
 static volatile struct hpc_keyb *sgi_kh = (struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64);
 
@@ -68,6 +70,16 @@
 	kbd_write_output = sgi_write_output;
 	kbd_write_command = sgi_write_command;
 	kbd_read_status = sgi_read_status;
+
+	request_irq(SGI_KEYBOARD_IRQ, keyboard_interrupt,
+	            0, "keyboard", NULL);
+
+	/* Dirty hack, this get's called as a callback from the keyboard
+	   driver.  We piggyback the initialization of the front panel
+	   button handling on it even though they're technically not
+	   related with the keyboard driver in any way.  Doing it from
+	   indy_setup wouldn't work since kmalloc isn't initialized yet.  */
+	indy_reboot_setup();
 }
 
 __initfunc(static void sgi_irq_setup(void))
@@ -77,16 +89,13 @@
 
 __initfunc(void sgi_setup(void))
 {
+#ifdef CONFIG_SERIAL_CONSOLE
 	char *ctype;
+#endif
 
 	irq_setup = sgi_irq_setup;
-	feature = &sgi_feature;
 	keyboard_setup = sgi_keyboard_setup;
 
-	_machine_restart = sgi_machine_restart;
-	_machine_halt = sgi_machine_halt;
-	_machine_power_off = sgi_machine_power_off;
-
 	/* Init the INDY HPC I/O controller.  Need to call this before
 	 * fucking with the memory controller because it needs to know the
 	 * boardID and whether this is a Guiness or a FullHouse machine.
@@ -99,6 +108,7 @@
 	/* Now enable boardcaches, if any. */
 	indy_sc_init();
 
+#ifdef CONFIG_SERIAL_CONSOLE
 	/* ARCS console environment variable is set to "g?" for
 	 * graphics console, it is set to "d" for the first serial
 	 * line and "d2" for the second serial line.
@@ -117,4 +127,10 @@
 			prom_imode();
 		}
 	}
+#endif
+
+#ifdef CONFIG_VT
+	conswitchp = &newport_con;
+#endif
+	rtc_ops = &indy_rtc_ops;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/system.c linux/arch/mips/sgi/kernel/system.c
--- v2.1.125/linux/arch/mips/sgi/kernel/system.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/system.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: system.c,v 1.4 1998/05/01 01:35:19 ralf Exp $
+ * $Id: system.c,v 1.4 1998/03/27 08:53:45 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/time.c linux/arch/mips/sgi/kernel/time.c
--- v2.1.125/linux/arch/mips/sgi/kernel/time.c	Fri May  8 23:14:43 1998
+++ linux/arch/mips/sgi/kernel/time.c	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.2 1998/05/01 01:35:20 ralf Exp $
+/* $Id: time.c,v 1.2 1998/03/27 08:53:45 ralf Exp $
  * time.c: Generic SGI time_init() code, this will dispatch to the
  *         appropriate per-architecture time/counter init code.
  *
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/Makefile linux/arch/mips/sgi/prom/Makefile
--- v2.1.125/linux/arch/mips/sgi/prom/Makefile	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/Makefile	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.2 1998/05/01 01:35:22 ralf Exp $
+# $Id: Makefile,v 1.1.1.1 1997/06/01 03:16:40 ralf Exp $
 # Makefile for the SGI arcs prom monitor library routines
 # under Linux.
 #
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/cmdline.c linux/arch/mips/sgi/prom/cmdline.c
--- v2.1.125/linux/arch/mips/sgi/prom/cmdline.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/cmdline.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: cmdline.c,v 1.3 1998/05/01 01:35:22 ralf Exp $
+ * $Id: cmdline.c,v 1.3 1998/03/27 08:53:46 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/console.c linux/arch/mips/sgi/prom/console.c
--- v2.1.125/linux/arch/mips/sgi/prom/console.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/console.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  *
- * $Id: console.c,v 1.2 1998/05/01 01:35:23 ralf Exp $
+ * $Id: console.c,v 1.2 1998/03/27 08:53:46 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/env.c linux/arch/mips/sgi/prom/env.c
--- v2.1.125/linux/arch/mips/sgi/prom/env.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/env.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: env.c,v 1.2 1998/05/01 01:35:24 ralf Exp $
+ * $Id: env.c,v 1.2 1998/03/27 08:53:46 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/file.c linux/arch/mips/sgi/prom/file.c
--- v2.1.125/linux/arch/mips/sgi/prom/file.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/file.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: file.c,v 1.2 1998/05/01 01:35:24 ralf Exp $
+ * $Id: file.c,v 1.2 1998/03/27 08:53:47 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/init.c linux/arch/mips/sgi/prom/init.c
--- v2.1.125/linux/arch/mips/sgi/prom/init.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/init.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: init.c,v 1.2 1998/05/01 01:35:25 ralf Exp $
+ * $Id: init.c,v 1.2 1998/03/27 08:53:47 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/memory.c linux/arch/mips/sgi/prom/memory.c
--- v2.1.125/linux/arch/mips/sgi/prom/memory.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/memory.c	Tue Oct 20 13:52:55 1998
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: memory.c,v 1.2 1998/05/01 01:35:25 ralf Exp $
+ * $Id: memory.c,v 1.2 1998/03/27 08:53:47 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/misc.c linux/arch/mips/sgi/prom/misc.c
--- v2.1.125/linux/arch/mips/sgi/prom/misc.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/misc.c	Tue Oct 20 13:52:55 1998
@@ -1,9 +1,8 @@
-/*
+/* $Id: misc.c,v 1.6 1998/07/08 15:59:13 ralf Exp $
+ *
  * misc.c: Miscellaneous ARCS PROM routines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: misc.c,v 1.2 1998/05/01 01:35:26 ralf Exp $
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -15,14 +14,12 @@
 #include <asm/system.h>
 
 extern unsigned long mips_cputype;
-extern int initialize_kbd(void);
 extern void *sgiwd93_host;
 extern void reset_wd33c93(void *instance);
 
 void prom_halt(void)
 {
 	bcops->bc_disable();
-	initialize_kbd();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
@@ -33,7 +30,6 @@
 void prom_powerdown(void)
 {
 	bcops->bc_disable();
-	initialize_kbd();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
@@ -45,7 +41,6 @@
 void prom_restart(void)
 {
 	bcops->bc_disable();
-	initialize_kbd();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
@@ -56,7 +51,6 @@
 void prom_reboot(void)
 {
 	bcops->bc_disable();
-	initialize_kbd();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
@@ -67,7 +61,6 @@
 void prom_imode(void)
 {
 	bcops->bc_disable();
-	initialize_kbd();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/printf.c linux/arch/mips/sgi/prom/printf.c
--- v2.1.125/linux/arch/mips/sgi/prom/printf.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/printf.c	Tue Oct 20 13:52:55 1998
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  *
- * $Id: printf.c,v 1.2 1998/05/01 01:35:27 ralf Exp $
+ * $Id: printf.c,v 1.2 1998/03/27 08:53:48 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/salone.c linux/arch/mips/sgi/prom/salone.c
--- v2.1.125/linux/arch/mips/sgi/prom/salone.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/salone.c	Tue Oct 20 13:52:55 1998
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: salone.c,v 1.2 1998/05/01 01:35:27 ralf Exp $
+ * $Id: salone.c,v 1.2 1998/03/27 08:53:48 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/tags.c linux/arch/mips/sgi/prom/tags.c
--- v2.1.125/linux/arch/mips/sgi/prom/tags.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/tags.c	Tue Oct 20 13:52:55 1998
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: tags.c,v 1.2 1998/05/01 01:35:28 ralf Exp $
+ * $Id: tags.c,v 1.2 1998/03/27 08:53:48 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/time.c linux/arch/mips/sgi/prom/time.c
--- v2.1.125/linux/arch/mips/sgi/prom/time.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/time.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: time.c,v 1.2 1998/05/01 01:35:29 ralf Exp $
+ * $Id: time.c,v 1.2 1998/03/27 08:53:49 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/tree.c linux/arch/mips/sgi/prom/tree.c
--- v2.1.125/linux/arch/mips/sgi/prom/tree.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sgi/prom/tree.c	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: tree.c,v 1.2 1998/05/01 01:35:30 ralf Exp $
+ * $Id: tree.c,v 1.2 1998/03/27 08:53:49 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/Makefile linux/arch/mips/sni/Makefile
--- v2.1.125/linux/arch/mips/sni/Makefile	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sni/Makefile	Tue Oct 20 13:52:55 1998
@@ -5,7 +5,7 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 #
-# $Id: Makefile,v 1.2 1998/05/01 01:35:32 ralf Exp $
+# $Id: Makefile,v 1.2 1997/12/20 13:27:14 ralf Exp $
 #
 
 .S.s:
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/hw-access.c linux/arch/mips/sni/hw-access.c
--- v2.1.125/linux/arch/mips/sni/hw-access.c	Thu Aug  6 14:06:29 1998
+++ linux/arch/mips/sni/hw-access.c	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,4 @@
-/* $Id: hw-access.c,v 1.5 1998/05/07 00:39:56 ralf Exp $
+/* $Id: hw-access.c,v 1.8 1998/09/16 22:50:46 ralf Exp $
  *
  * Low-level hardware access stuff for SNI RM200 PCI
  *
@@ -10,6 +10,7 @@
  */
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/kbd_ll.h>
 #include <linux/kbdcntrlr.h>
 #include <linux/kernel.h>
 #include <linux/linkage.h>
@@ -23,144 +24,7 @@
 #include <asm/irq.h>
 #include <asm/mc146818rtc.h>
 #include <asm/pgtable.h>
-#include <asm/vector.h>
-
-extern int FLOPPY_IRQ;
-extern int FLOPPY_DMA;
-
-/*
- * How to access the FDC's registers.
- */
-static unsigned char
-fd_inb(unsigned int port)
-{
-	return inb_p(port);
-}
-
-static void
-fd_outb(unsigned char value, unsigned int port)
-{
-	outb_p(value, port);
-}
-
-/*
- * How to access the floppy DMA functions.
- */
-static void
-fd_enable_dma(int channel)
-{
-	enable_dma(channel);
-}
-
-static void
-fd_disable_dma(int channel)
-{
-	disable_dma(channel);
-}
-
-static int
-fd_request_dma(int channel)
-{
-	return request_dma(channel, "floppy");
-}
-
-static void
-fd_free_dma(int channel)
-{
-	free_dma(channel);
-}
-
-static void
-fd_clear_dma_ff(int channel)
-{
-	clear_dma_ff(channel);
-}
-
-static void
-fd_set_dma_mode(int channel, char mode)
-{
-	set_dma_mode(channel, mode);
-}
-
-static void
-fd_set_dma_addr(int channel, unsigned int addr)
-{
-	set_dma_addr(channel, addr);
-}
-
-static void
-fd_set_dma_count(int channel, unsigned int count)
-{
-	set_dma_count(channel, count);
-}
-
-static int
-fd_get_dma_residue(int channel)
-{
-	return get_dma_residue(channel);
-}
-
-static void
-fd_enable_irq(int irq)
-{
-	enable_irq(irq);
-}
-
-static void
-fd_disable_irq(int irq)
-{
-	disable_irq(irq);
-}
-
-void
-sni_fd_cacheflush(const void *addr, size_t size)
-{
-	flush_cache_all();
-}
-
-/*
- * RTC stuff (This is a guess on how the RM handles this ...)
- */
-static unsigned char
-rtc_read_data(unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	return inb_p(RTC_PORT(1));
-}
-
-static void
-rtc_write_data(unsigned char data, unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	outb_p(data, RTC_PORT(1));
-}
-
-struct feature sni_rm200_pci_feature = {
-	/*
-	 * How to access the floppy controller's ports
-	 */
-	fd_inb,
-	fd_outb,
-	/*
-	 * How to access the floppy DMA functions.
-	 */
-	fd_enable_dma,
-	fd_disable_dma,
-	fd_request_dma,
-	fd_free_dma,
-	fd_clear_dma_ff,
-	fd_set_dma_mode,
-	fd_set_dma_addr,
-	fd_set_dma_count,
-	fd_get_dma_residue,
-	fd_enable_irq,
-	fd_disable_irq,
-	/*
-	 * How to access the RTC functions.
-	 */
-	rtc_read_data,
-	rtc_write_data
-};
+#include <asm/sni.h>
 
 #define KBD_STAT_IBF		0x02	/* Keyboard input buffer full */
 
@@ -200,5 +64,7 @@
 	kbd_write_output = sni_write_output;
 	kbd_write_command = sni_write_command;
 	kbd_read_status = sni_read_status;
+	request_irq(PCIMT_KEYBOARD_IRQ, keyboard_interrupt,
+	            0, "keyboard", NULL);
 	request_region(0x60, 16, "keyboard");
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/int-handler.S linux/arch/mips/sni/int-handler.S
--- v2.1.125/linux/arch/mips/sni/int-handler.S	Thu Aug  6 14:06:29 1998
+++ linux/arch/mips/sni/int-handler.S	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,4 @@
-/* $Id: int-handler.S,v 1.4 1998/05/08 01:44:24 ralf Exp $
+/* $Id: int-handler.S,v 1.4 1998/05/07 14:17:47 ralf Exp $
  *
  * SNI RM200 PCI specific interrupt handler code.
  *
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/io.c linux/arch/mips/sni/io.c
--- v2.1.125/linux/arch/mips/sni/io.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sni/io.c	Tue Oct 20 13:52:55 1998
@@ -5,7 +5,7 @@
  *
  * Low level I/O functions for SNI.
  *
- * $Id: io.c,v 1.2 1998/05/01 01:35:34 ralf Exp $
+ * $Id: io.c,v 1.2 1998/03/27 08:53:50 ralf Exp $
  */
 #include <linux/string.h>
 #include <asm/mipsconfig.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/pci.c linux/arch/mips/sni/pci.c
--- v2.1.125/linux/arch/mips/sni/pci.c	Thu Aug  6 14:06:29 1998
+++ linux/arch/mips/sni/pci.c	Tue Oct 20 13:52:55 1998
@@ -1,13 +1,14 @@
-/* $Id: pci.c,v 1.5 1998/05/08 01:44:26 ralf Exp $
+/* $Id: pci.c,v 1.6 1998/05/07 14:17:48 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * SNI specific PCI support for RM200/RM300.
+ *
+ * Copyright (C) 1997, 1998 Ralf Baechle
  */
 #include <linux/config.h>
-#include <linux/bios32.h>
 #include <linux/pci.h>
 #include <linux/types.h>
 #include <asm/byteorder.h>
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/pcimt_scache.c linux/arch/mips/sni/pcimt_scache.c
--- v2.1.125/linux/arch/mips/sni/pcimt_scache.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/sni/pcimt_scache.c	Tue Oct 20 13:52:55 1998
@@ -7,9 +7,10 @@
  *
  * Copyright (c) 1997 by Ralf Baechle
  *
- * $Id: pcimt_scache.c,v 1.1 1998/03/04 08:47:29 ralf Exp $
+ * $Id: pcimt_scache.c,v 1.2 1998/05/28 03:18:02 ralf Exp $
  */
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <asm/bcache.h>
 #include <asm/sni.h>
 
diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/setup.c linux/arch/mips/sni/setup.c
--- v2.1.125/linux/arch/mips/sni/setup.c	Thu Aug  6 14:06:29 1998
+++ linux/arch/mips/sni/setup.c	Tue Oct 20 13:52:55 1998
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.7 1998/06/10 07:21:19 davem Exp $
+/* $Id: setup.c,v 1.13 1998/08/17 13:57:45 ralf Exp $
  *
  * Setup pointers to hardware-dependent routines.
  *
@@ -6,7 +6,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
  */
 #include <asm/ptrace.h>
 #include <linux/config.h>
@@ -26,7 +26,6 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/sni.h>
-#include <asm/vector.h>
 #include <asm/pci.h>
 
 /*
@@ -40,8 +39,6 @@
 static struct irqaction irq2  = { no_action, 0, 0, "cascade", NULL, NULL};
 
 extern asmlinkage void sni_rm200_pci_handle_int(void);
-extern asmlinkage void sni_fd_cacheflush(const void *addr, size_t size);
-extern struct feature sni_rm200_pci_feature;
 extern void sni_rm200_keyboard_setup(void);
 
 extern void sni_machine_restart(char *command);
@@ -49,6 +46,7 @@
 extern void sni_machine_power_off(void);
 
 extern struct ide_ops std_ide_ops;
+extern struct rtc_ops std_rtc_ops;
 
 __initfunc(static void sni_irq_setup(void))
 {
@@ -133,8 +131,6 @@
 	sni_pcimt_sc_init();
 
 	irq_setup = sni_irq_setup;
-	fd_cacheflush = sni_fd_cacheflush;	// Will go away
-	feature = &sni_rm200_pci_feature;
 	mips_io_port_base = SNI_PORT_BASE;
 	keyboard_setup = sni_rm200_keyboard_setup;
 
@@ -165,7 +161,10 @@
 	 */
 	request_region(0xcfc,0x04,"PCI config data");
 	pci_ops = &sni_pci_ops;
+
 #ifdef CONFIG_BLK_DEV_IDE
 	ide_ops = &std_ide_ops;
 #endif
+
+	rtc_ops = &std_rtc_ops;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/mips/tools/Makefile linux/arch/mips/tools/Makefile
--- v2.1.125/linux/arch/mips/tools/Makefile	Fri May  8 23:14:44 1998
+++ linux/arch/mips/tools/Makefile	Tue Oct 20 13:52:55 1998
@@ -3,7 +3,7 @@
 # Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
 # Copyright (C) 1997 Ralf Baechle (ralf@gnu.ai.mit.edu)
 #
-# $Id: Makefile,v 1.3 1998/05/01 01:35:37 ralf Exp $
+# $Id: Makefile,v 1.2 1997/09/23 06:23:49 ralf Exp $
 #
 TARGET	:= $(TOPDIR)/include/asm-$(ARCH)/offset.h
 
diff -u --recursive --new-file v2.1.125/linux/arch/mips/tools/offset.c linux/arch/mips/tools/offset.c
--- v2.1.125/linux/arch/mips/tools/offset.c	Fri May  8 23:14:44 1998
+++ linux/arch/mips/tools/offset.c	Tue Oct 20 13:52:55 1998
@@ -1,10 +1,9 @@
-/*
+/* $Id: offset.c,v 1.10 1998/08/19 21:53:53 ralf Exp $
+ *
  * offset.c: Calculate pt_regs and task_struct offsets.
  *
  * Copyright (C) 1996 David S. Miller
  * Made portable by Ralf Baechle
- *
- * $Id: offset.c,v 1.6 1998/05/04 09:18:45 ralf Exp $
  */
 
 #include <linux/types.h>
@@ -77,10 +76,11 @@
 {
 	text("/* MIPS task_struct offsets. */");
 	offset("#define TASK_STATE         ", struct task_struct, state);
-	offset("#define TASK_COUNTER       ", struct task_struct, counter);
-	offset("#define TASK_PRIORITY      ", struct task_struct, priority);
 	offset("#define TASK_FLAGS         ", struct task_struct, flags);
 	offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
+	offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
+	offset("#define TASK_COUNTER       ", struct task_struct, counter);
+	offset("#define TASK_PRIORITY      ", struct task_struct, priority);
 	offset("#define TASK_MM            ", struct task_struct, mm);
 	linefeed;
 }
diff -u --recursive --new-file v2.1.125/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- v2.1.125/linux/arch/ppc/kernel/pmac_setup.c	Mon Oct  5 13:13:36 1998
+++ linux/arch/ppc/kernel/pmac_setup.c	Wed Oct 14 11:43:13 1998
@@ -145,6 +145,12 @@
 #include "../../../drivers/scsi/sd.h"
 #include "../../../drivers/scsi/hosts.h"
 
+#define SD_MAJOR(i)		(!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
+#define SD_MAJOR_NUMBER(i)	SD_MAJOR((i) >> 8)
+#define SD_MINOR_NUMBER(i)	((i) & 255)
+#define MKDEV_SD_PARTITION(i)	MKDEV(SD_MAJOR_NUMBER(i), SD_MINOR_NUMBER(i))
+#define MKDEV_SD(index)		MKDEV_SD_PARTITION((index) << 4)
+
 kdev_t sd_find_target(void *host, int tgt)
 {
     Scsi_Disk *dp;
@@ -153,7 +159,7 @@
     for (dp = rscsi_disks, i = 0; i < sd_template.dev_max; ++i, ++dp)
         if (dp->device != NULL && dp->device->host == host
             && dp->device->id == tgt)
-            return MKDEV(SCSI_DISK_MAJOR, i << 4);
+            return MKDEV_SD(i);
     return 0;
 }
 #endif
diff -u --recursive --new-file v2.1.125/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v2.1.125/linux/drivers/block/Config.in	Mon Oct  5 13:13:38 1998
+++ linux/drivers/block/Config.in	Mon Oct 12 11:40:12 1998
@@ -43,6 +43,7 @@
             bool '     Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
             bool '     NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415
             bool '     VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586
+            bool '     CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646
           fi
         fi
       fi
diff -u --recursive --new-file v2.1.125/linux/drivers/block/README.fd linux/drivers/block/README.fd
--- v2.1.125/linux/drivers/block/README.fd	Wed Jun 24 22:54:04 1998
+++ linux/drivers/block/README.fd	Mon Oct 12 14:13:54 1998
@@ -102,12 +102,12 @@
 	Tells the floppy driver that a workable DMA channel is available
 	(the default).
 
-floppy=nofifo
+ floppy=nofifo
 	Disables the FIFO entirely. This is needed if you get "Bus
 	master arbitration error" messages from your Ethernet card (or
 	from other devices) while accessing the floppy.
 
-floppy=fifo
+ floppy=fifo
 	Enables the FIFO (default)
 
  floppy=<threshold>,fifo_depth
@@ -188,6 +188,13 @@
 
  floppy=<nr>,dma
 	Sets the floppy DMA channel to <nr> instead of 2
+
+ floppy=slow
+	Use PS/2 stepping rate:
+	 " PS/2 floppies have much slower step rates than regular floppies.
+	   It's been recommended that take about 1/4 of the default speed
+	   in some more extreme cases."
+	 
 
 
 Supporting utilities and additional documentation:
diff -u --recursive --new-file v2.1.125/linux/drivers/block/acsi.c linux/drivers/block/acsi.c
--- v2.1.125/linux/drivers/block/acsi.c	Wed Aug 26 11:37:34 1998
+++ linux/drivers/block/acsi.c	Fri Oct  9 11:56:59 1998
@@ -3,7 +3,7 @@
  *
  * Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
  *
- * Some parts are based on hd.c by Linus Thorvalds
+ * Some parts are based on hd.c by Linus Torvalds
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive for
diff -u --recursive --new-file v2.1.125/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.1.125/linux/drivers/block/floppy.c	Mon Oct  5 13:13:38 1998
+++ linux/drivers/block/floppy.c	Mon Oct 12 14:13:54 1998
@@ -153,6 +153,11 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
+/*
+ * PS/2 floppies have much slower step rates than regular floppies.
+ * It's been recommended that take about 1/4 of the default speed
+ * in some more extreme cases.
+ */
 static int slow_floppy = 0;
 
 #include <asm/dma.h>
@@ -354,7 +359,7 @@
       0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/
 
 {{2,  500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6,  83, 3*HZ, 17, {3,1,2,0,2}, 0,
-      0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/
+      0, { 2, 5, 6,23,10,20,12, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/
 
 {{3,  250, 16, 16, 3000,    1*HZ, 3*HZ,  0, SEL_DLY, 5,  83, 3*HZ, 20, {3,1,2,0,2}, 0,
       0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/
@@ -1051,6 +1056,7 @@
 static void setup_DMA(void)
 {
 	unsigned long flags;
+	unsigned long f;
 
 #ifdef FLOPPY_SANITY_CHECK
 	if (raw_cmd->length == 0){
@@ -1072,17 +1078,20 @@
 	}
 #endif
 	INT_OFF;
+	f=claim_dma_lock();
 	fd_disable_dma();
 #ifdef fd_dma_setup
 	if(fd_dma_setup(raw_cmd->kernel_data, raw_cmd->length, 
 			(raw_cmd->flags & FD_RAW_READ)?
 			DMA_MODE_READ : DMA_MODE_WRITE,
 			FDCS->address) < 0) {
+		release_dma_lock(f);
 		INT_ON;
 		cont->done(0);
 		FDCS->reset=1;
 		return;
 	}
+	release_dma_lock(f);
 #else	
 	fd_clear_dma_ff();
 	fd_cacheflush(raw_cmd->kernel_data, raw_cmd->length);
@@ -1092,6 +1101,7 @@
 	fd_set_dma_count(raw_cmd->length);
 	virtual_dma_port = FDCS->address;
 	fd_enable_dma();
+	release_dma_lock(f);
 #endif
 	INT_ON;
 	floppy_disable_hlt();
@@ -1694,11 +1704,15 @@
 {
 	void (*handler)(void) = DEVICE_INTR;
 	int do_print;
+	unsigned long f;
 
 	lasthandler = handler;
 	interruptjiffies = jiffies;
 
+	f=claim_dma_lock();
 	fd_disable_dma();
+	release_dma_lock(f);
+	
 	floppy_enable_hlt();
 	CLEAR_INTR;
 	if (fdc >= N_FDC || FDCS->address == -1){
@@ -1779,13 +1793,18 @@
  */
 static void reset_fdc(void)
 {
+	unsigned long flags;
+	
 	SET_INTR(reset_interrupt);
 	FDCS->reset = 0;
 	reset_fdc_info(0);
 
 	/* Pseudo-DMA may intercept 'reset finished' interrupt.  */
 	/* Irrelevant for systems with true DMA (i386).          */
+	
+	flags=claim_dma_lock();
 	fd_disable_dma();
+	release_dma_lock(flags);
 
 	if (FDCS->version >= FDC_82072A)
 		fd_outb(0x80 | (FDCS->dtr &3), FD_STATUS);
@@ -1844,12 +1863,18 @@
 
 static void floppy_shutdown(void)
 {
+	unsigned long flags;
+	
 	if (!initialising)
 		show_floppy();
 	cancel_activity();
 
 	floppy_enable_hlt();
+	
+	flags=claim_dma_lock();
 	fd_disable_dma();
+	release_dma_lock(flags);
+	
 	/* avoid dma going to a random drive after shutdown */
 
 	if (!initialising)
@@ -1897,6 +1922,8 @@
 
 static void floppy_ready(void)
 {
+	unsigned long flags;
+	
 	CHECK_RESET;
 	if (start_motor(floppy_ready)) return;
 	if (fdc_dtr()) return;
@@ -1915,8 +1942,12 @@
 #ifdef fd_chose_dma_mode
 	if ((raw_cmd->flags & FD_RAW_READ) || 
 	    (raw_cmd->flags & FD_RAW_WRITE))
+	{
+		flags=claim_dma_lock();
 		fd_chose_dma_mode(raw_cmd->kernel_data,
 				  raw_cmd->length);
+		release_dma_lock(flags);
+	}
 #endif
 
 	if (raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){
@@ -3020,7 +3051,12 @@
 			raw_cmd->reply[i] = reply_buffer[i];
 
 		if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE))
+		{
+			unsigned long flags;
+			flags=claim_dma_lock();
 			raw_cmd->length = fd_get_dma_residue();
+			release_dma_lock(flags);
+		}
 		
 		if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) &&
 		    (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0)))
@@ -4025,6 +4061,7 @@
 	{ "usefifo", 0, &no_fifo, 0, 0 },
 
 	{ "cmos", set_cmos, 0, 0, 0 },
+	{ "slow", 0, &slow_floppy, 1, 0 },
 
 	{ "unexpected_interrupts", 0, &print_unex, 1, 0 },
 	{ "no_unexpected_interrupts", 0, &print_unex, 0, 0 },
@@ -4036,15 +4073,6 @@
 	int i;
 	int param;
 	if (str) {
-	/*
-	 * PS/2 floppies have much slower step rates than regular floppies.
-	 * It's been recommended that take about 1/4 of the default speed
-	 * in some more extreme cases.
-	 */
-	if( strcmp(str,"slow") == 0) {
-		slow_floppy = 1;
-		return;
-	}
 		for (i=0; i< ARRAY_SIZE(config_params); i++){
 			if (strcmp(str,config_params[i].name) == 0){
 				if (ints[0])
@@ -4125,6 +4153,8 @@
 #endif
 
 	if (floppy_grab_irq_and_dma()){
+		del_timer(&fd_timeout);
+		blk_dev[MAJOR_NR].request_fn = NULL;
 		unregister_blkdev(MAJOR_NR,"fd");
 		del_timer(&fd_timeout);
 		return -EBUSY;
@@ -4176,7 +4206,8 @@
 	current_drive = 0;
 	floppy_release_irq_and_dma();
 	initialising=0;
-	if (have_no_fdc) {
+	if (have_no_fdc) 
+	{
 		DPRINT("no floppy controllers found\n");
 		unregister_blkdev(MAJOR_NR,"fd");		
 	}
diff -u --recursive --new-file v2.1.125/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.1.125/linux/drivers/block/genhd.c	Mon Sep 28 10:51:33 1998
+++ linux/drivers/block/genhd.c	Tue Oct 20 13:52:01 1998
@@ -71,7 +71,7 @@
 {
 	unsigned int part;
 	const char *maj = hd->major_name;
-	char unit = (minor >> hd->minor_shift) + 'a';
+	int unit = (minor >> hd->minor_shift) + 'a';
 
 	/*
 	 * IDE devices use multiple major numbers, but the drives
@@ -91,8 +91,19 @@
 			unit += 2;
 		case IDE0_MAJOR:
 			maj = "hd";
+			break;
 	}
 	part = minor & ((1 << hd->minor_shift) - 1);
+	if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
+		unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
+		if (unit > 'z') {
+			unit -= 'z' + 1;
+			sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
+			if (part)
+				sprintf(buf + 4, "%d", part);
+			return buf;
+		}
+	}
 	if (part)
 		sprintf(buf, "%s%c%d", maj, unit, part);
 	else
@@ -647,6 +658,74 @@
 
 #endif /* CONFIG_SUN_PARTITION */
 
+#ifdef CONFIG_SGI_PARTITION
+
+static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
+{
+	int i, csum;
+	unsigned int *ui;
+	struct buffer_head *bh;
+	struct sgi_disklabel {
+		int magic_mushroom;         /* Big fat spliff... */
+		short root_part_num;        /* Root partition number */
+		short swap_part_num;        /* Swap partition number */
+		char boot_file[16];         /* Name of boot file for ARCS */
+		unsigned char _unused0[48]; /* Device parameter useless crapola.. */
+		struct sgi_volume {
+			char name[8];       /* Name of volume */
+			int  block_num;     /* Logical block number */
+			int  num_bytes;     /* How big, in bytes */
+		} volume[15];
+		struct sgi_partition {
+			int num_blocks;     /* Size in logical blocks */
+			int first_block;    /* First logical block */
+			int type;           /* Type of this partition */
+		} partitions[16];
+		int csum;                   /* Disk label checksum */
+		int _unused1;               /* Padding */
+	} *label;
+	struct sgi_partition *p;
+#define SGI_LABEL_MAGIC 0x0be5a941
+
+	if(!(bh = bread(dev, 0, 1024))) {
+		printk("Dev %s: unable to read partition table\n", kdevname(dev));
+		return -1;
+	}
+	label = (struct sgi_disklabel *) bh->b_data;
+	p = &label->partitions[0];
+	if(label->magic_mushroom != SGI_LABEL_MAGIC) {
+		printk("Dev %s SGI disklabel: bad magic %08x\n",
+		       kdevname(dev), label->magic_mushroom);
+		brelse(bh);
+		return 0;
+	}
+	ui = ((unsigned int *) (label + 1)) - 1;
+	for(csum = 0; ui >= ((unsigned int *) label);)
+		csum += *ui--;
+	if(csum) {
+		printk("Dev %s SGI disklabel: csum bad, label corrupted\n",
+		       kdevname(dev));
+		brelse(bh);
+		return 0;
+	}
+	/* All SGI disk labels have 16 partitions, disks under Linux only
+	 * have 15 minor's.  Luckily there are always a few zero length
+	 * partitions which we don't care about so we never overflow the
+	 * current_minor.
+	 */
+	for(i = 0; i < 16; i++, p++) {
+		if(!(p->num_blocks))
+			continue;
+		add_partition(hd, current_minor, p->first_block, p->num_blocks);
+		current_minor++;
+	}
+	printk("\n");
+	brelse(bh);
+	return 1;
+}
+
+#endif
+
 #ifdef CONFIG_AMIGA_PARTITION
 #include <asm/byteorder.h>
 #include <linux/affs_hardblocks.h>
@@ -1037,6 +1116,10 @@
 #endif
 #ifdef CONFIG_MAC_PARTITION
 	if (mac_partition(hd, dev, first_sector))
+		return;
+#endif
+#ifdef CONFIG_SGI_PARTITION
+	if(sgi_partition(hd, dev, first_sector))
 		return;
 #endif
 	printk(" unknown partition table\n");
diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- v2.1.125/linux/drivers/block/ide-cd.c	Thu Sep 17 17:53:35 1998
+++ linux/drivers/block/ide-cd.c	Wed Oct 21 16:03:04 1998
@@ -2600,6 +2600,8 @@
 		return 0;
 	}
 	else {
+		int was_locked;
+
 		if (
 #if ! STANDARD_ATAPI
 		    CDROM_STATE_FLAGS (drive)->sanyo_slot == 0 &&
@@ -2608,6 +2610,10 @@
 			return -ENOMEDIUM;
 		}
 
+		was_locked = CDROM_STATE_FLAGS (drive)->door_locked;
+		if (was_locked)
+			(void) cdrom_lockdoor (drive, 0, NULL);
+
 		stat = cdrom_load_unload (drive, slot, NULL);
 		cdrom_saw_media_change (drive);
 		if (stat)
@@ -2621,10 +2627,12 @@
 			stat = cdrom_read_toc (drive, &my_reqbuf);
 			if (stat)
 				return stat;
-			return slot;
 		}
-		else
-			return stat;
+
+		if (was_locked)
+			(void) cdrom_lockdoor (drive, 1, NULL);
+
+		return stat;
 	}
 }
 
diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-dma.c linux/drivers/block/ide-dma.c
--- v2.1.125/linux/drivers/block/ide-dma.c	Thu Sep 17 17:53:35 1998
+++ linux/drivers/block/ide-dma.c	Mon Oct 12 11:42:59 1998
@@ -344,6 +344,21 @@
 	}
 }
 
+/*
+ * Needed for allowing full modular support of ide-driver
+ */
+int ide_release_dma (ide_hwif_t *hwif)
+{
+	if (hwif->dmatable) {
+		clear_page((unsigned long)hwif->dmatable);	/* clear PRD 1st */
+		free_page((unsigned long)hwif->dmatable);	/* free PRD 2nd */
+	}
+	if ((hwif->dma_extra) && (hwif->channel == 0))
+		release_region((hwif->dma_base + 16), hwif->dma_extra);
+	release_region(hwif->dma_base, 8);
+	return 1;
+}
+
 __initfunc(void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports))
 {
 	static unsigned long dmatable = 0;
@@ -404,6 +419,7 @@
 		if (extra) /* PDC20246 & HPT343 */
 			request_region(dma_base+16, extra, name);
 		dma_base += hwif->channel ? 8 : 0;
+		hwif->dma_extra = extra;
 		if (inb(dma_base+2) & 0x80) {
 			printk("%s: simplex device:  DMA disabled\n", name);
 			dma_base = 0;
diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
--- v2.1.125/linux/drivers/block/ide-floppy.c	Thu Sep 17 17:53:35 1998
+++ linux/drivers/block/ide-floppy.c	Wed Oct 14 20:24:55 1998
@@ -868,7 +868,7 @@
 
 		if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) {	/* Error detected */
 #if IDEFLOPPY_DEBUG_LOG
-			printk (KERN_INFO "ide-floppy: %s: I/O error, ",drive->name);
+			printk (KERN_INFO "ide-floppy: %s: I/O error\n",drive->name);
 #endif /* IDEFLOPPY_DEBUG_LOG */
 			rq->errors++;
 			if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
@@ -1057,6 +1057,7 @@
 	pc->c[0] = IDEFLOPPY_READ_CAPACITY_CMD;
 	pc->c[7] = 255;
 	pc->c[8] = 255;
+	pc->request_transfer = 255;
 }
 
 /*
diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c
--- v2.1.125/linux/drivers/block/ide-pci.c	Mon Oct  5 13:13:38 1998
+++ linux/drivers/block/ide-pci.c	Mon Oct 12 11:42:59 1998
@@ -117,16 +117,6 @@
 	unsigned int		extra;
 } ide_pci_device_t;
 
-#ifdef CONFIG_BLK_DEV_OFFBOARD
-#  define ON_BOARD		0
-#  define OFF_BOARD		1
-#  define NEVER_BOARD		0
-#else /* CONFIG_BLK_DEV_OFFBOARD */
-#  define ON_BOARD		1
-#  define OFF_BOARD		0
-#  define NEVER_BOARD		0
-#endif /* CONFIG_BLK_DEV_OFFBOARD */
-
 static ide_pci_device_t ide_pci_chipsets[] __initdata = {
 	{DEVID_PIIXa,	"PIIX",		NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
 	{DEVID_PIIXb,	"PIIX",		NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.1.125/linux/drivers/block/ide.c	Fri Oct  9 13:27:07 1998
+++ linux/drivers/block/ide.c	Mon Oct 12 11:42:59 1998
@@ -1737,6 +1737,11 @@
 	else
 		hwgroup->hwif = HWIF(hwgroup->drive);
 
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	if (hwif->dma_base)
+		(void) ide_release_dma(hwif);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
 	/*
 	 * Remove us from the kernel's knowledge
 	 */
@@ -2998,8 +3003,13 @@
 {
 	int index;
 
-	for (index = 0; index < MAX_HWIFS; ++index)
+	for (index = 0; index < MAX_HWIFS; ++index) {
 		ide_unregister(index);
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		if (ide_hwifs[index].dma_base)
+			(void) ide_release_dma(&ide_hwifs[index]);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	}
 #ifdef CONFIG_PROC_FS
 	proc_ide_destroy();
 #endif
diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide.h linux/drivers/block/ide.h
--- v2.1.125/linux/drivers/block/ide.h	Fri Oct  9 13:27:07 1998
+++ linux/drivers/block/ide.h	Fri Oct 23 10:18:55 1998
@@ -328,6 +328,7 @@
 	unsigned long	*dmatable;	/* dma physical region descriptor table */
 	struct hwif_s	*mate;		/* other hwif from same PCI chip */
 	unsigned long	dma_base;	/* base addr for dma ports */
+	unsigned	dma_extra;	/* extra addr for dma ports */
 	unsigned long	config_data;	/* for use by chipset-specific code */
 	unsigned long	select_data;	/* for use by chipset-specific code */
 	struct proc_dir_entry *proc;	/* /proc/ide/ directory entry */
@@ -725,6 +726,14 @@
 int ide_replace_subdriver(ide_drive_t *drive, const char *driver);
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
+#define ON_BOARD		1
+#define NEVER_BOARD		0
+#ifdef CONFIG_BLK_DEV_OFFBOARD
+#  define OFF_BOARD		ON_BOARD
+#else /* CONFIG_BLK_DEV_OFFBOARD */
+#  define OFF_BOARD		NEVER_BOARD
+#endif /* CONFIG_BLK_DEV_OFFBOARD */
+
 unsigned long ide_find_free_region (unsigned short size) __init;
 void ide_scan_pcibus (void) __init;
 #endif
@@ -735,6 +744,7 @@
 void ide_dma_intr  (ide_drive_t *drive);
 int check_drive_lists (ide_drive_t *drive, int good_bad);
 int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
+int ide_release_dma (ide_hwif_t *hwif);
 void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init;
 unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init;
 #endif
diff -u --recursive --new-file v2.1.125/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.1.125/linux/drivers/block/ll_rw_blk.c	Mon Aug  3 12:45:44 1998
+++ linux/drivers/block/ll_rw_blk.c	Wed Oct 14 11:43:13 1998
@@ -93,8 +93,8 @@
  *		then 512 bytes is assumed.
  * else
  *		sector_size is hardsect_size[MAJOR][MINOR]
- * This is currently set by some scsi device and read by the msdos fs driver
- * This might be a some uses later.
+ * This is currently set by some scsi devices and read by the msdos fs driver.
+ * Other uses may appear later.
  */
 int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
 
@@ -297,8 +297,8 @@
 	int queue_new_request = 0;
 
 	switch (MAJOR(req->rq_dev)) {
-		case SCSI_DISK_MAJOR:
-			disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4;
+		case SCSI_DISK0_MAJOR:
+			disk_index = (MINOR(req->rq_dev) & 0x00f0) >> 4;
 			if (disk_index < 4)
 				drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
 			break;
@@ -479,7 +479,14 @@
 			break;
 		/* fall through */
 
-	     case SCSI_DISK_MAJOR:
+	     case SCSI_DISK0_MAJOR:
+	     case SCSI_DISK1_MAJOR:
+	     case SCSI_DISK2_MAJOR:
+	     case SCSI_DISK3_MAJOR:
+	     case SCSI_DISK4_MAJOR:
+	     case SCSI_DISK5_MAJOR:
+	     case SCSI_DISK6_MAJOR:
+	     case SCSI_DISK7_MAJOR:
 	     case SCSI_CDROM_MAJOR:
 
 		do {
diff -u --recursive --new-file v2.1.125/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.1.125/linux/drivers/block/loop.c	Thu Sep 17 17:53:35 1998
+++ linux/drivers/block/loop.c	Wed Oct 21 09:59:41 1998
@@ -21,9 +21,13 @@
  * Still To Fix:
  * - Advisory locking is ignored here. 
  * - Should use an own CAP_* category instead of CAP_SYS_ADMIN 
+ * - Should use the underlying filesystems/devices read function if possible
+ *   to support read ahead (and for write)
  */
 
 #include <linux/module.h>
+
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
 #include <linux/file.h>
@@ -304,7 +308,7 @@
 		file->f_version = ++event;
 	}
 
-	if ((file->f_mode & FMODE_WRITE) == 0 ||  file->f_op->write == NULL) {
+	if (file->f_op->write == NULL) {
 		printk(KERN_WARNING "loop: cannot create block - file not writeable\n");
 		return FALSE;
 	}
@@ -384,9 +388,9 @@
 			lo->lo_backing_file->f_op = file->f_op;
 			lo->lo_backing_file->private_data = file->private_data;
 
-			error = get_write_access(inode); /* cannot fail */
+			error = get_write_access(inode);
 			if (error) {
-				fput(lo->lo_backing_file);
+				put_filp(lo->lo_backing_file);
 				lo->lo_backing_file = NULL;
 			}
 		}
@@ -402,8 +406,7 @@
 		set_device_ro(dev, 0);
 	}
 
-	lo->lo_dentry = file->f_dentry;
-	lo->lo_dentry->d_count++;
+	lo->lo_dentry = dget(file->f_dentry);
 	lo->transfer = NULL;
 	lo->ioctl = NULL;
 	figure_loop_size(lo);
@@ -420,15 +423,32 @@
 {
 	int err = 0; 
 	if (lo->lo_encrypt_type) {
-		if (xfer_funcs[lo->lo_encrypt_type] && 
-		    xfer_funcs[lo->lo_encrypt_type]->release) { 
-			err = xfer_funcs[lo->lo_encrypt_type]->release(lo);
-		}
+		struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type]; 
+		if (xfer && xfer->release)
+			err = xfer->release(lo); 
+		if (xfer && xfer->unlock)
+			xfer->unlock(lo); 
 		lo->lo_encrypt_type = 0;
 	}
 	return err;
 }
 
+static int loop_init_xfer(struct loop_device *lo, int type,struct loop_info *i)
+{
+	int err = 0; 
+	if (type) {
+		struct loop_func_table *xfer = xfer_funcs[type]; 
+		if (xfer->init)
+			err = xfer->init(lo, i);
+		if (!err) { 
+			lo->lo_encrypt_type = type;
+			if (xfer->lock)
+				xfer->lock(lo);
+		}
+	}
+	return err;
+}  
+
 static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
 {
 	struct dentry *dentry = lo->lo_dentry;
@@ -449,6 +469,7 @@
 		dput(dentry);
 	}
 
+	loop_release_xfer(lo);
 	lo->transfer = NULL;
 	lo->ioctl = NULL;
 	lo->lo_device = 0;
@@ -481,17 +502,14 @@
 	type = info.lo_encrypt_type; 
 	if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
 		return -EINVAL;
-	err = loop_release_xfer(lo); 
-	if (err)
-		return err;
-	if (xfer_funcs[type]->init) 
-		err = xfer_funcs[type]->init(lo, &info);
+	err = loop_release_xfer(lo);
+	if (!err) 
+		err = loop_init_xfer(lo, type, &info);
 	if (err)
-		return err;
+		return err;	
 
 	lo->lo_offset = info.lo_offset;
 	strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);
-	lo->lo_encrypt_type = type; 
 
 	lo->transfer = xfer_funcs[type]->transfer;
 	lo->ioctl = xfer_funcs[type]->ioctl;
@@ -572,7 +590,8 @@
 static int lo_open(struct inode *inode, struct file *file)
 {
 	struct loop_device *lo;
-	int	dev;
+	int	dev, type;
+
 
 	if (!inode)
 		return -EINVAL;
@@ -585,6 +604,10 @@
 		return -ENODEV;
 	}
 	lo = &loop_dev[dev];
+
+	type = lo->lo_encrypt_type; 
+	if (type && xfer_funcs[type] && xfer_funcs[type]->lock)
+		xfer_funcs[type]->lock(lo);
 	lo->lo_refcnt++;
 	MOD_INC_USE_COUNT;
 	return 0;
@@ -593,7 +616,7 @@
 static int lo_release(struct inode *inode, struct file *file)
 {
 	struct loop_device *lo;
-	int	dev, err = 0;
+	int	dev, err;
 
 	if (!inode)
 		return 0;
@@ -605,14 +628,14 @@
 	if (dev >= MAX_LOOP)
 		return 0;
 	err = fsync_dev(inode->i_rdev);
-	if (err < 0) 
-		return err; 
 	lo = &loop_dev[dev];
 	if (lo->lo_refcnt <= 0)
 		printk(KERN_ERR "lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);
 	else  {
-		if (--lo->lo_refcnt == 0) 
-			err = loop_release_xfer(lo);
+		int type  = lo->lo_encrypt_type;
+		--lo->lo_refcnt;
+		if (xfer_funcs[type] && xfer_funcs[type]->unlock)
+			xfer_funcs[type]->unlock(lo);
 		MOD_DEC_USE_COUNT;
 	}
 	return err;
@@ -646,11 +669,20 @@
 	return 0; 
 }
 
-/* Usage checking must be done by the caller - usually with MOD_INC/DEC_* */  
 int loop_unregister_transfer(int number)
 {
+	struct loop_device *lo; 
+
 	if ((unsigned)number >= MAX_LO_CRYPT)
 		return -EINVAL; 
+	for (lo = &loop_dev[0]; lo < &loop_dev[MAX_LOOP]; lo++) { 
+		int type = lo->lo_encrypt_type;
+		if (type == number) { 
+			xfer_funcs[type]->release(lo);
+			lo->transfer = NULL; 
+			lo->lo_encrypt_type = 0; 
+		}
+	}
 	xfer_funcs[number] = NULL; 
 	return 0; 
 }
diff -u --recursive --new-file v2.1.125/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.1.125/linux/drivers/block/xd.c	Wed Aug 26 11:37:35 1998
+++ linux/drivers/block/xd.c	Fri Oct  9 11:56:59 1998
@@ -533,6 +533,8 @@
 /* xd_setup_dma: set up the DMA controller for a data transfer */
 static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
 {
+	unsigned long f;
+	
 	if (nodma)
 		return (PIO_MODE);
 	if (((u_int) buffer & 0xFFFF0000) != (((u_int) buffer + count) & 0xFFFF0000)) {
@@ -541,11 +543,15 @@
 #endif /* DEBUG_OTHER */
 		return (PIO_MODE);
 	}
+	
+	f=claim_dma_lock();
 	disable_dma(xd_dma);
 	clear_dma_ff(xd_dma);
 	set_dma_mode(xd_dma,mode);
 	set_dma_addr(xd_dma,(u_int) buffer);
 	set_dma_count(xd_dma,count);
+	
+	release_dma_lock(f);
 
 	return (DMA_MODE);			/* use DMA and INT */
 }
@@ -597,13 +603,22 @@
 
 static inline u_int xd_wait_for_IRQ (void)
 {
+	unsigned long flags;
 	xd_watchdog_int.expires = jiffies + 8 * HZ;
 	add_timer(&xd_watchdog_int);
+	
+	flags=claim_dma_lock();
 	enable_dma(xd_dma);
+	release_dma_lock(flags);
+	
 	sleep_on(&xd_wait_int);
 	del_timer(&xd_watchdog_int);
 	xdc_busy = 0;
+	
+	flags=claim_dma_lock();
 	disable_dma(xd_dma);
+	release_dma_lock(flags);
+	
 	if (xd_error) {
 		printk("xd: missed IRQ - command aborted\n");
 		xd_error = 0;
diff -u --recursive --new-file v2.1.125/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v2.1.125/linux/drivers/cdrom/cdu31a.c	Thu Sep 17 17:53:35 1998
+++ linux/drivers/cdrom/cdu31a.c	Sat Oct 17 15:52:18 1998
@@ -3020,18 +3020,20 @@
          sony_get_toc();
          if (!sony_toc_read)
          {
-            return -EIO;
+         	return -EIO;
          }
-         
+
+	 if(copy_from_user(&ra, (char *) arg, sizeof(ra)))
+	 	return -EFAULT;
+
          if (ra.nframes == 0)
          {
-            return 0;
+         	return 0;
          }
 
          i=verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes);
          if(i<0)
          	return i;
-         copy_from_user(&ra, (char *) arg, sizeof(ra));
 
          if (ra.addr_format == CDROM_LBA)
          {
diff -u --recursive --new-file v2.1.125/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.1.125/linux/drivers/char/Config.in	Fri Oct  9 13:27:07 1998
+++ linux/drivers/char/Config.in	Fri Oct  9 11:44:19 1998
@@ -56,7 +56,7 @@
 	tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE
 	tristate 'Logitech busmouse support' CONFIG_BUSMOUSE
 	tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE
-	tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+	bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
 	tristate 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
 	tristate 'PC110 digitizer pad support' CONFIG_PC110_PAD
 fi
diff -u --recursive --new-file v2.1.125/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.1.125/linux/drivers/char/Makefile	Fri Oct  9 13:27:07 1998
+++ linux/drivers/char/Makefile	Fri Oct  9 11:44:19 1998
@@ -184,14 +184,6 @@
   endif
 endif
 
-ifeq ($(CONFIG_PSMOUSE),y)
-L_OBJS += psaux.o
-else
-  ifeq ($(CONFIG_PSMOUSE),m)
-  M_OBJS += psaux.o
-  endif
-endif
-
 ifeq ($(CONFIG_SOFT_WATCHDOG),y)
 L_OBJS += softdog.o
 else
diff -u --recursive --new-file v2.1.125/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.1.125/linux/drivers/char/bttv.c	Thu Sep 17 17:53:36 1998
+++ linux/drivers/char/bttv.c	Sat Oct 17 15:52:18 1998
@@ -28,11 +28,10 @@
       composite source from a satellite tuner can deliver different norms
       depending on tuned channel
     * mmap VBI data?
-    * use new PCI routines
     * fix RAW Composite grabbing for NTSC 
-    * allow for different VDELAY in RAW grabbing?
+    * fix VBI reading double frames when grabbing is active
+    * allow for different VDELAYs
     * extra modules for tda9850, tda8425, any volunteers???
-    * support 15bpp
 */
 
 #include <linux/module.h>
@@ -80,12 +79,20 @@
 
 static unsigned int vidmem=0;   /* manually set video mem address */
 static int triton1=0;
+#ifndef USE_PLL
+/* 0=no pll, 1=28MHz, 2=34MHz */
+#define USE_PLL 0
+#endif
+#ifndef CARD_DEFAULT
+/* card type (see bttv.h) 0=autodetect */
+#define CARD_DEFAULT 0
+#endif
 
 static unsigned int remap[BTTV_MAX];    /* remap Bt848 */
 static unsigned int radio[BTTV_MAX];
-static unsigned int card[BTTV_MAX] = { 0, 0, 
-                                       0, 0 };
-static unsigned int pll[BTTV_MAX] = { 0, 0, 0, 0 };          
+static unsigned int card[BTTV_MAX] = { CARD_DEFAULT, CARD_DEFAULT, 
+                                       CARD_DEFAULT, CARD_DEFAULT };
+static unsigned int pll[BTTV_MAX] = { USE_PLL, USE_PLL, USE_PLL, USE_PLL };
 
 static int bttv_num;			/* number of Bt848s in use */
 static struct bttv bttvs[BTTV_MAX];
@@ -96,9 +103,8 @@
     { btwrite((CTRL<<1)|(DATA), BT848_I2C); udelay(I2C_DELAY); }
 #define I2C_GET()   (btread(BT848_I2C)&1)
 
-#define AUDIO_MUTE_DELAY 10000
-#define FREQ_CHANGE_DELAY 20000
 #define EEPROM_WRITE_DELAY 20000
+#define BURSTOFFSET 76
 
 /*******************************/
 /* Memory management functions */
@@ -344,7 +350,6 @@
 void attach_inform(struct i2c_bus *bus, int id)
 {
         struct bttv *btv = (struct bttv*)bus->data;
-	int tunertype;
         
 	switch (id) 
         {
@@ -354,12 +359,9 @@
         	case I2C_DRIVERID_TUNER:
 			btv->have_tuner = 1;
 			if (btv->tuner_type != -1) 
-			{
-				tunertype=btv->tuner_type;
  				i2c_control_device(&(btv->i2c), 
                                                    I2C_DRIVERID_TUNER,
-                                                   TUNER_SET_TYPE,&tunertype);
- 			}
+                                                   TUNER_SET_TYPE,&btv->tuner_type);
 			break;
 	}
 }
@@ -433,9 +435,10 @@
         {0, 0xc00, 0x800, 0x400, 0xc00, 0}},
         /* TurboTV */
         { 3, 0, 2, 3, { 2, 3, 1, 1}, { 1, 1, 2, 3, 0}},
-        /* Newer Hauppauge */
-	{ 2, 0, 2, 1, { 2, 0, 0, 0}, {0, 1, 2, 3, 4}},
-  
+	/* Newer Hauppauge (bt878) */
+	{ 3, 0, 2, 7, { 2, 0, 1, 1}, { 0, 1, 2, 3, 4}},
+	/* MIRO PCTV pro */
+	{ 3, 0, 2, 65551, { 2, 3, 1, 1}, {1,65537, 0, 0,10}},
 };
 #define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
 
@@ -546,32 +549,36 @@
 static int set_pll(struct bttv *btv)
 {
         int i;
-        unsigned long tv;
+	unsigned long tv;
 
         if (!btv->pll.pll_crystal)
-		return 0;
-        if ((btread(BT848_IFORM)&btv->pll.pll_crystal))
-        {
-                /* printk ("switching PLL off\n");*/
+                return 0;
+
+        if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
+                /* no PLL needed */
+                if (btv->pll.pll_current == 0) {
+                        /* printk ("bttv%d: PLL: is off\n",btv->nr); */
+                        return 0;
+                }
+                printk ("bttv%d: PLL: switching off\n",btv->nr);
                 btwrite(0x00,BT848_TGCTRL);
                 btwrite(0x00,BT848_PLL_XCI);
-                btv->pll.pll_crystal&=~2;
+                btv->pll.pll_current = 0;
                 return 0;
         }
-        
-        /* do not set pll again if already active */
-        if (btv->pll.pll_crystal&2)
+
+        if (btv->pll.pll_ofreq == btv->pll.pll_current) {
+                /* printk("bttv%d: PLL: no change required\n",btv->nr); */
                 return 1;
+        }
         
-        /* printk ("setting PLL for PAL/SECAM\n");*/
+        printk("bttv%d: PLL: %d => %d ... ",btv->nr,
+               btv->pll.pll_ifreq, btv->pll.pll_ofreq);
 
 	set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
 
-	/*
-	 *	Let other people run while the PLL stabilizes
-	 */
-	
-	tv=jiffies+HZ/10;	/* .1 seconds */
+	/*  Let other people run while the PLL stabilizes */
+	tv=jiffies+HZ/10;       /* .1 seconds */
 	do
 	{
 		schedule();
@@ -585,11 +592,14 @@
                 else
                 {
                         btwrite(0x08,BT848_TGCTRL);
-                        btv->pll.pll_crystal|=2;
-                        return 1;            
+                        btv->pll.pll_current = btv->pll.pll_ofreq;
+                        printk("ok\n");
+                        return 1;
                 }
-                udelay(10000);
+                mdelay(10);
         }
+        btv->pll.pll_current = 0;
+        printk("oops\n");
         return -1;
 }
 
@@ -623,8 +633,9 @@
 
 #define VBIBUF_SIZE 65536
 
-/* Maximum sample number per VBI line is 2044, can NTSC deliver this? 
+/* Maximum sample number per VBI line is 2044, NTSC delivers 1600
    Note that we write 2048-aligned to keep alignment to memory pages 
+   VBI_RISC is written so that it applies to either 2044 or 1600
 */
 #define VBI_SPL 2044
 
@@ -684,7 +695,7 @@
        BT848_COLOR_FMT_YCrCb422,
        BT848_COLOR_FMT_YCrCb411,
 };
-#define PALETTEFMT_MAX 15
+#define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))
 
 static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
                             unsigned int *re, unsigned int *vbuf)
@@ -783,199 +794,102 @@
 	return 0;
 }
 
-/* does this really make a difference ???? */
-#define BURST_MAX 4096
-
-static inline void write_risc_segment(unsigned int **rp, unsigned long line_adr, unsigned int command,
-			int *x, uint dx, uint bpp, uint width)
+static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int h)
 {
-        unsigned int flags, len;
-  
-	if (!dx)
-                return;
-	len=dx*bpp;
-
-#ifdef LIMIT_DMA
-	if (command==BT848_RISC_WRITEC)
-	{
-                unsigned int dx2=BURST_MAX/bpp;
-		while (len>BURST_MAX)
-		{
-	                write_risc_segment(rp, line_adr, command,
-					   &x,dx2, bpp, width);
-			dx-=dx2;
-			len=dx*bpp;
-		}
-	}
-#endif
-
-	/* mask upper 8 bits for 24+8 bit overlay modes */
-	flags = ((bpp==4) ? BT848_RISC_BYTE3 : 0);
-	
-	if (*x==0) 
-	{
-                if (command==BT848_RISC_SKIP) 
-		{
-	                if (dx<width)
-			{
-		                flags|=BT848_RISC_BYTE_ALL;
-				command=BT848_RISC_WRITE;
-			}
-		}
-		else
-	                if (command==BT848_RISC_WRITEC)
-                                command=BT848_RISC_WRITE;
-		flags|=BT848_RISC_SOL;
-        }
-	if (*x+dx==width)
-                flags|=BT848_RISC_EOL;
-	*((*rp)++)=command|flags|len;
-	if (command==BT848_RISC_WRITE)
-                *((*rp)++)=line_adr+*x*bpp;
-	*x+=dx;
+	int i, j;
+	/* bitmap is fixed width, 128 bytes (1024 pixels represented) */
+	if (x < 0 || y < 0 || w < 0 || h < 0)	/* catch bad clips */
+		return;
+	/* out of range data should just fall through */
+	for (i = y; i < y + h && i < 625; i++)
+		for (j = x; j < x + w && j < 1024; j++)
+			clipmap[(i<<7)+(j>>3)] |= (1<<(j&7));
 }
 
 static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
 {
-	int i,t;
-	int yy, y, x, dx;
-	struct video_clip first, *cur, *cur2, *nx, first2, *prev, *nx2;
-	int bpp, bpl, width, height, inter;
-	unsigned int **rp,*ro,*re;
+	int i, line, x, y, bpl, width, height, inter;
+	unsigned int bpp, dx, sx, **rp, *ro, *re, flags, len;
 	unsigned long adr;
-	int cx,cx2,cy,cy2;
+	unsigned char *clipmap, cbit, lastbit, outofmem;
 
 	inter=(btv->win.interlace&1)^1;
 	bpp=btv->win.bpp;
+	if (bpp==15)	/* handle 15bpp as 16bpp in calculations */
+		bpp++;
 	bpl=btv->win.bpl;
 	ro=btv->risc_odd;
 	re=btv->risc_even;
-	width=btv->win.width;
-	height=btv->win.height;
+	if((width=btv->win.width)>1023)
+		width = 1023;		/* sanity check */
+	if((height=btv->win.height)>625)
+		height = 625;		/* sanity check */
 	adr=btv->win.vidadr+btv->win.x*bpp+btv->win.y*bpl;
-
-	/* clip clipping rects against viewing window AND screen 
+	if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) {
+		/* can't clip, don't generate any risc code */
+		*(ro++)=BT848_RISC_JUMP;
+		*(ro++)=btv->bus_vbi_even;
+		*(re++)=BT848_RISC_JUMP;
+		*(re++)=btv->bus_vbi_odd;
+	}
+	if (ncr < 0) {	/* bitmap was pased */
+		memcpy(clipmap, (unsigned char *)cr, VIDEO_CLIPMAP_SIZE);
+	} else {	/* convert rectangular clips to a bitmap */
+		memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */
+		for (i=0; i<ncr; i++)
+			clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,
+				cr[i].width, cr[i].height);
+	}
+	/* clip against viewing window AND screen 
 	   so we do not have to rely on the user program
 	 */
-	cx=(btv->win.x<0) ? (-btv->win.x) : 0;
-	cy=(btv->win.y<0) ? (-btv->win.y) : 0;
-	cx2=(btv->win.x+width>btv->win.swidth) ? 
-	        (btv->win.swidth-btv->win.x) : width;
-	cy2=(btv->win.y+height>btv->win.sheight) ? 
-	        (btv->win.sheight-btv->win.y) : height;
-	first.next=NULL;
-	for (i=0; i<ncr; i++)
-	{
-                if ((t=cy-cr[i].y)>0)
-		{
-		        if (cr[i].height<=t)
-			        continue;
-                        cr[i].height-=t;
-			cr[i].y=cy;
-		} 
-		if ((t=cy2-cr[i].y)<cr[i].height) 
-		{
-		        if (t<=0)
-			        continue;
-			cr[i].height=t;
-		}
-                if ((t=cx-cr[i].x)>0)
-		{
-		        if (cr[i].width<=t)
-			        continue;
-                        cr[i].width-=t;
-			cr[i].x=cx;
-		} 
-		if ((t=cx2-cr[i].x)<cr[i].width) 
-		{
-		        if (t<=0)
-			        continue;
-			cr[i].width=t;
-		}
-	        cur=&first;
-		while ((nx=cur->next) && (cr[i].y > cur->next->y))
-		        cur=nx; 
-		cur->next=&(cr[i]);
-		cr[i].next=nx;
-	}
-	first2.next=NULL;
+	clip_draw_rectangle(clipmap,(btv->win.x+width>btv->win.swidth) ?
+		(btv->win.swidth-btv->win.x) : width, 0, 1024, 768);
+	clip_draw_rectangle(clipmap,0,(btv->win.y+height>btv->win.sheight) ?
+		(btv->win.sheight-btv->win.y) : height,1024,768);
+	if (btv->win.x<0)
+		clip_draw_rectangle(clipmap, 0, 0, -(btv->win.x), 768);
+	if (btv->win.y<0)
+		clip_draw_rectangle(clipmap, 0, 0, 1024, -(btv->win.y));
 	
 	*(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
 	*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
 	
-	/* loop through all lines */
-	for (yy=0; yy<(height<<inter); yy++) 
+	/* translate bitmap to risc code */
+        for (line=outofmem=0; line < (height<<inter) && !outofmem; line++)
         {
-                y=yy>>inter;
-                rp= (yy&1) ? &re : &ro;
-	  
-                /* remove rects with y2 > y */
-                if ((cur=first2.next))
-                {
-                        prev=&first2;
-                        do
-                        {
-                                if (cur->y+cur->height <= y) 
-                                        prev->next=cur->next;
-                                else
-                                        prev=cur;
-                        } 
-                        while ((cur=cur->next));
-                }
-                
-                /* add rect to second (x-sorted) list if rect.y == y  */
-                if ((cur=first.next))
-                {
-                        while ((cur) && (cur->y == y))
-                        { 
-                                first.next=cur->next;
-                                cur2=&first2;
-                                while ((nx2=cur2->next) && (cur->x > cur2->next->x)) 
-                                        cur2=nx2; 
-                                cur2->next=cur;
-                                cur->next=nx2;
-                                cur=first.next;
-                        }
-                }
-                x=0;
-                if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight))
-                        write_risc_segment(rp, adr, BT848_RISC_SKIP, &x,
-                                           width, bpp, width);
-                else 
-                {
-                        dx=cx;
-                        for (cur2=first2.next; cur2; cur2=cur2->next)
-                        {
-                                if (x+dx < cur2->x)
-                                {
-                                        write_risc_segment(rp, adr, BT848_RISC_SKIP,
-                                                           &x, dx, bpp, width);
-                                        dx=cur2->x-x;
-                                        write_risc_segment(rp, adr, BT848_RISC_WRITEC,
-                                                           &x, dx, bpp, width);
-                                        dx=cur2->width;
-                                }
-                                else if (x+dx < cur2->x+cur2->width) 
-                                        dx=cur2->x+cur2->width-x; 
-                        }
-                        if (cx2<width)
-                        {
-                                write_risc_segment(rp, adr, BT848_RISC_SKIP,
-                                                   &x, dx, bpp, width);
-                                write_risc_segment(rp, adr, BT848_RISC_WRITEC,
-                                                   &x, cx2-x, bpp, width);
-                                dx=width-x;
-                        }
-                        write_risc_segment(rp, adr, BT848_RISC_SKIP,
-                                           &x, dx, bpp, width);
-                        write_risc_segment(rp, adr, BT848_RISC_WRITEC,
-                                           &x, width-x, bpp, width);
-                }
-                if ((!inter)||(yy&1))
+		y = line>>inter;
+		rp= (line&1) ? &re : &ro;
+		lastbit=(clipmap[y<<7]&1);
+		for(x=dx=1,sx=0; x<=width && !outofmem; x++) {
+			cbit = (clipmap[(y<<7)+(x>>3)] & (1<<(x&7)));
+			if (x < width && !lastbit == !cbit)
+				dx++;
+			else {	/* generate the dma controller code */
+				len = dx * bpp;
+				flags = ((bpp==4) ? BT848_RISC_BYTE3 : 0);
+				flags |= ((!sx) ? BT848_RISC_SOL : 0);
+				flags |= ((sx + dx == width) ? BT848_RISC_EOL : 0);
+				if (!lastbit) {
+					*((*rp)++)=BT848_RISC_WRITE|flags|len;
+					*((*rp)++)=adr + bpp * sx;
+				} else
+					*((*rp)++)=BT848_RISC_SKIP|flags|len;
+				lastbit=cbit;
+				sx += dx;
+				dx = 1;
+				if (ro - btv->risc_odd > RISCMEM_LEN/2 - 16)
+					outofmem++;
+				if (re - btv->risc_even > RISCMEM_LEN/2 - 16)
+					outofmem++;
+			}
+		}
+		if ((!inter)||(line&1))
                         adr+=bpl;
 	}
-        
-        *(ro++)=BT848_RISC_JUMP;
+	vfree(clipmap);
+	/* outofmem flag relies on the following code to discard extra data */
+	*(ro++)=BT848_RISC_JUMP;
 	*(ro++)=btv->bus_vbi_even;
 	*(re++)=BT848_RISC_JUMP;
 	*(re++)=btv->bus_vbi_odd;
@@ -999,44 +913,51 @@
 	u8 adelay, bdelay, iform;
 	u32 scaledtwidth;
 	u16 hdelayx1, hactivex1;
-	u16 vdelay, fporch;
+	u16 vdelay;
+	u8 vbipack;
 };
 
 static struct tvnorm tvnorms[] = {
 	/* PAL-BDGHI */
-        /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
+        /* max pal/secam is actually 922, but 924 is divisible by 4 and 3! */
+	/* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
         { 35468950,
           924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
-          1135, 186, 924, 0x20},
+          1135, 178, 924, 0x20, 255},
 /*
         { 35468950, 
           768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
-	  944, 186, 922, 0x20},
+	  944, 178, 922, 0x20, 255},
 */
 	/* NTSC */
 	{ 28636363,
+          768, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
+          910, 128, 754, 0x1a, 144},
+/*
+	{ 28636363,
           640, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
-          780, 135, 754, 0x1a},
-	/* SECAM */
-	{ 28636363, 
-          640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
-	  780, 135, 754, 0x16},
+          780, 122, 754, 0x1a, 144},
+*/
+	/* SECAM - phase means nothing in SECAM, bdelay is useless */
+	{ 35468950, 
+          924, 576,1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
+	  1135, 178, 924, 0x20, 255},
 	/* PAL-M */
 	{ 28636363, 
           640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
-	  780, 135, 754, 0x16},
+	  780, 122, 754, 0x1a, 144},
 	/* PAL-N */
 	{ 35468950, 
           768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
-	  944, 186, 922, 0x20},
+	  944, 178, 922, 0x20, 255},
 	/* PAL-NC */
 	{ 35468950, 
           768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
-	  944, 186, 922, 0x20},
+	  944, 178, 922, 0x20, 255},
 	/* NTSC-Japan */
 	{ 28636363,
           640, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
-	  780, 135, 754, 0x16},
+	  780, 122, 754, 0x1a, 144},
 };
 #define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
 
@@ -1101,6 +1022,8 @@
 	btwrite(tvn->adelay, BT848_ADELAY);
 	btwrite(tvn->bdelay, BT848_BDELAY);
 	btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
+	btwrite(1, BT848_VBI_PACK_DEL);
+	btwrite(tvn->vbipack, BT848_VBI_PACK_SIZE);
 	
 	set_pll(btv);
 
@@ -1172,11 +1095,7 @@
 static void set_freq(struct bttv *btv, unsigned short freq)
 {
 	int fixme = freq; /* XXX */
-	int oldAudio = btv->audio;
 	
-	audio(btv, AUDIO_MUTE);
-	udelay(AUDIO_MUTE_DELAY);
-
 	if (btv->radio) 
 	{
 		if (btv->have_tuner)
@@ -1204,10 +1123,6 @@
 		}
 	}
 
- 	if (!(oldAudio & AUDIO_MUTE)) {
-		udelay(FREQ_CHANGE_DELAY);
-		audio(btv, AUDIO_UNMUTE);
-	}
 }
       
 
@@ -1243,10 +1158,15 @@
         So, better check the total image size ...
 */
 /*
-	if(mp->height>576 || mp->width>768)
+	if(mp->height>576 || mp->width>768+BURSTOFFSET)
 		return -EINVAL;
 */
-	if (mp->height*mp->width*fmtbppx2[mp->format&0x0f]/2>BTTV_MAX_FBUF)
+	if (mp->format >= PALETTEFMT_MAX)
+		return -EINVAL;
+ 	if (mp->height*mp->width*fmtbppx2[palette2fmt[mp->format]&0x0f]/2
+		> BTTV_MAX_FBUF)
+		return -EINVAL;
+	if (!palette2fmt[mp->format])
 		return -EINVAL;
  
 	/*
@@ -1264,31 +1184,28 @@
                 return -EAGAIN;*/
 	ro=btv->grisc+(((btv->grabcount++)&1) ? 4096 :0);
 	re=ro+2048;
-	btv->gwidth=mp->width;
-	btv->gheight=mp->height;
-
-	if (mp->format > PALETTEFMT_MAX)
-		return -EINVAL;
-	btv->gfmt=palette2fmt[mp->format];
-	if(btv->gfmt==0)
-		return -EINVAL;
-		
-	make_vrisctab(btv, ro, re, vbuf, btv->gwidth, btv->gheight, btv->gfmt);
+	make_vrisctab(btv, ro, re, vbuf, mp->width, mp->height, palette2fmt[mp->format]);
 	/* bt848_set_risc_jmps(btv); */
-	btor(3, BT848_CAP_CTL);
-	btor(3, BT848_GPIO_DMA_CTL);
         btv->frame_stat[mp->frame] = GBUFFER_GRABBING;
         if (btv->grabbing) {
+		btv->gfmt_next=palette2fmt[mp->format];
+		btv->gwidth_next=mp->width;
+		btv->gheight_next=mp->height;
 		btv->gro_next=virt_to_bus(ro);
 		btv->gre_next=virt_to_bus(re);
                 btv->grf_next=mp->frame;
         } else {
+		btv->gfmt=palette2fmt[mp->format];
+		btv->gwidth=mp->width;
+		btv->gheight=mp->height;
 		btv->gro=virt_to_bus(ro);
 		btv->gre=virt_to_bus(re);
                 btv->grf=mp->frame;
         }
 	if (!(btv->grabbing++)) 
 		btv->risc_jmp[12]=BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ;
+	btor(3, BT848_CAP_CTL);
+	btor(3, BT848_GPIO_DMA_CTL);
 	/* interruptible_sleep_on(&btv->capq); */
 	return 0;
 }
@@ -1519,6 +1436,7 @@
 			   &&v.norm!=VIDEO_MODE_SECAM)
 				return -EOPNOTSUPP;
 			btv->win.norm = v.norm;
+			make_vbitab(btv);
 			bt848_set_winsize(btv);
 			btv->channel=v.channel;
 			return 0;
@@ -1604,15 +1522,20 @@
 		case VIDIOCSWIN:
 		{
 			struct video_window vw;
-			struct video_clip *vcp;
+			struct video_clip *vcp = NULL;
 			int on;
 			
 			if(copy_from_user(&vw,arg,sizeof(vw)))
 				return -EFAULT;
 				
-			if(vw.flags)
+			if(vw.flags || vw.width < 16 || vw.height < 16) {
+				bt848_cap(btv,0);
 				return -EINVAL;
-				
+			}
+			if (btv->win.bpp < 4) {	/* adjust and align writes */
+				vw.x = (vw.x + 3) & ~3;
+				vw.width = (vw.width - 3) & ~3;
+			}
 			btv->win.x=vw.x;
 			btv->win.y=vw.y;
 			btv->win.width=vw.width;
@@ -1623,26 +1546,37 @@
 			else
 				btv->win.interlace=0;
 
-			on=(btv->cap&3)?1:0;
+			on=(btv->cap&3);
 			
 			bt848_cap(btv,0);
 			bt848_set_winsize(btv);
 
-			if(vw.clipcount>256)
-				return -EDOM;	/* Too many! */
-
 			/*
 			 *	Do any clips.
 			 */
-
-			vcp=vmalloc(sizeof(struct video_clip)*(vw.clipcount+4));
-			if(vcp==NULL)
-				return -ENOMEM;
-			if(vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount))
-				return -EFAULT;
-			make_clip_tab(btv,vcp, vw.clipcount);
-			vfree(vcp);
-			if(on && btv->win.vidadr!=0)
+			if(vw.clipcount<0) {
+				if((vcp=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL)
+					return -ENOMEM;
+				if(copy_from_user(vcp, vw.clips,
+					VIDEO_CLIPMAP_SIZE)) {
+					vfree(vcp);
+					return -EFAULT;
+				}
+			} else if (vw.clipcount) {
+				if((vcp=vmalloc(sizeof(struct video_clip)*
+					(vw.clipcount))) == NULL)
+					return -ENOMEM;
+				if(copy_from_user(vcp,vw.clips,
+					sizeof(struct video_clip)*
+					vw.clipcount)) {
+					vfree(vcp);
+					return -EFAULT;
+				}
+			}
+			make_clip_tab(btv, vcp, vw.clipcount);
+			if (vw.clipcount != 0)
+				vfree(vcp);
+			if(on && btv->win.vidadr != 0)
 				bt848_cap(btv,1);
 			return 0;
 		}
@@ -1700,7 +1634,9 @@
 				return -EPERM;
 			if(copy_from_user(&v, arg,sizeof(v)))
 				return -EFAULT;
-			if(v.depth!=8 && v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
+			if(v.depth!=8 && v.depth!=15 && v.depth!=16 && 
+				v.depth!=24 && v.depth!=32 && v.width > 16 &&
+				v.height > 16 && v.bytesperline > 16)
 				return -EINVAL;
 	                btv->win.vidadr=(unsigned long)v.base;
 			btv->win.sheight=v.height;
@@ -1801,9 +1737,8 @@
 	        case VIDIOCSYNC:
 			if(copy_from_user((void *)&i,arg,sizeof(int)))
 				return -EFAULT;
-                        if(i>1 || i<0)
-                                return -EINVAL;
-
+			if (i>1 || i<0)
+				return -EINVAL;
                         switch (btv->frame_stat[i]) {
                         case GBUFFER_UNUSED:
                                 return -EINVAL;
@@ -1832,24 +1767,25 @@
 				return -EFAULT;
 			break;
 
-                case BTTV_FIELDNR: 
+		case BTTV_FIELDNR:
 			if(copy_to_user((void *) arg, (void *) &btv->last_field, 
                                         sizeof(btv->last_field)))
 				return -EFAULT;
                         break;
-      
-                case BTTV_PLLSET: {
-                        struct bttv_pll_info p;
-                        if(!capable(CAP_SYS_ADMIN))
-                        	return -EPERM;
-                        if(copy_from_user(&p , (void *) arg, sizeof(btv->pll)))
-				return -EFAULT;
-                        btv->pll.pll_ifreq = p.pll_ifreq;
-                        btv->pll.pll_ofreq = p.pll_ofreq;
-                        btv->pll.pll_crystal = p.pll_crystal;
 
+		case BTTV_PLLSET:
+		{
+			struct bttv_pll_info p;
+			if(!capable(CAP_SYS_ADMIN))
+				return -EPERM;
+			if(copy_from_user(&p , (void *) arg, sizeof(btv->pll)))
+				return -EFAULT;
+			btv->pll.pll_ifreq = p.pll_ifreq;
+			btv->pll.pll_ofreq = p.pll_ofreq;
+			btv->pll.pll_crystal = p.pll_crystal;
 			break;
-                }						
+		}
+
 	        case VIDIOCMCAPTURE:
 		{
                         struct video_mmap vm;
@@ -1893,7 +1829,27 @@
 				return -EFAULT;
 			return 0;
 		}
-		
+
+	        case BTTV_BURST_ON:
+		{
+			tvnorms[0].scaledtwidth=1135-BURSTOFFSET-2;
+			tvnorms[0].hdelayx1=186-BURSTOFFSET;
+			return 0;
+		}
+
+		case BTTV_BURST_OFF:
+		{
+			tvnorms[0].scaledtwidth=1135;
+			tvnorms[0].hdelayx1=186;
+			return 0;
+		}
+
+		case BTTV_PICNR:
+		{
+			/* return picture */
+			return  0;
+		}
+                        
 		default:
 			return -ENOIOCTLCMD;
 	}
@@ -2182,6 +2138,8 @@
 };
 
 static struct vidbases vbs[] = {
+	{ PCI_VENDOR_ID_ALLIANCE, PCI_DEVICE_ID_ALLIANCE_AT3D,
+		"Alliance AT3D", PCI_BASE_ADDRESS_0},
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_215CT222,
                 "ATI MACH64 CT", PCI_BASE_ADDRESS_0},
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_210888GX,
@@ -2418,12 +2376,11 @@
 	{
 	        btv->type=BTTV_MIRO;
     
-		if (I2CRead(&(btv->i2c), I2C_HAUPEE)>=0)
-		{
+		if (I2CRead(&(btv->i2c), I2C_HAUPEE)>=0) {
 			if(btv->id>849)
 				btv->type=BTTV_HAUPPAUGE878;
 			else
-			        btv->type=BTTV_HAUPPAUGE;
+				btv->type=BTTV_HAUPPAUGE;
 		}
 		else
 		        if (I2CRead(&(btv->i2c), I2C_STBEE)>=0)
@@ -2443,8 +2400,8 @@
 
         if (I2CRead(&(btv->i2c), I2C_TDA8425) >=0)
         {
-            btv->audio_chip = TDA8425;
-            printk("bttv%d: audio chip: TDA8425\n", i);
+		btv->audio_chip = TDA8425;
+		printk("bttv%d: audio chip: TDA8425\n", i);
         }
         
         switch(btv->audio_chip)
@@ -2459,11 +2416,11 @@
 
 	/* How do I detect the tuner type for other cards but Miro ??? */
 	printk(KERN_INFO "bttv%d: model: ", btv->nr);
-	
 	sprintf(btv->video_dev.name,"BT%d",btv->id);
 	switch (btv->type) 
 	{
 		case BTTV_MIRO:
+		case BTTV_MIROPRO:
 			printk("MIRO\n");
 			if (btv->have_tuner) 
 			{
@@ -2472,7 +2429,7 @@
 						   I2C_DRIVERID_TUNER,
 						   TUNER_SET_TYPE,&tunertype);
 			}
-			strcat(btv->video_dev.name, "(Miro)");
+			strcat(btv->video_dev.name,"(Miro)");
 			break;
 		case BTTV_HAUPPAUGE:
 		case BTTV_HAUPPAUGE878:
@@ -2650,11 +2607,6 @@
         /* select direct input */
 	btwrite(0x00, BT848_GPIO_REG_INP);
 
-
-	btwrite(0xff, BT848_VBI_PACK_SIZE);
-	btwrite(1, BT848_VBI_PACK_DEL);
-
-		
 	btwrite(BT848_IFORM_MUX1 | BT848_IFORM_XTAUTO | BT848_IFORM_PAL_BDGHI,
 		BT848_IFORM);
 
@@ -2759,6 +2711,7 @@
 		if (astat&BT848_INT_VSYNC) 
 		{
 			IDEBUG(printk ("bttv%d: IRQ_VSYNC\n", btv->nr));
+			btv->field++;
 		}
 		if (astat&BT848_INT_SCERR) {
 			IDEBUG(printk ("bttv%d: IRQ_SCERR\n", btv->nr));
@@ -2776,18 +2729,22 @@
 			if (stat&(1<<28)) 
 			{
 				btv->vbip=0;
+				/* inc vbi frame count for detecting drops */
+				(*(u32 *)&(btv->vbibuf[VBIBUF_SIZE - 4]))++;
 				wake_up_interruptible(&btv->vbiq);
 			}
 
 			/* captured full frame */
 			if (stat&(2<<28)) 
 			{
-				wake_up_interruptible(&btv->capq);
                                 btv->last_field=btv->field;
                                 btv->grab++;
                                 btv->frame_stat[btv->grf] = GBUFFER_DONE;
 			        if ((--btv->grabbing))
 				{
+					btv->gfmt = btv->gfmt_next;
+					btv->gwidth = btv->gwidth_next;
+					btv->gheight = btv->gheight_next;
 					btv->gro = btv->gro_next;
 					btv->gre = btv->gre_next;
 					btv->grf = btv->grf_next;
@@ -2844,10 +2801,12 @@
 		}
 		if (astat&BT848_INT_HLOCK) 
 		{
+#if 0
 			if ((dstat&BT848_DSTATUS_HLOC) || (btv->radio))
 				audio(btv, AUDIO_ON);
 			else
 				audio(btv, AUDIO_OFF);
+#endif
 		}
     
 		if (astat&BT848_INT_I2CDONE) 
@@ -2923,18 +2882,28 @@
         printk("irq: %d, ",btv->irq);
         printk("memory: 0x%08x.\n", btv->bt848_adr);
         
-        btv->pll.pll_ifreq=0;
-        btv->pll.pll_ofreq=0;
-        btv->pll.pll_crystal=0;
-        if(pll[btv->nr])
-                if (!(btv->id==848 && btv->revision==0x11))
-                {
-                        printk(KERN_INFO "bttv%d: internal PLL, single crystal operation enabled\n",bttv_num);
-                        btv->pll.pll_ofreq=28636363;
+	btv->pll.pll_ifreq=0;
+	btv->pll.pll_ofreq=0;
+	btv->pll.pll_crystal=0;
+	btv->pll.pll_current=0;
+        if (!(btv->id==848 && btv->revision==0x11)) {
+                switch (pll[btv->nr]) {
+                case 0:
+                        /* off */
+                        break;
+                case 1:
+                        /* 28 MHz crystal installed */
+                        btv->pll.pll_ifreq=28636363;
+                        btv->pll.pll_crystal=BT848_IFORM_XT0;
+                        break;
+                case 2:
+                        /* 35 MHz crystal installed */
                         btv->pll.pll_ifreq=35468950;
                         btv->pll.pll_crystal=BT848_IFORM_XT1;
+                        break;
                 }
-        
+        }
+
         btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
         
 	/* clear interrupt mask */
@@ -2997,7 +2966,7 @@
                 dev = dev->next;
         }
 	if(bttv_num)
-		printk(KERN_INFO "bttv: %d BT8xx card(s) found.\n", bttv_num);
+		printk(KERN_INFO "bttv: %d Bt8xx card(s) found.\n", bttv_num);
 	return bttv_num;
 }
  
@@ -3113,4 +3082,3 @@
  * tab-width: 8
  * End:
  */
- 
diff -u --recursive --new-file v2.1.125/linux/drivers/char/bttv.h linux/drivers/char/bttv.h
--- v2.1.125/linux/drivers/char/bttv.h	Sat Sep  5 16:46:40 1998
+++ linux/drivers/char/bttv.h	Sat Oct 17 15:52:18 1998
@@ -31,12 +31,11 @@
 #include "bt848.h"
 #include <linux/videodev.h>
 
-#define MAX_CLIPRECS	100
 #define MAX_GBUFFERS	2
 #define RISCMEM_LEN	(32744*2)
 
 /* maximum needed buffer size for extended VBI frame mode capturing */
-#define BTTV_MAX_FBUF	0x151000
+#define BTTV_MAX_FBUF	0x190000
 
 #ifdef __KERNEL__
 
@@ -56,11 +55,11 @@
 	ushort depth;
 };
 
-
 struct bttv_pll_info {
-	unsigned int pll_ifreq;	/* PLL input frequency 	  */
-	unsigned int pll_ofreq;	/* PLL output frequency   */
+	unsigned int pll_ifreq;		/* PLL input frequency    */
+	unsigned int pll_ofreq;		/* PLL output frequency   */
 	unsigned int pll_crystal;	/* Crystal used for input */
+	unsigned int pll_current;	/* Current programmed ofrq*/
 };
 
 struct bttv 
@@ -116,6 +115,7 @@
 	struct gbuffer *ogbuffers;
 	struct gbuffer *egbuffers;
 	u16 gwidth, gheight, gfmt;
+        u16 gwidth_next, gheight_next, gfmt_next;
 	u32 *grisc;
 	
 	unsigned long gro;
@@ -143,6 +143,7 @@
 	int i2c_command;
 	int triton1;
 };
+
 #endif
 
 /*The following should be done in more portable way. It depends on define
@@ -167,6 +168,10 @@
 #define BTTV_GRAB		_IOR('v' , BASE_VIDIOCPRIVATE+2, struct gbuf)
 #define BTTV_FIELDNR		_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)
 #define BTTV_PLLSET		_IOW('v' , BASE_VIDIOCPRIVATE+3, struct bttv_pll_info)
+#define BTTV_BURST_ON		_IOR('v' , BASE_VIDIOCPRIVATE+4, int)
+#define BTTV_BURST_OFF		_IOR('v' , BASE_VIDIOCPRIVATE+5, int)
+#define BTTV_NAGRAVERSION	_IOR('v' , BASE_VIDIOCPRIVATE+6, int)
+#define BTTV_PICNR		_IOR('v' , BASE_VIDIOCPRIVATE+7, int)
 
 
 #define BTTV_UNKNOWN       0x00
@@ -178,7 +183,9 @@
 #define BTTV_AVERMEDIA     0x06 
 #define BTTV_MATRIX_VISION 0x07 
 #define BTTV_FLYVIDEO      0x08
-#define BTTV_HAUPPAUGE878  0x09
+#define BTTV_TURBOTV       0x09
+#define BTTV_HAUPPAUGE878  0x0a
+#define BTTV_MIROPRO       0x0b
 
 #define AUDIO_TUNER        0x00
 #define AUDIO_RADIO        0x01
diff -u --recursive --new-file v2.1.125/linux/drivers/char/bw-qcam.c linux/drivers/char/bw-qcam.c
--- v2.1.125/linux/drivers/char/bw-qcam.c	Tue Aug 18 22:02:03 1998
+++ linux/drivers/char/bw-qcam.c	Fri Oct  9 11:56:59 1998
@@ -296,7 +296,7 @@
 		if (reg != lastreg)
 			count++;
 		lastreg = reg;
-		mdelay(1);
+		mdelay(2);
 	}
 
 	/* Be liberal in what you accept...  */
diff -u --recursive --new-file v2.1.125/linux/drivers/char/esp.c linux/drivers/char/esp.c
--- v2.1.125/linux/drivers/char/esp.c	Mon Sep 28 10:51:33 1998
+++ linux/drivers/char/esp.c	Fri Oct  9 11:56:59 1998
@@ -395,15 +395,20 @@
 
 static _INLINE_ void receive_chars_dma(struct esp_struct *info, int num_bytes)
 {
+	unsigned long flags;
 	info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
 	dma_bytes = num_bytes;
 	info->stat_flags |= ESP_STAT_DMA_RX;
+	
+	flags=claim_dma_lock();
         disable_dma(dma);
         clear_dma_ff(dma);
         set_dma_mode(dma, DMA_MODE_READ);
         set_dma_addr(dma, virt_to_bus(dma_buffer));
         set_dma_count(dma, dma_bytes);
         enable_dma(dma);
+        release_dma_lock(flags);
+        
         serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX);
 }
 
@@ -412,12 +417,17 @@
 {
 	struct tty_struct *tty = info->tty;
 	int num_bytes;
-
+	unsigned long flags;
+	
+	
+	flags=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 
 	info->stat_flags &= ~ESP_STAT_DMA_RX;
 	num_bytes = dma_bytes - get_dma_residue(dma);
+	release_dma_lock(flags);
+	
 	info->icount.rx += num_bytes;
 
 	memcpy(tty->flip.char_buf_ptr, dma_buffer, num_bytes);
@@ -534,6 +544,8 @@
 
 static _INLINE_ void transmit_chars_dma(struct esp_struct *info, int num_bytes)
 {
+	unsigned long flags;
+	
 	dma_bytes = num_bytes;
 
 	if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) {
@@ -564,34 +576,46 @@
 	}
 
 	info->stat_flags |= ESP_STAT_DMA_TX;
+	
+	flags=claim_dma_lock();
         disable_dma(dma);
         clear_dma_ff(dma);
         set_dma_mode(dma, DMA_MODE_WRITE);
         set_dma_addr(dma, virt_to_bus(dma_buffer));
         set_dma_count(dma, dma_bytes);
         enable_dma(dma);
+        release_dma_lock(flags);
+        
         serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
 }
 
 static _INLINE_ void transmit_chars_dma_done(struct esp_struct *info)
 {
 	int num_bytes;
+	unsigned long flags;
+	
 
+	flags=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 
 	num_bytes = dma_bytes - get_dma_residue(dma);
 	info->icount.tx += dma_bytes;
+	release_dma_lock(flags);
 
 	if (dma_bytes != num_bytes) {
 		dma_bytes -= num_bytes;
 		memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes);
+		
+		flags=claim_dma_lock();
         	disable_dma(dma);
         	clear_dma_ff(dma);
         	set_dma_mode(dma, DMA_MODE_WRITE);
         	set_dma_addr(dma, virt_to_bus(dma_buffer));
         	set_dma_count(dma, dma_bytes);
         	enable_dma(dma);
+        	release_dma_lock(flags);
+        	
         	serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
 	} else {
 		dma_bytes = 0;
@@ -1003,7 +1027,7 @@
  */
 static void shutdown(struct esp_struct * info)
 {
-	unsigned long	flags;
+	unsigned long	flags, f;
 
 	if (!(info->flags & ASYNC_INITIALIZED))
 		return;
@@ -1025,8 +1049,11 @@
 	/* stop a DMA transfer on the port being closed */
 	   
 	if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) {
+		f=claim_dma_lock();
 		disable_dma(dma);
 		clear_dma_ff(dma);
+		release_dma_lock(f);
+		
 		dma_bytes = 0;
 	}
 	
diff -u --recursive --new-file v2.1.125/linux/drivers/char/hfmodem/main.c linux/drivers/char/hfmodem/main.c
--- v2.1.125/linux/drivers/char/hfmodem/main.c	Wed Aug 26 11:37:37 1998
+++ linux/drivers/char/hfmodem/main.c	Fri Oct  9 12:20:27 1998
@@ -148,14 +148,6 @@
 #define SP_PAR  2
 #define SP_MIDI 4
 
-/* ---------------------------------------------------------------------- */
-
-static int parptt_preempt(void *handle)
-{
-	/* we cannot relinquish the port in the middle of an operation */
-	return 1;
-}
-
 /* --------------------------------------------------------------------- */
 
 static void parptt_wakeup(void *handle)
@@ -176,8 +168,8 @@
 		pp = pp->next;
 	if (!pp)
 		return 0;
-	if (!(dev->ptt_out.pardev = parport_register_device(pp, hfmodem_drvname, parptt_preempt, parptt_wakeup, 
-							    NULL, PARPORT_DEV_LURK, dev)))
+	if (!(dev->ptt_out.pardev = parport_register_device(pp, hfmodem_drvname, NULL, parptt_wakeup, 
+							    NULL, PARPORT_DEV_EXCL, dev)))
 		return 0;
 	return 1;
 }
diff -u --recursive --new-file v2.1.125/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
--- v2.1.125/linux/drivers/char/istallion.c	Wed Jun 24 22:54:05 1998
+++ linux/drivers/char/istallion.c	Fri Oct 23 08:26:04 1998
@@ -170,7 +170,7 @@
  */
 static char	*stli_drvtitle = "Stallion Intelligent Multiport Serial Driver";
 static char	*stli_drvname = "istallion";
-static char	*stli_drvversion = "5.4.6";
+static char	*stli_drvversion = "5.4.7";
 static char	*stli_serialname = "ttyE";
 static char	*stli_calloutname = "cue";
 
@@ -635,16 +635,21 @@
  *	board. This is also a very useful debugging tool.
  */
 static struct file_operations	stli_fsiomem = {
-	NULL,
-	stli_memread,
-	stli_memwrite,
-	NULL,
-	NULL,
-	stli_memioctl,
-	NULL,
-	stli_memopen,
-	stli_memclose,
-	NULL
+	NULL,		/* llseek */
+	stli_memread,	/* read */
+	stli_memwrite,	/* write */
+	NULL,		/* readdir */
+	NULL,		/* poll */
+	stli_memioctl,	/* ioctl */
+	NULL,		/* mmap */
+	stli_memopen,	/* open */
+	NULL,		/* flush */
+	stli_memclose,	/* release */
+	NULL,		/* fsync */
+	NULL,		/* fasync */
+	NULL,		/* check_media_change */
+	NULL,		/* revalidate */
+	NULL		/* lock */
 };
 
 /*****************************************************************************/
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-analog.c linux/drivers/char/joystick/joy-analog.c
--- v2.1.125/linux/drivers/char/joystick/joy-analog.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-analog.c	Wed Oct 21 08:43:33 1998
@@ -73,7 +73,7 @@
 	u = a = ((info->mask[0] | info->mask[1]) & JS_AN_AXES_STD) | (info->extensions & JS_AN_HAT_FCS)
 	      | ((info->extensions & JS_AN_BUTTONS_PXY_XY) >> 2) | ((info->extensions & JS_AN_BUTTONS_PXY_UV) >> 4);
 
-	outb(inb(io),io);
+	outb(0xff,io);
 	t = js_get_time_a();
 	do {
 		v = inb(io) & a;
@@ -130,7 +130,7 @@
 	if (check_region(io, 1)) return port;
 
 	if (((u = inb(io)) & 3) == 3) return port;
-	outb(u,io);
+	outb(0xff,io);
 	u = inb(io);
 	udelay(JS_AN_MAX_TIME);
 	u = (inb(io) ^ u) & u;
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-assasin.c linux/drivers/char/joystick/joy-assasin.c
--- v2.1.125/linux/drivers/char/joystick/joy-assasin.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-assasin.c	Wed Oct 21 08:43:33 1998
@@ -84,7 +84,7 @@
 
 	__save_flags(flags);
 	__cli();
-	outb(inb(io),io);
+	outb(0xff,io);
 
 	u = inb(io);
 	t = js_get_time();
@@ -306,7 +306,7 @@
 
 	if (check_region(io, 1)) return port;
 	if (((u = inb(io)) & 3) == 3) return port;
-	outb(u,io);
+	outb(0xff,io);
 	if (!((inb(io) ^ u) & ~u & 0xf)) return port;
 
 	if (js_as_read_packet(io, 1, data) != 1) return port;
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-console.c linux/drivers/char/joystick/joy-console.c
--- v2.1.125/linux/drivers/char/joystick/joy-console.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-console.c	Wed Oct 21 08:43:33 1998
@@ -1,5 +1,5 @@
 /*
- * joy-console.c  Version 0.10
+ * joy-console.c  Version 0.11V
  *
  * Copyright (c) 1998 Andree Borrmann
  */
@@ -57,8 +57,6 @@
 struct js_console_info {
 #ifdef USE_PARPORT
 	struct pardevice *port;	/* parport device */
-	int use;		/* use count */
-	int wanted;		/* parport wanted */
 #else
 	int port;		/* hw port */
 #endif
@@ -345,19 +343,11 @@
 
 int js_console_open(struct js_dev *dev)
 {
-	MOD_INC_USE_COUNT;
-
 #ifdef USE_PARPORT
-	{
-		struct js_console_info *info = dev->port->info;
-		if (!info->use && parport_claim(info->port)) {
-			printk(KERN_WARNING "joy-console: parport busy!\n");	/* port currently not available ... */
-			info->wanted++;						/* we'll claim it on wakeup */
-			return 0;
-		}
-		info->use++;
-	}
+	struct js_console_info *info = dev->port->info;
+	if (!MOD_IN_USE && parport_claim(info->port)) return -EBUSY;
 #endif
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -369,32 +359,13 @@
 {
 #ifdef USE_PARPORT
 	struct js_console_info *info = dev->port->info;
-
-	if (!--info->use)
-		parport_release(info->port);
 #endif
 	MOD_DEC_USE_COUNT;
-
-	return 0;
-}
-
-/*
- * parport wakeup callback: claim the port!
- */
-
 #ifdef USE_PARPORT
-static void js_console_wakeup(void *v)
-{
-	struct js_console_info *info = js_console_port->info;	/* FIXME! We can have more than 1 port! */
-
-	if (!info->use && info->wanted)
-	{
-		parport_claim(info->port);
-		info->use++;
-		info->wanted--;
-	}
-}
+	if (!MOD_IN_USE) parport_release(info->port);
 #endif
+	return 0;
+}
 
 #ifdef MODULE
 void cleanup_module(void)
@@ -466,9 +437,9 @@
 			return port;
 		}
 
-		info.port = parport_register_device(pp, "joystick (console)", NULL, js_console_wakeup, NULL, 0, NULL);
-		info.wanted = 0;
-		info.use = 0;
+		info.port = parport_register_device(pp, "joystick (console)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+		if (!info.port)
+			return port;
 	}
 
 	if (parport_claim(info.port))
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-db9.c linux/drivers/char/joystick/joy-db9.c
--- v2.1.125/linux/drivers/char/joystick/joy-db9.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-db9.c	Wed Oct 21 08:43:33 1998
@@ -1,5 +1,5 @@
 /*
- * joy-db9.c  Version 0.3V
+ * joy-db9.c  Version 0.5V
  *
  * Copyright (c) 1998 Andree Borrmann
  */
@@ -47,8 +47,8 @@
 #define JS_GENESIS5_PAD 0x05
 #define JS_GENESIS6_PAD	0x06
 #define JS_SATURN_PAD	0x07
-
-#define JS_MAX_PAD	(JS_SATURN_PAD + 1)
+#define JS_MULTI_0802	0x08
+#define JS_MAX_PAD	0x09
 
 #define JS_DB9_UP	0x01
 #define JS_DB9_DOWN	0x02
@@ -78,11 +78,9 @@
 struct js_db9_info {
 #ifdef USE_PARPORT
 	struct pardevice *port;	/* parport device */
-	int wanted;		/* parport wanted */
 #else
 	int port;		/* hw port */
 #endif
-	int use;		/* use count */
 	int mode;		/* pad mode */
 };
 
@@ -97,6 +95,17 @@
 
 	switch(info->mode)
 	{
+	  case JS_MULTI_0802:
+
+		data = JS_PAR_STATUS(info->port) >> 3;
+
+		axes[0][1] = (data&JS_DB9_DOWN ?0:1) - (data&JS_DB9_UP  ?0:1);
+		axes[0][0] = (data&JS_DB9_RIGHT?0:1) - (data&JS_DB9_LEFT?0:1);
+
+		buttons[0][0] = (data&JS_DB9_FIRE1?1:0);
+
+		break;
+
 	  case JS_MULTI_STICK:
 
 		data = JS_PAR_DATA_IN(info->port);
@@ -262,19 +271,14 @@
 {
 	struct js_db9_info *info = dev->port->info;
 
-	MOD_INC_USE_COUNT;
-	if (!info->use) {
-
+	if (!MOD_IN_USE) {
 #ifdef USE_PARPORT
-		if (parport_claim(info->port)) {
-			printk(KERN_WARNING "joy-db9: parport busy\n");		/* port currently not available ... */
-			info->wanted++;						/* we'll claim it on wakeup */
-			return 0;
-		}
+		if (parport_claim(info->port)) return -EBUSY;
 #endif
 		js_db9_enable_ps2(info);
 	}
-	info->use++;
+		
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -287,9 +291,8 @@
 	struct js_db9_info *info = dev->port->info;
 
 	MOD_DEC_USE_COUNT;
-	info->use--;
 
-	if (!info->use) {
+	if (!MOD_IN_USE) {
 		js_db9_disable_ps2(info);
 #ifdef USE_PARPORT
 		parport_release(info->port);
@@ -298,25 +301,6 @@
 	return 0;
 }
 
-/*
- * parport wakeup callback: claim the port!
- */
-
-#ifdef USE_PARPORT
-static void js_db9_wakeup(void *v)
-{
-	struct js_db9_info *info = js_db9_port->info;	/* FIXME! We can have more than 1 port! */
-
-	if (!info->use && info->wanted)
-	{
-		parport_claim(info->port);
-		js_db9_enable_ps2(info);
-		info->use++;
-		info->wanted--;
-	}
-}
-#endif
-
 #ifdef MODULE
 void cleanup_module(void)
 {
@@ -363,9 +347,9 @@
 static struct js_port __init *js_db9_probe(int *config, struct js_port *port)
 {
 	struct js_db9_info info;
-	char buttons[JS_MAX_PAD] = {0,1,2,4,0,6,7,8};
+	char buttons[JS_MAX_PAD] = {0,1,2,4,0,6,7,8,1};
 	char *name[JS_MAX_PAD] = {NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
-					NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad"};
+					NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick"};
 
 	if (config[0] < 0) return port;
 	if (config[1] < 0 || config[1] >= JS_MAX_PAD || !name[config[1]]) return port;
@@ -389,8 +373,9 @@
 			return port;
 		}
 
-		info.port = parport_register_device(pp, "joystick (db9)", NULL, js_db9_wakeup, NULL, 0, NULL);
-		info.wanted = 0;
+		info.port = parport_register_device(pp, "joystick (db9)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+		if (!info.port)
+			return port;
 	}
 #else
 	info.port = config[0];
@@ -400,7 +385,6 @@
 #endif
 
 	info.mode = config[1];
-	info.use = 0;
 
 	port = js_register_port(port, &info, 1, sizeof(struct js_db9_info), js_db9_read);
 
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-joydump.c linux/drivers/char/joystick/joy-joydump.c
--- v2.1.125/linux/drivers/char/joystick/joy-joydump.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-joydump.c	Wed Dec 31 16:00:00 1969
@@ -1,172 +0,0 @@
-/*
- *  joydump.c  Version 1.2
- *
- *  Copyright (c) 1996-1998 Vojtech Pavlik
- */
-
-/*
- * This is just a very simple driver that can dump the data
- * out of the joystick port into the syslog ...
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or 
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * 
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
- */
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/joystick.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-
-#define JS_PORT 0x201
-
-#ifdef __i386__
-static unsigned int get_time(void)
-{
-	unsigned int x;
-	__asm__ __volatile__ ( "rdtsc" : "=A" (x) );
-	return x;
-}
-#else
-
-#ifdef	__alpha__
-static unsigned int get_time(void)
-{
-	unsigned int x;
-	__asm__ __volatile__ ( "rpcc %0" : "=r" (x) );
-	return x;
-}
-#else
-
-#error "Sorry, you need a precise timer for this - define some in joydump.c"
-
-#endif
-#endif
-
-#define BUF_SIZE 128
-
-struct datatype {
-	unsigned int time;
-	unsigned char data;
-};
-
-static struct datatype buf[BUF_SIZE];
-
-int init_module(void)
-{
-	int i, j;
-	unsigned int t, t1;
-	int timeout, div;
-	unsigned long flags;
-	unsigned char u;
-
-	printk(KERN_INFO "joydump: ,------------------- START ------------------.\n");
-
-/*
- * Calibrate.
- */
-
-	__save_flags(flags);
-	__cli();
-	t = get_time();
-	udelay(1000);
-	t1 = get_time();
-	__restore_flags(flags);
-
-	timeout = t1 - t;
-	div = timeout / 1000;
-
-	printk(KERN_INFO "joydump: | Timer ticks at %d.%02d MHz.                 |\n",
-		timeout / 1000, timeout / 10 % 100);
-
-	__save_flags(flags);
-	__cli();
-	t = get_time();
-	inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT);
-	inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT);
-	t1 = get_time();
-	__restore_flags(flags);
-
-	printk(KERN_INFO "joydump: | I/O at %#x takes %d.%02d us.                |\n",
-		JS_PORT, (t1 - t) / div / 10, (t1 - t) * 10 / div % 100);
-
-	timeout *= 20;
-
-/*
- * Gather data.
- */
-
-	__save_flags(flags);
-	__cli();
-
-	u = inb(JS_PORT);
-	t = t1 = get_time();
-	buf[0].data = u;
-	buf[0].time = t1;
-	i = 1;
-
-	outb(u,JS_PORT);
-
-	while (i < BUF_SIZE && t1 - t < timeout) {
-
-		t1 = get_time();
-		buf[i].data = inb(JS_PORT);
-
-		if (buf[i].data != u) {
-			u = buf[i].data;
-			buf[i].time = t1;
-			i++;
-		}
-	}
-
-	__restore_flags(flags);
-
-/*
- * Dump data.
- */
-
-
-	t = i;
-
-	printk(KERN_INFO "joydump: >------------------- DATA -------------------<\n");
-	printk(KERN_INFO "joydump: | index: %3d delta: %3d.%02d us data: ", 0, 0, 0);
-	for (j = 7; j >= 0; j--)
-		printk("%d",(buf[0].data >> j) & 1);
-	printk(" |\n");
-	for (i = 1; i < t; i++) {
-		printk(KERN_INFO "joydump: | index: %3d delta: %3d.%02d us data: ", i,
-			(buf[i].time - buf[i-1].time) / div, (buf[i].time - buf[i-1].time) * 100 / div % 100);
-		for (j = 7; j >= 0; j--)
-			printk("%d",(buf[i].data >> j) & 1);
-		printk(" |\n");
-	}
-
-	printk(KERN_INFO "joydump: `-------------------- END -------------------'\n");
-
-	return -1;
-}
-
-void cleanup_module(void)
-{
-}
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-lightning.c linux/drivers/char/joystick/joy-lightning.c
--- v2.1.125/linux/drivers/char/joystick/joy-lightning.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-lightning.c	Wed Oct 21 08:43:34 1998
@@ -109,18 +109,42 @@
 
 	js_an_decode(&info->an, axes, buttons);
 
+	return 0;
+}
+
+/*
+ * js_l4_getcal() reads the L4 with calibration values.
+ */
+
+static int js_l4_getcal(int port, int *cal)
+{
+	int i;
+	
 	outb(JS_L4_SELECT_ANALOG, JS_L4_PORT);
+	outb(JS_L4_SELECT_DIGITAL + (port >> 2), JS_L4_PORT);
+
+	if (inb(JS_L4_PORT) & JS_L4_BUSY) return -1;
+	outb(JS_L4_CMD_GETCAL, JS_L4_PORT);
+
+	if (js_l4_wait_ready()) return -1;
+	if (inb(JS_L4_PORT) != JS_L4_SELECT_DIGITAL + (port >> 2)) return -1;
+
+	if (js_l4_wait_ready()) return -1;
+        outb(port & 3, JS_L4_PORT);
+
+	for (i = 0; i < 4; i++) {
+		if (js_l4_wait_ready()) return -1;
+		cal[i] = inb(JS_L4_PORT);
+	}
 
 	return 0;
 }
 
-#if 0
-
 /*
  * js_l4_setcal() programs the L4 with calibration values.
  */
 
-static int js_l4_setcal(int port, int *calib)
+static int js_l4_setcal(int port, int *cal)
 {
 	int i;
 
@@ -128,54 +152,61 @@
 	outb(JS_L4_SELECT_DIGITAL + (port >> 2), JS_L4_PORT);
 
 	if (inb(JS_L4_PORT) & JS_L4_BUSY) return -1;
-
 	outb(JS_L4_CMD_SETCAL, JS_L4_PORT);
+
 	if (js_l4_wait_ready()) return -1;
+	if (inb(JS_L4_PORT) != JS_L4_SELECT_DIGITAL + (port >> 2)) return -1;
 
-        outb(port & 3, JS_L4_PORT);
 	if (js_l4_wait_ready()) return -1;
+        outb(port & 3, JS_L4_PORT);
 
 	for (i = 0; i < 4; i++) {
-		outb(calib[0], JS_L4_PORT);
 		if (js_l4_wait_ready()) return -1;
+		outb(cal[i], JS_L4_PORT);
 	}
 
-	outb(JS_L4_SELECT_ANALOG, JS_L4_PORT);
-
 	return 0;
 }
 
+/*
+ * js_l4_calibrate() calibrates the L4 for the attached device, so
+ * that the device's resistance fits into the L4's 8-bit range.
+ */
 
 static void js_l4_calibrate(struct js_l4_info *info)
 {
-	int calib[4];
 	int i;
+	int cal[4];
+	int axes[4];
+	int t;
+
+	js_l4_getcal(info->port, cal);
 
+	for (i = 0; i < 4; i++)
+		axes[i] = info->an.axes[i];
+	
 	if ((info->an.extensions & JS_AN_BUTTON_PXY_X) && !(info->an.extensions & JS_AN_BUTTON_PXY_U))
-		info->an.axes[2] >>= 2;						/* Pad button X */
+		axes[2] >>= 1;							/* Pad button X */
 
 	if ((info->an.extensions & JS_AN_BUTTON_PXY_Y) && !(info->an.extensions & JS_AN_BUTTON_PXY_V))
-		info->an.axes[3] >>= 2;						/* Pad button Y */
+		axes[3] >>= 1;							/* Pad button Y */
 
 	if (info->an.extensions & JS_AN_HAT_FCS) 
-		info->an.axes[3] >>= 2;						/* FCS hat */
-
-	if (((info->an.mask[0] & 0xb) == 0xb) ||
-	    ((info->an.mask[1] & 0xb) == 0xb))
-		info->an.axes[3] = (info->an.axes[0] + info->an.axes[1]) >> 1;	/* Throttle */
+		axes[3] >>= 1;							/* FCS hat */
 
-	for (i = 0; i < 4; i++)
-		calib[i] = (info->an.axes[i] * 255) / 100;
-	
-	for (i = 0; i < 4; i++)
-		if (calib[i] > 255) calib[i] = 255;
+	if (((info->an.mask[0] & 0xb) == 0xb) || ((info->an.mask[1] & 0xb) == 0xb))
+		axes[3] = (axes[0] + axes[1]) >> 1;				/* Throttle */
 
-	js_l4_setcal(info->port, calib);
+	for (i = 0; i < 4; i++) {
+		t = (axes[i] * cal[i]) / 100;
+		if (t > 255) t = 255;
+		info->an.axes[i] = (info->an.axes[i] * cal[i]) / t;
+		cal[i] = t;
+	}
 
+	js_l4_setcal(info->port, cal);
 }
 	
-#endif
-
 /*
  * js_l4_open() is a callback from the file open routine.
  */
@@ -200,25 +231,21 @@
  * js_l4_probe() probes for joysticks on the L4 cards.
  */
 
-static struct js_port __init *js_l4_probe(int cards, int l4port, int mask0, int mask1, struct js_port *port)
+static struct js_port __init *js_l4_probe(unsigned char *cards, int l4port, int mask0, int mask1, struct js_port *port)
 {
 	struct js_l4_info iniinfo;
 	struct js_l4_info *info = &iniinfo;
-#if 0
-	int calib[4] = {255, 255, 255, 255};
-#endif
+	int cal[4] = {255,255,255,255};
 	int i, numdev;
 	unsigned char u;
 
 	if (l4port < 0) return port;
-	if (~cards & (1 << (l4port >> 2))) return port;
+	if (!cards[(l4port >> 2)]) return port;
 
 	memset(info, 0, sizeof(struct js_l4_info));
 	info->port = l4port;
 
-#if 0
-	js_l4_setcal(info->port, calib);
-#endif
+	if (cards[l4port >> 2] > 0x28) js_l4_setcal(info->port, cal);
 	if (js_l4_read(info, NULL, NULL)) return port;
 
 	for (i = u = 0; i < 4; i++) if (info->an.axes[i] < 253) u |= 1 << i;
@@ -236,9 +263,7 @@
 
 	info = port->info;
 
-#if 0
 	js_l4_calibrate(info);
-#endif
 	js_l4_read(info, port->axes, port->buttons);
 	js_an_init_corr(&info->an, port->axes, port->corr, 0);
 
@@ -249,12 +274,12 @@
  * js_l4_card_probe() probes for presence of the L4 card(s).
  */
 
-static int __init js_l4_card_probe(void)
+static void __init js_l4_card_probe(unsigned char *cards)
 {
-	int i, cards = 0;
+	int i;
 	unsigned char rev = 0;
 
-	if (check_region(JS_L4_PORT, 1)) return 0;
+	if (check_region(JS_L4_PORT, 1)) return;
 
 	for (i = 0; i < 2; i++) {
 
@@ -273,15 +298,12 @@
 		if (js_l4_wait_ready()) continue;
 		rev = inb(JS_L4_PORT);
 
-		cards |= (1 << i);
+		cards[i] = rev; 
 
 		printk(KERN_INFO "js: PDPI Lightning 4 %s card (ports %d-%d) firmware v%d.%d found at %#x\n",
 			i ? "secondary" : "primary", (i << 2), (i << 2) + 3, rev >> 4, rev & 0xf, JS_L4_PORT);
 	}
 
-	outb(JS_L4_SELECT_ANALOG, JS_L4_PORT);
-
-	return cards;
 }
 
 #ifndef MODULE
@@ -295,18 +317,19 @@
 #ifdef MODULE
 int init_module(void)
 #else
-int __init js_l4_an_init(void)
+int __init js_l4_init(void)
 #endif
 {
-	int i, cards;
+	int i;
+	unsigned char cards[2] = {0, 0};
 
-	cards = js_l4_card_probe();
+	js_l4_card_probe(cards);
 
 	if (js_l4[0] >= 0) {
 		for (i = 0; (js_l4[i*3] >= 0) && i < 8; i++)
 			js_l4_port = js_l4_probe(cards, js_l4[i*3], js_l4[i*3+1], js_l4[i*3+2], js_l4_port);
 	} else {
-		for (i = 0; i < (cards << 2); i++)
+		for (i = 0; i < 8; i++)
 			js_l4_port = js_l4_probe(cards, i, 0, 0, js_l4_port);
 	}
 
@@ -326,15 +349,18 @@
 void cleanup_module(void)
 {
 	int i;
+	int cal[4] = {59, 59, 59, 59};
+	struct js_l4_info *info;
 
 	while (js_l4_port) {
 		for (i = 0; i < js_l4_port->ndevs; i++)
 			if (js_l4_port->devs[i])
 				js_unregister_device(js_l4_port->devs[i]);
+		info = js_l4_port->info;
+		js_l4_setcal(info->port, cal);
 		js_l4_port = js_unregister_port(js_l4_port);
 	}
 	outb(JS_L4_SELECT_ANALOG, JS_L4_PORT);
 	release_region(JS_L4_PORT, 1);
-
 }
 #endif
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-logitech.c linux/drivers/char/joystick/joy-logitech.c
--- v2.1.125/linux/drivers/char/joystick/joy-logitech.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-logitech.c	Wed Oct 21 08:43:34 1998
@@ -92,7 +92,7 @@
 	__save_flags(flags);
 	__cli();
 
-	outb(u,io);
+	outb(0xff,io);
 
 	u = inb(io);
 	t = js_get_time();
@@ -232,7 +232,7 @@
 static void __init js_lt_trigger_sequence(int io, int *seq)
 {
 	while (*seq) {
-		outb(inb(io),io);
+		outb(0xff,io);
 		udelay(*seq++);
 	}
 }
@@ -288,7 +288,7 @@
 	if (check_region(io, 1)) return port;
 
 	if (((u = inb(io)) & 3) == 3) return port;
-	outb(u,io);
+	outb(0xff,io);
 	if (!((inb(io) ^ u) & ~u & 0xf)) return port;
 
 	if (!(i = js_lt_read_packet(io, &data))) {
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-sidewinder.c linux/drivers/char/joystick/joy-sidewinder.c
--- v2.1.125/linux/drivers/char/joystick/joy-sidewinder.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-sidewinder.c	Wed Oct 21 08:43:34 1998
@@ -68,21 +68,20 @@
 
 /*
  * js_sw_init_digital() switches a SideWinder into digital mode.
- * It currently switches to 2-bit mode only (FIXME).
  */
 
 static void __init js_sw_init_digital(int io)
 {
 	unsigned int t;
 	unsigned int timeout = (js_time_speed * JS_SW_MAX_TIME) >> 10;
-	int delays[] = {100, 850, 400, 0};
+        int delays[] = {140, 140+726, 140+300, 0};
 	int i = 0;
 	unsigned long flags;
 
 	__save_flags(flags);
 	__cli();
 	do {
-		outb(inb(io),io);
+		outb(0xff,io);
 		t = js_get_time();
 		while ((inb(io) & 1) && (js_delta(js_get_time(),t) < timeout));
 		udelay(delays[i]);
@@ -112,7 +111,7 @@
 
 	__save_flags(flags);
 	__cli();
-	outb(inb(io),io);
+	outb(0xff,io);
 
 	v = inb(io);
 	t = js_get_time();
@@ -214,7 +213,6 @@
 				info->optimize = 0;
 				return -1;
 			}
-
 			axes[0][0] = ((data <<  4) & 0x380) | ((data >> 16) & 0x07f);
 			axes[0][1] = ((data <<  7) & 0x380) | ((data >> 24) & 0x07f);
 			axes[0][2] = ((data >> 28) & 0x180) | ((data >> 40) & 0x07f);
@@ -367,7 +365,7 @@
 
 	if (check_region(io, 1)) return port;
 	if (((u = inb(io)) & 3) == 3) return port;
-	outb(u,io);
+	outb(0xff,io);
 	if (!((inb(io) ^ u) & ~u & 0xf)) return port;
 
 	i = js_sw_read_packet(io, JS_SW_MAX_LENGTH, -1, JS_SW_EXT_STROBE, &data);
@@ -390,7 +388,7 @@
 		case 45:
 		case 60:
 			info.mode = JS_SW_MODE_GP;
-			outb(inb(io),io);						/* Kick into 3-bit mode */
+			outb(0xff,io);							/* Kick into 3-bit mode */
 			udelay(JS_SW_MAX_TIME);
 			i = js_sw_read_packet(io, 60, -1, JS_SW_EXT_STROBE, &data);	/* Get total length */
 			udelay(JS_SW_MIN_TIME);
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-thrustmaster.c linux/drivers/char/joystick/joy-thrustmaster.c
--- v2.1.125/linux/drivers/char/joystick/joy-thrustmaster.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-thrustmaster.c	Wed Oct 21 08:43:34 1998
@@ -94,7 +94,7 @@
 
 	__save_flags(flags);
 	__cli();
-	outb(inb(io),io);
+	outb(0xff,io);
 
 	t = js_get_time();
 
@@ -262,7 +262,7 @@
 	if (check_region(io, 1)) return port;
 
 	if (((u = inb(io)) & 3) == 3) return port;
-	outb(u,io);
+	outb(0xff,io);
 	if (!((inb(io) ^ u) & ~u & 0xf)) return port;
 
 	if(js_tm_read_packet(io, data)) {
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-turbografx.c linux/drivers/char/joystick/joy-turbografx.c
--- v2.1.125/linux/drivers/char/joystick/joy-turbografx.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joy-turbografx.c	Wed Oct 21 08:43:34 1998
@@ -61,8 +61,6 @@
 struct js_tg_info {
 #ifdef USE_PARPORT
 	struct pardevice *port;	/* parport device */
-	int use;		/* use count */
-	int wanted;		/* parport wanted */
 #else
 	int port;		/* hw port */
 #endif
@@ -99,19 +97,11 @@
 
 int js_tg_open(struct js_dev *dev)
 {
-	MOD_INC_USE_COUNT;
-
 #ifdef USE_PARPORT
-	{
-		struct js_tg_info *info = dev->port->info;
-		if (!info->use && parport_claim(info->port)) {
-			printk(KERN_WARNING "joy-tg: parport busy\n");		/* port currently not available ... */
-			info->wanted++;						/* we'll claim it on wakeup */
-			return 0;
-		}
-		info->use++;
-	}
+	struct js_tg_info *info = dev->port->info;
+	if (!MOD_IN_USE && parport_claim(info->port)) return -EBUSY; 
 #endif
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -122,33 +112,14 @@
 int js_tg_close(struct js_dev *dev)
 {
 #ifdef USE_PARPORT
-	struct js_tg_info *info = dev->port->info;
-
-	if (!--info->use)
-		parport_release(info->port);
+        struct js_tg_info *info = dev->port->info;
 #endif
-	MOD_DEC_USE_COUNT;
-
-	return 0;
-}
-
-/*
- * parport wakeup callback: claim the port!
- */
-
+        MOD_DEC_USE_COUNT;
 #ifdef USE_PARPORT
-static void js_tg_wakeup(void *v)
-{
-	struct js_tg_info *info = js_tg_port->info;	/* FIXME! We can have more than 1 port! */
-
-	if (!info->use && info->wanted)
-	{
-		parport_claim(info->port);
-		info->use++;
-		info->wanted--;
-	}
-}
+        if (!MOD_IN_USE) parport_release(info->port);
 #endif
+        return 0;
+}
 
 #ifdef MODULE
 void cleanup_module(void)
@@ -217,9 +188,9 @@
 			return port;
 		}
 
-		info.port = parport_register_device(pp, "joystick (turbografx)", NULL, js_tg_wakeup, NULL, 0, NULL);
-		info.wanted = 0;
-		info.use = 0;
+		info.port = parport_register_device(pp, "joystick (turbografx)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+		if (!info.port)
+			return port;
 	}
 #else
 	info.port = config[0];
diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joystick.c linux/drivers/char/joystick/joystick.c
--- v2.1.125/linux/drivers/char/joystick/joystick.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/joystick/joystick.c	Wed Oct 21 08:43:34 1998
@@ -859,6 +859,7 @@
 	struct js_dev *jd = js_dev;
 	int i = MINOR(inode->i_rdev);
 	unsigned long flags;
+	int result;
 
 	if (MAJOR(inode->i_rdev) != JOYSTICK_MAJOR)
 		return -EINVAL;
@@ -870,7 +871,7 @@
 
 	if (!jd) return -ENODEV;
 
-	jd->open(jd);
+	if ((result = jd->open(jd))) return result;
 
 	MOD_INC_USE_COUNT;
 	if (!js_use_count++) js_do_timer(0);
diff -u --recursive --new-file v2.1.125/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v2.1.125/linux/drivers/char/lp.c	Wed Sep  9 14:51:07 1998
+++ linux/drivers/char/lp.c	Sat Oct 17 15:52:18 1998
@@ -543,7 +543,7 @@
 
 		if (( i & 1) != 0) {
 			Byte= (Byte | z<<4);
-			if (put_user(Byte, (char *)temp))
+			if (__put_user(Byte, (char *)temp))
 				return -EFAULT;
 			temp++;
 		} else Byte=z;
@@ -768,7 +768,7 @@
 	lp_table[nr].dev = parport_register_device(port, "lp", 
 						   lp_preempt, NULL,
 						   lp_interrupt, 
-						   PARPORT_DEV_TRAN,
+						   0,
 						   (void *) &lp_table[nr]);
 	if (lp_table[nr].dev == NULL)
 		return 1;
diff -u --recursive --new-file v2.1.125/linux/drivers/char/misc.c linux/drivers/char/misc.c
--- v2.1.125/linux/drivers/char/misc.c	Mon Sep 28 10:51:33 1998
+++ linux/drivers/char/misc.c	Fri Oct  9 12:30:15 1998
@@ -66,7 +66,6 @@
 
 extern int adbdev_init(void);
 extern int bus_mouse_init(void);
-extern int psaux_init(void);
 extern int qpmouse_init(void);
 extern int ms_bus_mouse_init(void);
 extern int atixl_busmouse_init(void);
@@ -156,8 +155,13 @@
 	}
 	if (misc->minor < DYNAMIC_MINORS)
 		misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
-	misc->next = &misc_list;
-	misc->prev = misc_list.prev;
+
+	/*
+	 * Add it to the front, so that later devices can "override"
+	 * earlier defaults
+	 */
+	misc->prev = &misc_list;
+	misc->next = misc_list.next;
 	misc->prev->next = misc;
 	misc->next->prev = misc;
 	return 0;
@@ -199,10 +203,7 @@
 	bus_mouse_init();
 #endif
 #if defined CONFIG_82C710_MOUSE
-	qpmouse_init();		/* This must be before psaux_init */
-#endif
-#if defined CONFIG_PSMOUSE
-	psaux_init();
+	qpmouse_init();
 #endif
 #ifdef CONFIG_MS_BUSMOUSE
 	ms_bus_mouse_init();
diff -u --recursive --new-file v2.1.125/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- v2.1.125/linux/drivers/char/pc_keyb.c	Mon Sep 28 10:51:33 1998
+++ linux/drivers/char/pc_keyb.c	Fri Oct  9 13:19:46 1998
@@ -5,10 +5,16 @@
  * See keyboard.c for the whole history.
  *
  * Major cleanup by Martin Mares, May 1997
+ *
+ * Combined the keyboard and PS/2 mouse handling into one file,
+ * because they share the same hardware.
+ * Johan Myreen <jem@iki.fi> 1998-10-08.
+ *
  */
 
 #include <linux/config.h>
 
+#include <asm/spinlock.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
@@ -18,10 +24,15 @@
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
 #include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
 
 #include <asm/keyboard.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
+#include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/irq.h>
@@ -43,32 +54,69 @@
 	"\r\000/";					/* 0x60 - 0x6f */
 #endif
 
-unsigned char pckbd_read_mask = KBD_STAT_OBF; /* Modified by psaux.c */
+static void kbd_write(int address, int data);
+
+static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
 
 /* used only by send_data - set by keyboard_interrupt */
 static volatile unsigned char reply_expected = 0;
 static volatile unsigned char acknowledge = 0;
 static volatile unsigned char resend = 0;
 
+
+#if defined CONFIG_PSMOUSE
+/*
+ *	PS/2 Auxiliary Device
+ */
+
+static int __init psaux_init(void);
+
+static struct aux_queue *queue;	/* Mouse data buffer. */
+static int aux_count = 0;
+
+#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
+#define AUX_INTS_ON  (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
+
+#define MAX_RETRIES	60		/* some aux operations take long time*/
+#if defined(__alpha__) && !defined(CONFIG_PCI)
+# define AUX_IRQ	9		/* Jensen is odd indeed */
+#else
+# define AUX_IRQ	12
+#endif
+#endif /* CONFIG_PSMOUSE */
+
 /*
- *	Wait for keyboard controller input buffer is empty.
+ * Wait for keyboard controller input buffer is empty.
+ *
+ * Don't use 'jiffies' so that we don't depend on
+ * interrupts..
  *
- *	Don't use 'jiffies' so that we don't depend on
- *	interrupts..
+ * Quote from PS/2 System Reference Manual:
+ *
+ * "Address hex 0060 and address hex 0064 should be written only when
+ * the input-buffer-full bit and output-buffer-full bit in the
+ * Controller Status register are set 0."
  */
 
 static inline void kb_wait(void)
 {
 	unsigned long timeout = KBC_TIMEOUT;
+	unsigned char status;
 
 	do {
+		status = inb_p(KBD_STATUS_REG);
+		if (status & KBD_STAT_OBF) {
+			if (status & KBD_STAT_MOUSE_OBF)
+			inb_p(KBD_DATA_REG); /* Flush. */
+		}
+
 		if (! (inb_p(KBD_STATUS_REG) & KBD_STAT_IBF))
 			return;
 		mdelay(1);
 		timeout--;
 	} while (timeout);
 #ifdef KBD_REPORT_TIMEOUTS
-	printk(KERN_WARNING "Keyboard timed out\n");
+	printk(KERN_WARNING "Keyboard timed out[1]\n");
 #endif
 }
 
@@ -211,11 +259,16 @@
 #if DISABLE_KBD_DURING_INTERRUPTS
 static inline void send_cmd(unsigned char c)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
 	kb_wait();
 	outb(c, KBD_CNTL_REG);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
 }
 
-#define disable_keyboard()	do { send_cmd(KBD_CCMD_KBD_DISABLE); kb_wait(); } while (0)
+/* #define disable_keyboard()	do { send_cmd(KBD_CCMD_KBD_DISABLE); kb_wait(); } while (0) */
+#define disable_keyboard()	send_cmd(KBD_CCMD_KBD_DISABLE)
 #define enable_keyboard()	send_cmd(KBD_CCMD_KBD_ENABLE)
 #else
 #define disable_keyboard()	/* nothing */
@@ -368,27 +421,45 @@
 
 static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	unsigned long flags;
 	unsigned char status;
 
-	kbd_pt_regs = regs;
 	disable_keyboard();
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	kbd_pt_regs = regs;
 
-	status = inb_p(KBD_STATUS_REG);
-	do {
+	status = inb(KBD_STATUS_REG);
+	while (status & KBD_STAT_OBF) {
 		unsigned char scancode;
 
-		/* mouse data? */
-		if (status & pckbd_read_mask & KBD_STAT_MOUSE_OBF)
-			break;
-
 		scancode = inb(KBD_DATA_REG);
-		if ((status & KBD_STAT_OBF) && do_acknowledge(scancode))
-			handle_scancode(scancode);
+
+		if (status & KBD_STAT_MOUSE_OBF) {
+#ifdef CONFIG_PSMOUSE
+			/* Mouse data. */
+			if (aux_count) {
+				int head = queue->head;
+				queue->buf[head] = scancode;
+				add_mouse_randomness(scancode);
+				head = (head + 1) & (AUX_BUF_SIZE-1);
+				if (head != queue->tail) {
+					queue->head = head;
+					if (queue->fasync)
+						kill_fasync(queue->fasync, SIGIO);
+					wake_up_interruptible(&queue->proc_list);
+				}
+			}
+#endif
+		} else {
+			if (do_acknowledge(scancode))
+				handle_scancode(scancode);
+			mark_bh(KEYBOARD_BH);
+		}
 
 		status = inb(KBD_STATUS_REG);
-	} while (status & KBD_STAT_OBF);
+	}
 
-	mark_bh(KEYBOARD_BH);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
 	enable_keyboard();
 }
 
@@ -406,11 +477,10 @@
 	do {
 		unsigned long timeout = KBD_TIMEOUT;
 
-		kb_wait();
-		acknowledge = 0;
+		acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
 		resend = 0;
 		reply_expected = 1;
-		outb_p(data, KBD_DATA_REG);
+		kbd_write(KBD_DATA_REG, data);
 		for (;;) {
 			if (acknowledge)
 				return 1;
@@ -419,7 +489,7 @@
 			mdelay(1);
 			if (!--timeout) {
 #ifdef KBD_REPORT_TIMEOUTS
-				printk(KERN_WARNING "Keyboard timeout\n");
+				printk(KERN_WARNING "Keyboard timeout[2]\n");
 #endif
 				return 0;
 			}
@@ -500,15 +570,29 @@
 	return -1;
 }
 
-static void __init kbd_write(int address, int data)
+static void kbd_write(int address, int data)
 {
-	int status;
+	unsigned long flags;
 
-	do {
-		status = inb(KBD_STATUS_REG);
-	} while (status & KBD_STAT_IBF);
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	kb_wait();
 	outb(data, address);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+
+#if defined CONFIG_PSMOUSE
+static void kbd_write_cmd(int cmd)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	kb_wait();
+	outb(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG);
+	kb_wait();
+	outb(cmd, KBD_DATA_REG);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
 }
+#endif /* CONFIG_PSMOUSE */
 
 static char * __init initialize_kbd(void)
 {
@@ -623,6 +707,225 @@
 			printk(KERN_WARNING "initialize_kbd: %s\n", msg);
 	}
 
+#if defined CONFIG_PSMOUSE
+	psaux_init();
+#endif
+
 	/* Ok, finally allocate the IRQ, and off we go.. */
 	request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
 }
+
+#if defined CONFIG_PSMOUSE
+/*
+ * Send a byte to the mouse.
+ */
+static void aux_write_dev(int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	kb_wait();
+	outb(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG);
+	kb_wait();
+	outb(val, KBD_DATA_REG);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+
+static unsigned int get_from_queue(void)
+{
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	result = queue->buf[queue->tail];
+	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
+	restore_flags(flags);
+	return result;
+}
+
+
+static inline int queue_empty(void)
+{
+	return queue->head == queue->tail;
+}
+
+static int fasync_aux(int fd, struct file *filp, int on)
+{
+	int retval;
+
+	retval = fasync_helper(fd, filp, on, &queue->fasync);
+	if (retval < 0)
+		return retval;
+	return 0;
+}
+
+
+static int release_aux(struct inode * inode, struct file * file)
+{
+	fasync_aux(-1, file, 0);
+	if (--aux_count)
+		return 0;
+	kbd_write_cmd(AUX_INTS_OFF);			    /* Disable controller ints */
+	kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG);
+#ifdef CONFIG_MCA
+	free_irq(AUX_IRQ, inode);
+#else
+	free_irq(AUX_IRQ, NULL);
+#endif
+	return 0;
+}
+
+/*
+ * Install interrupt handler.
+ * Enable auxiliary device.
+ */
+
+static int open_aux(struct inode * inode, struct file * file)
+{
+	if (aux_count++) {
+		return 0;
+	}
+	queue->head = queue->tail = 0;		/* Flush input queue */
+#ifdef CONFIG_MCA
+	if (request_irq(AUX_IRQ, keyboard_interrupt, MCA_bus ? SA_SHIRQ : 0, "PS/2 Mouse", inode)) {
+#else
+	if (request_irq(AUX_IRQ, keyboard_interrupt, 0, "PS/2 Mouse", NULL)) {
+#endif
+		aux_count--;
+		return -EBUSY;
+	}
+	kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG);	/* Enable the
+							   auxiliary port on
+							   controller. */
+	aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */
+	kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
+
+	return 0;
+}
+
+/*
+ * Put bytes from input queue to buffer.
+ */
+
+static ssize_t read_aux(struct file * file, char * buffer,
+			size_t count, loff_t *ppos)
+{
+	struct wait_queue wait = { current, NULL };
+	ssize_t i = count;
+	unsigned char c;
+
+	if (queue_empty()) {
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		add_wait_queue(&queue->proc_list, &wait);
+repeat:
+		current->state = TASK_INTERRUPTIBLE;
+		if (queue_empty() && !signal_pending(current)) {
+			schedule();
+			goto repeat;
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&queue->proc_list, &wait);
+	}
+	while (i > 0 && !queue_empty()) {
+		c = get_from_queue();
+		put_user(c, buffer++);
+		i--;
+	}
+	if (count-i) {
+		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+		return count-i;
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+/*
+ * Write to the aux device.
+ */
+
+static ssize_t write_aux(struct file * file, const char * buffer,
+			 size_t count, loff_t *ppos)
+{
+	ssize_t retval = 0;
+
+	if (count) {
+		ssize_t written = 0;
+
+		if (count > 32)
+			count = 32; /* Limit to 32 bytes. */
+		do {
+			char c;
+			get_user(c, buffer++);
+			aux_write_dev(c);
+			written++;
+		} while (--count);
+		retval = -EIO;
+		if (written) {
+			retval = written;
+			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
+		}
+	}
+
+	return retval;
+}
+
+static unsigned int aux_poll(struct file *file, poll_table * wait)
+{
+	poll_wait(file, &queue->proc_list, wait);
+	if (!queue_empty())
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+struct file_operations psaux_fops = {
+	NULL,		/* seek */
+	read_aux,
+	write_aux,
+	NULL, 		/* readdir */
+	aux_poll,
+	NULL, 		/* ioctl */
+	NULL,		/* mmap */
+	open_aux,
+	NULL,		/* flush */
+	release_aux,
+	NULL,
+	fasync_aux,
+};
+
+/*
+ * Initialize driver.
+ */
+static struct miscdevice psaux_mouse = {
+	PSMOUSE_MINOR, "psaux", &psaux_fops
+};
+
+static int __init psaux_init(void)
+{
+	if (aux_device_present != 0xaa)
+		return -EIO;
+
+	printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n");
+	misc_register(&psaux_mouse);
+	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+	memset(queue, 0, sizeof(*queue));
+	queue->head = queue->tail = 0;
+	queue->proc_list = NULL;
+
+#ifdef INITIALIZE_MOUSE
+	kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG);	/* Enable Aux. */
+	aux_write_dev(AUX_SET_SAMPLE);
+	aux_write_dev(100);			/* 100 samples/sec */
+	aux_write_dev(AUX_SET_RES);
+	aux_write_dev(3);			/* 8 counts per mm */
+	aux_write_dev(AUX_SET_SCALE21);		/* 2:1 scaling */
+#endif /* INITIALIZE_MOUSE */
+	kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable aux device. */
+	kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
+
+	return 0;
+}
+
+#endif /* CONFIG_PSMOUSE */
diff -u --recursive --new-file v2.1.125/linux/drivers/char/pc_keyb.h linux/drivers/char/pc_keyb.h
--- v2.1.125/linux/drivers/char/pc_keyb.h	Sat Sep  5 16:46:40 1998
+++ linux/drivers/char/pc_keyb.h	Fri Oct  9 11:44:19 1998
@@ -14,6 +14,9 @@
 #define KBD_REPORT_UNKN			/* Report unknown scan codes */
 #define KBD_REPORT_TIMEOUTS		/* Report keyboard timeouts */
 #undef KBD_IS_FOCUS_9000		/* We have the brain-damaged FOCUS-9000 keyboard */
+#undef INITIALIZE_MOUSE			/* Define if your PS/2 mouse needs initialization. */
+
+
 
 #define KBD_INIT_TIMEOUT 1000		/* Timeout in ms for initializing the keyboard */
 #define KBC_TIMEOUT 250			/* Timeout in ms for sending to keyboard controller */
@@ -109,3 +112,13 @@
 #define AUX_ENABLE_DEV		0xF4	/* Enable aux device */
 #define AUX_DISABLE_DEV		0xF5	/* Disable aux device */
 #define AUX_RESET		0xFF	/* Reset aux device */
+
+#define AUX_BUF_SIZE		2048
+
+struct aux_queue {
+	unsigned long head;
+	unsigned long tail;
+	struct wait_queue *proc_list;
+	struct fasync_struct *fasync;
+	unsigned char buf[AUX_BUF_SIZE];
+};
diff -u --recursive --new-file v2.1.125/linux/drivers/char/psaux.c linux/drivers/char/psaux.c
--- v2.1.125/linux/drivers/char/psaux.c	Mon Sep 28 10:51:33 1998
+++ linux/drivers/char/psaux.c	Wed Dec 31 16:00:00 1969
@@ -1,452 +0,0 @@
-/*
- * linux/drivers/char/psaux.c
- *
- * Driver for PS/2 type mouse by Johan Myreen.
- *
- * Supports pointing devices attached to a PS/2 type
- * Keyboard and Auxiliary Device Controller.
- *
- * Corrections in device setup for some laptop mice & trackballs.
- * 02Feb93  (troyer@saifr00.cfsat.Honeywell.COM,mch@wimsey.bc.ca)
- *
- * Changed to prevent keyboard lockups on AST Power Exec.
- * 28Jul93  Brad Bosch - brad@lachman.com
- *
- * Added support for SIGIO. 28Jul95 jem@pandora.pp.fi
- *
- * 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
- * 3-Jul-96, 22-Aug-96 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
- *
- * Cleanup by Martin Mares, 01-Jun-97 (now uses the new PC kbd include)
- *
- * Renamed misc. name to "psaux",more in keeping with Documentation/devices.txt
- * 13-Jan-1998, Richard Gooch <rgooch@atnf.csiro.au>
- */
-
-/*
- * This really should be part of the pc_kbd driver - they share the same
- * controller, and right now we have ridiculous synchronization problems.
- * Some of the SMP bootup problems may be due to not getting synchronization
- * right.
- *
- * I moved the C&T mouse driver to a file of its own, hopefully that will
- * make it easier to eventually fix this all.
- *
- *		Linus
- */
-
-/* Uncomment the following line if your mouse needs initialization. */
-
-/* #define INITIALIZE_DEVICE */
-
-#include <linux/module.h>
- 
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/malloc.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/semaphore.h>
-
-#include <linux/config.h>
-
-#include "pc_keyb.h"
-
-/*
- *	Generic declarations for both PS2 and 82C710
- */
-
-#define PSMOUSE_MINOR      1	       		/* Minor device # for this mouse */
-#define AUX_BUF_SIZE	2048
-
-struct aux_queue {
-	unsigned long head;
-	unsigned long tail;
-	struct wait_queue *proc_list;
-	struct fasync_struct *fasync;
-	unsigned char buf[AUX_BUF_SIZE];
-};
-
-static struct aux_queue *queue;
-static int aux_count = 0;
-
-static unsigned int get_from_queue(void)
-{
-	unsigned int result;
-	unsigned long flags;
-
-	save_flags(flags);
-	cli();
-	result = queue->buf[queue->tail];
-	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
-	restore_flags(flags);
-	return result;
-}
-
-
-static inline int queue_empty(void)
-{
-	return queue->head == queue->tail;
-}
-
-static int fasync_aux(int fd, struct file *filp, int on)
-{
-	int retval;
-
-	retval = fasync_helper(fd, filp, on, &queue->fasync);
-	if (retval < 0)
-		return retval;
-	return 0;
-}
-
-/*
- *	PS/2 Aux Device
- */
-
-#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
-#define AUX_INTS_ON  (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
-
-#define MAX_RETRIES	60		/* some aux operations take long time*/
-#if defined(__alpha__) && !defined(CONFIG_PCI)
-# define AUX_IRQ	9		/* Jensen is odd indeed */
-#else
-# define AUX_IRQ	12
-#endif
-
-/*
- *	Status polling
- */
-
-static int poll_aux_status(void)
-{
-	int retries=0;
-
-	while ((inb(KBD_STATUS_REG) & (KBD_STAT_IBF | KBD_STAT_OBF)) && retries < MAX_RETRIES) {
- 		if ((inb_p(KBD_STATUS_REG) & AUX_STAT_OBF) == AUX_STAT_OBF)
-			inb_p(KBD_DATA_REG);
-		current->state = TASK_INTERRUPTIBLE;
-		current->timeout = jiffies + (5*HZ + 99) / 100;
-		schedule();
-		retries++;
-	}
-	return (retries < MAX_RETRIES);
-}
-
-/*
- * Write to aux device
- */
-
-static void aux_write_dev(int val)
-{
-	poll_aux_status();
-	outb_p(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG);	    /* Write magic cookie */
-	poll_aux_status();
-	outb_p(val, KBD_DATA_REG);			    /* Write data */
-}
-
-/*
- * Write to device & handle returned ack
- */
-
-#ifdef INITIALIZE_DEVICE
-__initfunc(static int aux_write_ack(int val))
-{
-	aux_write_dev(val);
-	poll_aux_status();
-
-	if ((inb(KBD_STATUS_REG) & AUX_STAT_OBF) == AUX_STAT_OBF)
-	{
-		return (inb(KBD_DATA_REG));
-	}
-	return 0;
-}
-#endif /* INITIALIZE_DEVICE */
-
-/*
- * Write aux device command
- */
-
-static void aux_write_cmd(int val)
-{
-	poll_aux_status();
-	outb_p(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG);
-	poll_aux_status();
-	outb_p(val, KBD_DATA_REG);
-}
-
-/*
- * AUX handler critical section start and end.
- * 
- * Only one process can be in the critical section and all keyboard sends are
- * deferred as long as we're inside. This is necessary as we may sleep when
- * waiting for the keyboard controller and other processes / BH's can
- * preempt us. Please note that the input buffer must be flushed when
- * aux_end_atomic() is called and the interrupt is no longer enabled as not
- * doing so might cause the keyboard driver to ignore all incoming keystrokes.
- */
-
-static struct semaphore aux_sema4 = MUTEX;
-
-static inline void aux_start_atomic(void)
-{
-	down(&aux_sema4);
-	disable_bh(KEYBOARD_BH);
-}
-
-static inline void aux_end_atomic(void)
-{
-	enable_bh(KEYBOARD_BH);
-	up(&aux_sema4);
-}
-
-/*
- * Interrupt from the auxiliary device: a character
- * is waiting in the keyboard/aux controller.
- */
-
-static void aux_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
-{
-	int head = queue->head;
-	int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
-
-	if ((inb(KBD_STATUS_REG) & AUX_STAT_OBF) != AUX_STAT_OBF)
-		return;
-
-	add_mouse_randomness(queue->buf[head] = inb(KBD_DATA_REG));
-	if (head != maxhead) {
-		head++;
-		head &= AUX_BUF_SIZE-1;
-	}
-	queue->head = head;
-	if (queue->fasync)
-		kill_fasync(queue->fasync, SIGIO);
-	wake_up_interruptible(&queue->proc_list);
-}
-
-static int release_aux(struct inode * inode, struct file * file)
-{
-	fasync_aux(-1, file, 0);
-	if (--aux_count)
-		return 0;
-#ifdef CONFIG_VT
-	pckbd_read_mask = KBD_STAT_OBF;
-#endif
-	aux_start_atomic();
-	aux_write_cmd(AUX_INTS_OFF);			    /* Disable controller ints */
-	poll_aux_status();
-	outb_p(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG);	    /* Disable Aux device */
-	poll_aux_status();
-	aux_end_atomic();
-#ifdef CONFIG_MCA
-	free_irq(AUX_IRQ, inode);
-#else
-	free_irq(AUX_IRQ, NULL);
-#endif
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-/*
- * Install interrupt handler.
- * Enable auxiliary device.
- */
-
-static int open_aux(struct inode * inode, struct file * file)
-{
-	aux_start_atomic();
-	if (aux_count++) {
-		aux_end_atomic();
-		return 0;
-	}
-	if (!poll_aux_status()) {		/* FIXME: Race condition */
-		aux_count--;
-		aux_end_atomic();
-		return -EBUSY;
-	}
-	queue->head = queue->tail = 0;		/* Flush input queue */
-#ifdef CONFIG_MCA
-	if (request_irq(AUX_IRQ, aux_interrupt, MCA_bus ? SA_SHIRQ : 0, "PS/2 Mouse", inode)) {
-#else
-	if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL)) {
-#endif
-		aux_count--;
-		aux_end_atomic();
-		return -EBUSY;
-	}
-	MOD_INC_USE_COUNT;
-	poll_aux_status();
-	outb_p(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG);	    /* Enable Aux */
-	aux_write_dev(AUX_ENABLE_DEV);			    /* Enable aux device */
-	aux_write_cmd(AUX_INTS_ON);			    /* Enable controller ints */
-	poll_aux_status();
-	aux_end_atomic();
-
-#ifdef CONFIG_VT
-	pckbd_read_mask = AUX_STAT_OBF;
-#endif
-
-	return 0;
-}
-
-/*
- * Write to the aux device.
- */
-
-static ssize_t write_aux(struct file * file, const char * buffer,
-			 size_t count, loff_t *ppos)
-{
-	ssize_t retval = 0;
-
-	if (count) {
-		ssize_t written = 0;
-
-		aux_start_atomic();
-		do {
-			char c;
-			if (!poll_aux_status())
-				break;
-			outb_p(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG);
-			if (!poll_aux_status())
-				break;
-			get_user(c, buffer++);
-			outb_p(c, KBD_DATA_REG);
-			written++;
-		} while (--count);
-		aux_end_atomic();
-		retval = -EIO;
-		if (written) {
-			retval = written;
-			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
-		}
-	}
-
-	return retval;
-}
-
-/*
- * Put bytes from input queue to buffer.
- */
-
-static ssize_t read_aux(struct file * file, char * buffer,
-			size_t count, loff_t *ppos)
-{
-	struct wait_queue wait = { current, NULL };
-	ssize_t i = count;
-	unsigned char c;
-
-	if (queue_empty()) {
-		if (file->f_flags & O_NONBLOCK)
-			return -EAGAIN;
-		add_wait_queue(&queue->proc_list, &wait);
-repeat:
-		current->state = TASK_INTERRUPTIBLE;
-		if (queue_empty() && !signal_pending(current)) {
-			schedule();
-			goto repeat;
-		}
-		current->state = TASK_RUNNING;
-		remove_wait_queue(&queue->proc_list, &wait);
-	}
-	while (i > 0 && !queue_empty()) {
-		c = get_from_queue();
-		put_user(c, buffer++);
-		i--;
-	}
-	if (count-i) {
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-		return count-i;
-	}
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-static unsigned int aux_poll(struct file *file, poll_table * wait)
-{
-	poll_wait(file, &queue->proc_list, wait);
-	if (!queue_empty())
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-
-struct file_operations psaux_fops = {
-	NULL,		/* seek */
-	read_aux,
-	write_aux,
-	NULL, 		/* readdir */
-	aux_poll,
-	NULL, 		/* ioctl */
-	NULL,		/* mmap */
-	open_aux,
-	NULL,		/* flush */
-	release_aux,
-	NULL,
-	fasync_aux,
-};
-
-/*
- * Initialize driver.
- */
-static struct miscdevice psaux_mouse = {
-	PSMOUSE_MINOR, "psaux", &psaux_fops
-};
-
-__initfunc(int psaux_init(void))
-{
-	if (aux_device_present != 0xaa)
-		return -EIO;
-
-	printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n");
-	misc_register(&psaux_mouse);
-	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
-	memset(queue, 0, sizeof(*queue));
-	queue->head = queue->tail = 0;
-	queue->proc_list = NULL;
-
-	aux_start_atomic();
-#ifdef INITIALIZE_DEVICE
-	outb_p(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux */
-	aux_write_ack(AUX_SET_SAMPLE);
-	aux_write_ack(100);			/* 100 samples/sec */
-	aux_write_ack(AUX_SET_RES);
-	aux_write_ack(3);			/* 8 counts per mm */
-	aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
-	poll_aux_status();
-#endif /* INITIALIZE_DEVICE */
-	outb_p(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable Aux device */
-	poll_aux_status();
-	outb_p(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG);    /* Disable controller interrupts */
-	poll_aux_status();
-	outb_p(AUX_INTS_OFF, KBD_DATA_REG);
-	poll_aux_status();
-	aux_end_atomic();
-
-	return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-	return psaux_init();
-}
-
-void cleanup_module(void)
-{
-	misc_deregister(&psaux_mouse);
-	kfree(queue);
-}
-#endif
diff -u --recursive --new-file v2.1.125/linux/drivers/char/qpmouse.c linux/drivers/char/qpmouse.c
--- v2.1.125/linux/drivers/char/qpmouse.c	Mon Sep 28 10:51:33 1998
+++ linux/drivers/char/qpmouse.c	Fri Oct  9 11:44:19 1998
@@ -8,15 +8,15 @@
  * Corrections in device setup for some laptop mice & trackballs.
  * 02Feb93  (troyer@saifr00.cfsat.Honeywell.COM,mch@wimsey.bc.ca)
  *
- * Modified by Johan Myreen (jem@pandora.pp.fi) 04Aug93
+ * Modified by Johan Myreen (jem@iki.fi) 04Aug93
  *   to include support for QuickPort mouse.
  *
  * Changed references to "QuickPort" with "82C710" since "QuickPort"
  * is not what this driver is all about -- QuickPort is just a
  * connector type, and this driver is for the mouse port on the Chips
- * & Technologies 82C710 interface chip. 15Nov93 jem@pandora.pp.fi
+ * & Technologies 82C710 interface chip. 15Nov93 jem@iki.fi
  *
- * Added support for SIGIO. 28Jul95 jem@pandora.pp.fi
+ * Added support for SIGIO. 28Jul95 jem@iki.fi
  *
  * Rearranged SIGIO support to use code from tty_io.  9Sept95 ctm@ardi.com
  *
diff -u --recursive --new-file v2.1.125/linux/drivers/char/stallion.c linux/drivers/char/stallion.c
--- v2.1.125/linux/drivers/char/stallion.c	Wed Aug 26 11:37:37 1998
+++ linux/drivers/char/stallion.c	Fri Oct 23 08:26:04 1998
@@ -144,7 +144,7 @@
  */
 static char	*stl_drvtitle = "Stallion Multiport Serial Driver";
 static char	*stl_drvname = "stallion";
-static char	*stl_drvversion = "5.4.6";
+static char	*stl_drvversion = "5.4.7";
 static char	*stl_serialname = "ttyE";
 static char	*stl_calloutname = "cue";
 
@@ -664,17 +664,21 @@
  *	to get at port stats - only not using the port device itself.
  */
 static struct file_operations	stl_fsiomem = {
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	stl_memioctl,
-	NULL,
-	stl_memopen,
+	NULL,		/* llseek */
+	NULL,		/* read */
+	NULL,		/* write */
+	NULL,		/* readdir */
+	NULL,		/* poll */
+	stl_memioctl,	/* ioctl */
+	NULL,		/* mmap */
+	stl_memopen,	/* open */
 	NULL,		/* flush */
-	stl_memclose,
-	NULL
+	stl_memclose,	/* release */
+	NULL,		/* fsync */
+	NULL,		/* fasync */
+	NULL,		/* check_media_change */
+	NULL,		/* revalidate */
+	NULL		/* lock */
 };
 
 /*****************************************************************************/
diff -u --recursive --new-file v2.1.125/linux/drivers/char/sysrq.c linux/drivers/char/sysrq.c
--- v2.1.125/linux/drivers/char/sysrq.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/sysrq.c	Wed Oct 14 11:43:13 1998
@@ -168,7 +168,14 @@
 	case IDE1_MAJOR:
 	case IDE2_MAJOR:
 	case IDE3_MAJOR:
-	case SCSI_DISK_MAJOR:
+	case SCSI_DISK0_MAJOR:
+	case SCSI_DISK1_MAJOR:
+	case SCSI_DISK2_MAJOR:
+	case SCSI_DISK3_MAJOR:
+	case SCSI_DISK4_MAJOR:
+	case SCSI_DISK5_MAJOR:
+	case SCSI_DISK6_MAJOR:
+	case SCSI_DISK7_MAJOR:
 		return 1;
 	default:
 		return 0;
diff -u --recursive --new-file v2.1.125/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- v2.1.125/linux/drivers/char/tpqic02.c	Wed Aug 26 11:37:37 1998
+++ linux/drivers/char/tpqic02.c	Fri Oct  9 11:56:59 1998
@@ -1360,6 +1360,7 @@
  */ 
 static inline void dma_transfer(void)
 {
+	unsigned long flags;
 
 	if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
 		outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT);	/* back to normal */
@@ -1369,6 +1370,7 @@
 		outb_p(ctlbits, QIC02_CTL_PORT);
 
 
+	flags=claim_dma_lock();
 	clear_dma_ff(QIC02_TAPE_DMA);
 	set_dma_mode(QIC02_TAPE_DMA, dma_mode);
 	set_dma_addr(QIC02_TAPE_DMA, buffaddr+dma_bytes_done);	/* full address */
@@ -1393,6 +1395,9 @@
 
 	/* start computer DMA controller */
 	enable_dma(QIC02_TAPE_DMA);
+
+	release_dma_lock(flags);
+
 	/* block transfer should start now, jumping to the 
 	 * interrupt routine when done or an exception was detected.
 	 */
@@ -1410,6 +1415,7 @@
 /* assume 'bytes_todo'>0 */
 {
 	int stat;
+	unsigned long flags;
 	
 	tpqputs(TPQD_DEBUG, "start_dma() enter");
 	TPQDEB({printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n", doing_read, doing_write);})
@@ -1506,9 +1512,10 @@
 
 	/* initiate first data block read from/write to the tape controller */
 
+	save_flags(flags);
 	cli();
 	dma_transfer();
-	sti();
+	restore_flags(flags);
 
 	TPQPUTS("start_dma() end");
 	return TE_OK;
@@ -1524,13 +1531,18 @@
 static void end_dma(unsigned long * bytes_done)
 {
 	int stat = TE_OK;
+	unsigned long flags;
 
 	TIMEROFF;
 
 	TPQPUTS("end_dma() enter");
 
+	flags=claim_dma_lock();
+	
 	disable_dma(QIC02_TAPE_DMA);
 	clear_dma_ff(QIC02_TAPE_DMA);
+	
+	release_dma_lock(flags);
 
 	if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
 		outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT);	/* back to normal */
@@ -1633,6 +1645,7 @@
 static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int stat, r, i;
+	unsigned long flags;
 
 	TIMEROFF;
 
@@ -1682,10 +1695,14 @@
 				r = 1;
 			}
 
+		flags=claim_dma_lock();
+		
 		if ( (i = get_dma_residue(QIC02_TAPE_DMA)) != 0 ) {
 			printk(TPQIC02_NAME ": dma_residue == %x !!!\n", i);
 			r = 1;	/* big trouble, but can't do much about it... */
 		}
+		
+		release_dma_lock(flags);
 
 		if (r) 
 			return;
diff -u --recursive --new-file v2.1.125/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v2.1.125/linux/drivers/char/tty_io.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/tty_io.c	Tue Oct 13 11:42:18 1998
@@ -1132,7 +1132,6 @@
 	 * both sides, and we've completed the last operation that could 
 	 * block, so it's safe to proceed with closing.
 	 */
-
 	if (pty_master) {
 		if (--o_tty->count < 0) {
 			printk("release_dev: bad pty slave count (%d) for %s\n",
@@ -1147,6 +1146,16 @@
 	}
 
 	/*
+	 * We've decremented tty->count, so we should zero out
+	 * filp->private_data, to break the link between the tty and
+	 * the file descriptor.  Otherwise if close_fp() blocks before
+	 * the the file descriptor is removed from the inuse_filp
+	 * list, check_tty_count() could observe a discrepancy and
+	 * printk a warning message to the user.
+	 */
+	filp->private_data = 0;
+
+	/*
 	 * Perform some housekeeping before deciding whether to return.
 	 *
 	 * Set the TTY_CLOSING flag if this was the last open.  In the
@@ -1180,7 +1189,6 @@
 	/* check whether both sides are closing ... */
 	if (!tty_closing || (o_tty && !o_tty_closing))
 		return;
-	filp->private_data = 0;
 	
 #ifdef TTY_DEBUG_HANGUP
 	printk("freeing tty structure...");
@@ -1293,7 +1301,6 @@
 		return retval;
 
 #ifdef CONFIG_UNIX98_PTYS
-	/* N.B. this error exit may leave filp->f_flags with O_NONBLOCK set */
 init_dev_done:
 #endif
 	filp->private_data = tty;
@@ -2084,6 +2091,7 @@
 	if (tty_register_driver(&dev_syscons_driver))
 		panic("Couldn't register /dev/console driver\n");
 
+#ifdef CONFIG_UNIX98_PTYS
 	dev_ptmx_driver = dev_tty_driver;
 	dev_ptmx_driver.driver_name = "/dev/ptmx";
 	dev_ptmx_driver.name = dev_ptmx_driver.driver_name + 5;
@@ -2094,7 +2102,8 @@
 
 	if (tty_register_driver(&dev_ptmx_driver))
 		panic("Couldn't register /dev/ptmx driver\n");
-
+#endif
+	
 #ifdef CONFIG_VT
 	dev_console_driver = dev_tty_driver;
 	dev_console_driver.driver_name = "/dev/tty0";
diff -u --recursive --new-file v2.1.125/linux/drivers/char/videodev.c linux/drivers/char/videodev.c
--- v2.1.125/linux/drivers/char/videodev.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/char/videodev.c	Sat Oct 17 15:52:18 1998
@@ -53,6 +53,9 @@
 #ifdef CONFIG_VIDEO_BWQCAM
 extern int init_bw_qcams(struct video_init *);
 #endif
+#ifdef CONFIG_VIDEO_PLANB
+extern int init_planbs(struct video_init *);
+#endif
 #ifdef CONFIG_RADIO_AZTECH
 extern int aztech_init(struct video_init *);
 #endif
@@ -83,6 +86,9 @@
 #ifdef CONFIG_VIDEO_PMS
 	{"PMS", init_pms_cards}, 
 #endif	
+#ifdef CONFIG_VIDEO_PLANB
+	{"planb", init_planbs},
+#endif
 #ifdef CONFIG_RADIO_AZTECH
 	{"Aztech", aztech_init}, 
 #endif	
diff -u --recursive --new-file v2.1.125/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v2.1.125/linux/drivers/char/wdt.c	Wed Aug 26 11:37:37 1998
+++ linux/drivers/char/wdt.c	Sat Oct 17 15:52:18 1998
@@ -23,6 +23,7 @@
  *		Alan Cox	:	Fixed the reboot problem (as noted by
  *					Matt Crocker).
  *		Alan Cox	:	Added wdt= boot option
+ *		Alan Cox	:	Cleaned up copy/user stuff
  */
 
 #include <linux/config.h>
@@ -191,7 +192,6 @@
 {
 	unsigned short c=inb_p(WDT_RT);
 	unsigned char cp;
-	int err;
 	
 	/*  Can't seek (pread) on this device  */
 	if (ptr != &file->f_pos)
@@ -200,13 +200,11 @@
 	switch(MINOR(file->f_dentry->d_inode->i_rdev))
 	{
 		case TEMP_MINOR:
-			err=verify_area(VERIFY_WRITE, buf, 1);
-			if(err)
-				return err;
 			c*=11;
 			c/=15;
 			cp=c+7;
-			copy_to_user(buf,&cp,1);
+			if(copy_to_user(buf,&cp,1))
+				return -EFAULT;
 			return 1;
 		default:
 			return -EINVAL;
@@ -216,7 +214,6 @@
 static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	unsigned long arg)
 {
-	int i;
 	static struct watchdog_info ident=
 	{
 		WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER
@@ -231,20 +228,10 @@
 		default:
 			return -ENOIOCTLCMD;
 		case WDIOC_GETSUPPORT:
-			i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
-			if (i)
-				return i;
-			else
-				return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
+			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
 
 		case WDIOC_GETSTATUS:
-			i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(int));
-			if (i)
-				return i;
-			else 
-			{
-				return put_user(wdt_status(),(int *)arg);
-			}
+			return put_user(wdt_status(),(int *)arg);
 		case WDIOC_GETBOOTSTATUS:
 			return put_user(0, (int *)arg);
 		case WDIOC_KEEPALIVE:
diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_arc.c linux/drivers/misc/parport_arc.c
--- v2.1.125/linux/drivers/misc/parport_arc.c	Tue Jul 21 00:15:31 1998
+++ linux/drivers/misc/parport_arc.c	Fri Oct  9 12:20:27 1998
@@ -33,6 +33,11 @@
 /* ARC can't read from the data latch, so we must use a soft copy. */
 static unsigned char data_copy;
 
+static void arc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	parport_generic_irq(irq, (struct parport *) dev_id, regs);
+}
+
 static void arc_write_data(struct parport *p, unsigned char data)
 {
 	data_copy = data;
@@ -110,7 +115,7 @@
 
 	arc_enable_irq,
 	arc_disable_irq,
-	arc_examine_irq,
+	arc_interrupt,
 
 	arc_inc_use_count,
 	arc_dec_use_count,
diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_ax.c linux/drivers/misc/parport_ax.c
--- v2.1.125/linux/drivers/misc/parport_ax.c	Thu Aug  6 14:06:32 1998
+++ linux/drivers/misc/parport_ax.c	Fri Oct  9 12:20:27 1998
@@ -50,10 +50,9 @@
 #define CONFIGB		0x401
 #define ECONTROL	0x402
 
-static void
-parport_ax_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
+static void parport_ax_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	/* NULL function - Does nothing */
+	parport_generic_irq(irq, (struct parport *) dev_id, regs);
 }
 
 void
@@ -206,7 +205,7 @@
 {
 	if (p->irq != PARPORT_IRQ_NONE) {
 		parport_ax_disable_irq(p);
-		free_irq(p->irq, NULL);
+		free_irq(p->irq, p);
 	}
 	release_region(p->base, p->size);
 	if (p->modes & PARPORT_MODE_PCECR)
@@ -219,11 +218,15 @@
 parport_ax_claim_resources(struct parport *p)
 {
 	/* FIXME check that resources are free */
-	if (p->irq != PARPORT_IRQ_NONE) {
-		request_irq(p->irq, parport_ax_null_intr_func,
-			    0, p->name, NULL);
-		parport_ax_enable_irq(p);
-	}
+	int err;
+
+	if (p->irq != PARPORT_IRQ_NONE)
+		if ((err = request_irq(p->irq, parport_ax_interrupt,
+				       0, p->name, p)) != 0)
+			return err;
+		else
+			parport_ax_enable_irq(p);
+
 	request_region(p->base, p->size, p->name);
 	if (p->modes & PARPORT_MODE_PCECR)
 		request_region(p->base+0x400, 3, p->name);
@@ -281,12 +284,6 @@
 	return 0; /* FIXME */
 }
 
-int
-parport_ax_examine_irq(struct parport *p)
-{
-	return 0; /* FIXME */
-}
-
 void
 parport_ax_inc_use_count(void)
 {
@@ -355,7 +352,7 @@
 
 	parport_ax_enable_irq,
 	parport_ax_disable_irq,
-	parport_ax_examine_irq,
+	parport_ax_interrupt,
 
 	parport_ax_inc_use_count,
 	parport_ax_dec_use_count,
diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
--- v2.1.125/linux/drivers/misc/parport_pc.c	Wed Sep  9 14:51:07 1998
+++ linux/drivers/misc/parport_pc.c	Fri Oct  9 12:20:27 1998
@@ -1,4 +1,4 @@
-/* Low-level parallel-port routines for PC-style hardware.
+/* Low-level parallel-port routines for 8255-based PC-style hardware.
  * 
  * Authors: Phil Blundell <Philip.Blundell@pobox.com>
  *          Tim Waugh <tim@cyberelk.demon.co.uk>
@@ -32,13 +32,8 @@
  * accomodate this.
  */
 
-#include <linux/stddef.h>
-#include <linux/tasks.h>
-
-#include <asm/ptrace.h>
-#include <asm/io.h>
-
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -46,6 +41,8 @@
 #include <linux/kernel.h>
 #include <linux/malloc.h>
 
+#include <asm/io.h>
+
 #include <linux/parport.h>
 #include <linux/parport_pc.h>
 
@@ -53,9 +50,9 @@
    than PARPORT_MAX (in <linux/parport.h>).  */
 #define PARPORT_PC_MAX_PORTS  8
 
-static void parport_pc_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
+static void parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	/* Null function - does nothing */
+	parport_generic_irq(irq, (struct parport *) dev_id, regs);
 }
 
 void parport_pc_write_epp(struct parport *p, unsigned char d)
@@ -173,7 +170,7 @@
 void parport_pc_release_resources(struct parport *p)
 {
 	if (p->irq != PARPORT_IRQ_NONE)
-		free_irq(p->irq, NULL);
+		free_irq(p->irq, p);
 	release_region(p->base, p->size);
 	if (p->modes & PARPORT_MODE_PCECR)
 		release_region(p->base+0x400, 3);
@@ -183,7 +180,9 @@
 {
 	int err;
 	if (p->irq != PARPORT_IRQ_NONE)
-		if ((err = request_irq(p->irq, parport_pc_null_intr_func, 0, p->name, NULL)) != 0) return err;
+		if ((err = request_irq(p->irq, parport_pc_interrupt,
+				       0, p->name, p)) != 0)
+			return err;
 	request_region(p->base, p->size, p->name);
 	if (p->modes & PARPORT_MODE_PCECR)
 		request_region(p->base+0x400, 3, p->name);
@@ -242,11 +241,6 @@
 	return -ENOSYS; /* FIXME */
 }
 
-int parport_pc_examine_irq(struct parport *p)
-{
-	return 0; /* FIXME */
-}
-
 void parport_pc_inc_use_count(void)
 {
 #ifdef MODULE
@@ -313,7 +307,7 @@
 
 	parport_pc_enable_irq,
 	parport_pc_disable_irq,
-	parport_pc_examine_irq,
+	parport_pc_interrupt,
 
 	parport_pc_inc_use_count,
 	parport_pc_dec_use_count,
diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_procfs.c linux/drivers/misc/parport_procfs.c
--- v2.1.125/linux/drivers/misc/parport_procfs.c	Wed Sep  9 14:51:07 1998
+++ linux/drivers/misc/parport_procfs.c	Fri Oct  9 12:20:27 1998
@@ -29,16 +29,13 @@
 
 struct proc_dir_entry *base = NULL;
 
-extern void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs);
-
 static int irq_write_proc(struct file *file, const char *buffer,
-					  unsigned long count, void *data)
+			  unsigned long count, void *data)
 {
 	int retval = -EINVAL;
 	int newirq = PARPORT_IRQ_NONE;
 	struct parport *pp = (struct parport *)data;
 	int oldirq = pp->irq;
-	unsigned long flags;
 
 /*
  * We can have these valid cases:
@@ -70,30 +67,44 @@
 	if (oldirq == newirq)
 		goto out;
 
-	spin_lock_irqsave(&pp->lock, flags);
 	if (pp->flags & PARPORT_FLAG_COMA)
 		goto out_ok;
 
 	retval = -EBUSY;
+
+	/*
+	 * Here we don' t need the irq version of spinlocks because
+	 * the parport_lowlevel irq handler must not change the cad,
+	 * and so has no one reason to write_lock() the cad_lock spinlock.
+	 *						-arca
+	 */
+	read_lock(&pp->cad_lock);
+
 	if (pp->cad)
-		goto out_unlock;
+	{
+		read_unlock(&pp->cad_lock);
+		return retval;
+	}
 
 	if (newirq != PARPORT_IRQ_NONE) { 
-		retval = request_irq(newirq, parport_null_intr_func,
-				     SA_INTERRUPT, pp->name, NULL);
+		retval = request_irq(newirq, pp->ops->interrupt,
+				     0, pp->name, pp);
 		if (retval)
-			goto out_unlock;
-		else retval = count;
+		{
+			read_unlock(&pp->cad_lock);
+			return retval;
+		}
 	}
 
 	if (oldirq != PARPORT_IRQ_NONE)
-		free_irq(oldirq, NULL);
+		free_irq(oldirq, pp);
+
+	retval = count;
+
+	read_unlock(&pp->cad_lock);
 
 out_ok:
 	pp->irq = newirq;
-
-out_unlock:
-	spin_unlock_irqrestore (&pp->lock, flags);
 
 out:
 	return retval;
diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c
--- v2.1.125/linux/drivers/misc/parport_share.c	Wed Sep  9 14:51:07 1998
+++ linux/drivers/misc/parport_share.c	Fri Oct  9 12:20:27 1998
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 
 #include <asm/spinlock.h>
+#include <asm/irq.h>
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
@@ -55,19 +56,12 @@
 	return portlist;
 }
 
-void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
-{
-	/* Null function - does nothing.  IRQs are pointed here whenever
-	   there is no real handler for them.  */
-}
-
 struct parport *parport_register_port(unsigned long base, int irq, int dma,
 				      struct parport_operations *ops)
 {
 	struct parport *tmp;
 	int portnum;
 	char *name;
-	unsigned long flags;
 
 	/* Check for a previously registered port.
 	   NOTE: we will ignore irq and dma if we find a previously
@@ -111,7 +105,9 @@
 	tmp->ops = ops;
 	tmp->number = portnum;
 	memset (&tmp->probe_info, 0, sizeof (struct parport_device_info));
-	spin_lock_init (&tmp->lock);
+	spin_lock_init(&tmp->cad_lock);
+	spin_lock_init(&tmp->waitlist_lock);
+	spin_lock_init(&tmp->pardevice_lock);
 
 	name = kmalloc(15, GFP_KERNEL);
 	if (!name) {
@@ -122,14 +118,19 @@
 	sprintf(name, "parport%d", portnum);
 	tmp->name = name;
 
-	/* Chain the entry to our list. */
-	spin_lock_irqsave (&parportlist_lock, flags);
+	/*
+	 * Chain the entry to our list.
+	 *
+	 * This function must not run from an irq handler so we don' t need
+	 * to clear irq on the local CPU. -arca
+	 */
+	spin_lock(&parportlist_lock);
 	if (portlist_tail)
 		portlist_tail->next = tmp;
 	portlist_tail = tmp;
 	if (!portlist)
 		portlist = tmp;
-	spin_unlock_irqrestore (&parportlist_lock, flags);
+	spin_unlock(&parportlist_lock);
 
 	tmp->probe_info.class = PARPORT_CLASS_LEGACY;  /* assume the worst */
 	tmp->waithead = tmp->waittail = NULL;
@@ -140,8 +141,8 @@
 void parport_unregister_port(struct parport *port)
 {
 	struct parport *p;
-	unsigned long flags;
-	spin_lock_irqsave (&parportlist_lock, flags);
+
+	spin_lock(&parportlist_lock);
 	if (portlist == port) {
 		if ((portlist = port->next) == NULL)
 			portlist_tail = NULL;
@@ -155,7 +156,7 @@
 		else printk (KERN_WARNING
 			     "%s not found in port list!\n", port->name);
 	}
-	spin_unlock_irqrestore (&parportlist_lock, flags);
+	spin_unlock(&parportlist_lock);
 	if (port->probe_info.class_name)
 		kfree (port->probe_info.class_name);
 	if (port->probe_info.mfr)
@@ -195,7 +196,13 @@
 			  int flags, void *handle)
 {
 	struct pardevice *tmp;
-	unsigned long flgs;
+
+	if (port->flags & PARPORT_FLAG_EXCL) {
+		/* An exclusive device is registered. */
+		printk (KERN_DEBUG "%s: no more devices allowed\n",
+			port->name);
+		return NULL;
+	}
 
 	if (flags & PARPORT_DEV_LURK) {
 		if (!pf || !kf) {
@@ -242,12 +249,30 @@
 
 	/* Chain this onto the list */
 	tmp->prev = NULL;
-	spin_lock_irqsave (&port->lock, flgs);
+	/*
+	 * This function must not run from an irq handler so we don' t need
+	 * to clear irq on the local CPU. -arca
+	 */
+	spin_lock(&port->pardevice_lock);
+
+	if (flags & PARPORT_DEV_EXCL) {
+		if (port->devices) {
+			spin_unlock (&port->pardevice_lock);
+			kfree (tmp->state);
+			kfree (tmp);
+			printk (KERN_DEBUG
+				"%s: cannot grant exclusive access for "
+				"device %s\n", port->name, name);
+			return NULL;
+		}
+		port->flags |= PARPORT_FLAG_EXCL;
+	}
+
 	tmp->next = port->devices;
 	if (port->devices)
 		port->devices->prev = tmp;
 	port->devices = tmp;
-	spin_unlock_irqrestore (&port->lock, flgs);
+	spin_unlock(&port->pardevice_lock);
 
 	inc_parport_count();
 	port->ops->inc_use_count();
@@ -262,7 +287,6 @@
 void parport_unregister_device(struct pardevice *dev)
 {
 	struct parport *port;
-	unsigned long flags;
 
 #ifdef PARPORT_PARANOID
 	if (dev == NULL) {
@@ -279,14 +303,18 @@
 		return;
 	}
 
-	spin_lock_irqsave (&port->lock, flags);
+	spin_lock(&port->pardevice_lock);
 	if (dev->next)
 		dev->next->prev = dev->prev;
 	if (dev->prev)
 		dev->prev->next = dev->next;
 	else
 		port->devices = dev->next;
-	spin_unlock_irqrestore (&port->lock, flags);
+
+	if (dev->flags & PARPORT_DEV_EXCL)
+		port->flags &= ~PARPORT_FLAG_EXCL;
+
+	spin_unlock(&port->pardevice_lock);
 
 	kfree(dev->state);
 	kfree(dev);
@@ -337,7 +365,7 @@
 		dev->waiting = 0;
 
 		/* Take ourselves out of the wait list again.  */
-		spin_lock_irqsave (&port->lock, flags);
+		spin_lock_irqsave (&port->waitlist_lock, flags);
 		if (dev->waitprev)
 			dev->waitprev->waitnext = dev->waitnext;
 		else
@@ -346,28 +374,27 @@
 			dev->waitnext->waitprev = dev->waitprev;
 		else
 			port->waittail = dev->waitprev;
-		spin_unlock_irqrestore (&port->lock, flags);
+		spin_unlock_irqrestore (&port->waitlist_lock, flags);
 		dev->waitprev = dev->waitnext = NULL;
 	}
 
+	if (oldcad && port->irq != PARPORT_IRQ_NONE && !oldcad->irq_func)
+		/*
+		 * If there was an irq pending it should hopefully happen
+		 * before return from enable_irq(). -arca
+		 */
+		enable_irq(port->irq);
+
+	/*
+	 * Avoid running irq handlers if the pardevice doesn' t use it. -arca
+	 */
+	if (port->irq != PARPORT_IRQ_NONE && !dev->irq_func)
+		disable_irq(port->irq);
+
 	/* Now we do the change of devices */
-	spin_lock_irqsave(&port->lock, flags);
+	write_lock_irqsave(&port->cad_lock, flags);
 	port->cad = dev;
-	spin_unlock_irqrestore(&port->lock, flags);
-
-	/* Swap the IRQ handlers. */
-	if (port->irq != PARPORT_IRQ_NONE) {
-		if (oldcad && oldcad->irq_func) {
-			free_irq(port->irq, oldcad->private);
-			request_irq(port->irq, parport_null_intr_func,
-				    SA_INTERRUPT, port->name, NULL);
-		}
-		if (dev->irq_func) {
-			free_irq(port->irq, NULL);
-			request_irq(port->irq, dev->irq_func,
-				    SA_INTERRUPT, dev->name, dev->private);
-		}
-	}
+	write_unlock_irqrestore(&port->cad_lock, flags);
 
 	/* Restore control registers */
 	port->ops->restore_state(port, dev->state);
@@ -379,10 +406,10 @@
 	   interest.  This is only allowed for devices sleeping in
 	   parport_claim_or_block(), or those with a wakeup function.  */
 	if (dev->waiting & 2 || dev->wakeup) {
-		spin_lock_irqsave (&port->lock, flags);
+		spin_lock_irqsave (&port->waitlist_lock, flags);
 		if (port->cad == NULL) {
 			/* The port got released in the meantime. */
-			spin_unlock_irqrestore (&port->lock, flags);
+			spin_unlock_irqrestore (&port->waitlist_lock, flags);
 			goto try_again;
 		}
 		if (test_and_set_bit(0, &dev->waiting) == 0) {
@@ -395,7 +422,7 @@
 			} else
 				port->waithead = port->waittail = dev;
 		}
-		spin_unlock_irqrestore (&port->lock, flags);
+		spin_unlock_irqrestore (&port->waitlist_lock, flags);
 	}
 	return -EAGAIN;
 }
@@ -451,19 +478,19 @@
 		       "when not owner\n", port->name, dev->name);
 		return;
 	}
-	spin_lock_irqsave(&port->lock, flags);
+	write_lock_irqsave(&port->cad_lock, flags);
 	port->cad = NULL;
-	spin_unlock_irqrestore(&port->lock, flags);
+	write_unlock_irqrestore(&port->cad_lock, flags);
+
+	/*
+	 * Reenable irq and so discard the eventually pending irq while
+	 * cad is NULL. -arca
+	 */
+	if (port->irq != PARPORT_IRQ_NONE && !dev->irq_func)
+		enable_irq(port->irq);
 
 	/* Save control registers */
 	port->ops->save_state(port, dev->state);
-
-	/* Point IRQs somewhere harmless. */
-	if (port->irq != PARPORT_IRQ_NONE && dev->irq_func) {
-		free_irq(port->irq, dev->private);
-		request_irq(port->irq, parport_null_intr_func,
-			    SA_INTERRUPT, port->name, NULL);
- 	}
 
 	/* If anybody is waiting, find out who's been there longest and
 	   then wake them up. (Note: no locking required) */
diff -u --recursive --new-file v2.1.125/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v2.1.125/linux/drivers/net/3c505.c	Wed Jun 24 22:54:06 1998
+++ linux/drivers/net/3c505.c	Fri Oct  9 11:56:59 1998
@@ -327,13 +327,17 @@
 {
 	elp_device *adapter = dev->priv;
 	if (adapter->dmaing && (jiffies > (adapter->current_dma.start_time + 10))) {
-		unsigned long flags;
+		unsigned long flags, f;
 		printk("%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
 		save_flags(flags);
 		cli();
 		adapter->dmaing = 0;
 		adapter->busy = 0;
+		
+		f=claim_dma_lock();
 		disable_dma(dev->dma);
+		release_dma_lock(f);
+		
 		if (adapter->rx_active)
 			adapter->rx_active--;
 		outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
@@ -601,6 +605,7 @@
 	elp_device *adapter = dev->priv;
 	void *target;
 	struct sk_buff *skb;
+	unsigned long flags;
 
 	rlen = (len + 1) & ~1;
 	skb = dev_alloc_skb(rlen + 2);
@@ -632,12 +637,14 @@
 
 	outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev);
 
+	flags=claim_dma_lock();
 	disable_dma(dev->dma);
 	clear_dma_ff(dev->dma);
 	set_dma_mode(dev->dma, 0x04);	/* dma read */
 	set_dma_addr(dev->dma, virt_to_bus(target));
 	set_dma_count(dev->dma, rlen);
 	enable_dma(dev->dma);
+	release_dma_lock(flags);
 
 	if (elp_debug >= 3) {
 		printk("%s: rx DMA transfer started\n", dev->name);
@@ -1019,6 +1026,7 @@
 {
 	elp_device *adapter = dev->priv;
 	unsigned long target;
+	unsigned long flags;
 
 	/*
 	 * make sure the length is even and no shorter than 60 bytes
@@ -1060,7 +1068,8 @@
 		target = virt_to_bus(adapter->dma_buffer);
 	}
 	adapter->current_dma.skb = skb;
-	cli();
+
+	flags=claim_dma_lock();
 	disable_dma(dev->dma);
 	clear_dma_ff(dev->dma);
 	set_dma_mode(dev->dma, 0x48);	/* dma memory -> io */
@@ -1068,6 +1077,8 @@
 	set_dma_count(dev->dma, nlen);
 	outb_control(adapter->hcr_val | DMAE | TCEN, dev);
 	enable_dma(dev->dma);
+	release_dma_lock(flags);
+	
 	if (elp_debug >= 3)
 		printk("%s: DMA transfer started\n", dev->name);
 
diff -u --recursive --new-file v2.1.125/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v2.1.125/linux/drivers/net/3c509.c	Tue Aug 18 22:02:04 1998
+++ linux/drivers/net/3c509.c	Sat Oct 17 15:33:45 1998
@@ -178,28 +178,64 @@
 	}
 
 #ifdef CONFIG_MCA
-#warning "The MCA code in drivers/net/3c509.c does not compile"
-#warning "See http://glycerine.itsmm.uni.edu/mca/ for patches."
-#if 0   
-	if (MCA_bus) {
-		mca_adaptor_select_mode(1);
-		for (i = 0; i < 8; i++)
-			if ((mca_adaptor_id(i) | 1) == 0x627c) {
-				ioaddr = mca_pos_base_addr(i);
-				irq = inw(ioaddr + WN0_IRQ) >> 12;
-				if_port = inw(ioaddr + 6)>>14;
-				for (i = 0; i < 3; i++)
-					phys_addr[i] = htons(read_eeprom(ioaddr, i));
+#define MCA_NUMBER_OF_SLOTS 8
+#define MCA_PORT_POS_SEL 0x096
+#define MCA_PORT_ID_REG_0 0x100
+#define MCA_PORT_ID_REG_1 0x101
+#define MCA_SELECT_BIT 0x08
+	if (MCA_bus) 
+	{
+		u_int mca_id;
+		u_char posreg[4];
+		int mca_slot;
 
-				mca_adaptor_select_mode(0);
-				goto found;
+		if (el3_debug > 2)
+			printk("3c529: probing...\n");
+		/* This should probably be done once early on and read into
+		 * a structure somewhere... */
+		for (mca_slot = 0; mca_slot < MCA_NUMBER_OF_SLOTS; mca_slot++)
+		{
+			/* Select MCA slot i */
+			outb_p(mca_slot | MCA_SELECT_BIT, MCA_PORT_POS_SEL); 
+			mca_id = ((inb_p(MCA_PORT_ID_REG_1)<<8) 
+					  + inb_p(MCA_PORT_ID_REG_0));
+			if (mca_id == 0x627C     /* 10base2 */
+				|| mca_id == 0x627D  /* 10baseT */
+				|| mca_id == 0x62DB	 /* Test mode */
+				|| mca_id == 0x62F6	 /* TP or coax */
+				|| mca_id == 0x62F7) /* TP only */
+			{
+				if (el3_debug > 1)
+					printk("3c529: Found with id 0x%x at slot %d\n",
+						 mca_id, mca_slot);
+				posreg[0] = inb_p(0x102);  posreg[1] = inb_p(0x103);
+				posreg[2] = inb_p(0x104);  posreg[3] = inb_p(0x105);
+				break;
 			}
-		mca_adaptor_select_mode(0);
-
+			mca_id = 0xFFFF;
+		}
+		/* Read values from POS registers so now disable */
+		outb(0,MCA_PORT_POS_SEL);
+		if (mca_id != 0xFFFF && !(posreg[0]&0x01))
+			printk("3c529: Adapter found but disabled in slot %d\n", mca_slot);
+		else if (mca_id != 0xFFFF && posreg[0]&0x01)
+		{
+			/* Found and adapter is enabled */
+			if (el3_debug > 2)
+				printk("3c529: pos registers 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
+					 posreg[0], posreg[1], posreg[2], posreg[3]);
+			ioaddr = ((short)((posreg[2]&0xfc)|0x02)) << 8;
+			irq = posreg[3] & 0x0f;
+			if_port = posreg[2] & 0x03;
+			if (el3_debug > 2)
+				printk("3c529: irq %d  ioaddr 0x%x  ifport %d\n",
+					irq, ioaddr, if_port);
+			for (i = 0; i < 3; i++)
+				phys_addr[i] = htons(read_eeprom(ioaddr, i));
+			goto found;
+		}
 	}
 #endif
-#endif
-
 	/* Reset the ISA PnP mechanism on 3c509b. */
 	outb(0x02, 0x279);           /* Select PnP config control register. */
 	outb(0x02, 0xA79);           /* Return to WaitForKey state. */
diff -u --recursive --new-file v2.1.125/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.1.125/linux/drivers/net/Config.in	Fri Oct  9 13:27:08 1998
+++ linux/drivers/net/Config.in	Sat Oct 17 15:33:45 1998
@@ -106,6 +106,9 @@
     fi
     bool 'SK_G16 support' CONFIG_SK_G16
   fi
+  if [ "$CONFIG_MCA" = "y" ]; then
+    tristate 'NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA
+  fi
   bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA
   if [ "$CONFIG_NET_EISA" = "y" ]; then
     tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32
diff -u --recursive --new-file v2.1.125/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.1.125/linux/drivers/net/Makefile	Fri Oct  9 13:27:08 1998
+++ linux/drivers/net/Makefile	Sat Oct 17 15:33:45 1998
@@ -199,6 +199,16 @@
   endif
 endif
 
+ifeq ($(CONFIG_NE2_MCA),y)
+L_OBJS += ne2.o
+CONFIG_8390_BUILTIN = y
+else
+  ifeq ($(CONFIG_NE2_MCA),m)
+  CONFIG_8390_MODULE = y
+  M_OBJS += ne2.o
+  endif
+endif
+
 ifeq ($(CONFIG_HPLAN),y)
 L_OBJS += hp.o
 CONFIG_8390_BUILTIN = y
diff -u --recursive --new-file v2.1.125/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.1.125/linux/drivers/net/Space.c	Fri Oct  9 13:27:08 1998
+++ linux/drivers/net/Space.c	Sat Oct 17 15:33:45 1998
@@ -39,6 +39,7 @@
    ethernet adaptor have the name "eth[0123...]".
    */
 
+extern int ne2_probe(struct device *dev);
 extern int tulip_probe(struct device *dev);
 extern int hp100_probe(struct device *dev);
 extern int ultra_probe(struct device *dev);
@@ -108,6 +109,7 @@
 extern int epic100_probe(struct device *dev);
 extern int rtl8139_probe(struct device *dev);
 extern int hplance_probe(struct device *dev);
+extern int via_rhine_probe(struct device *dev);
 
 /* Gigabit Ethernet adapters */
 extern int yellowfin_probe(struct device *dev);
@@ -195,6 +197,9 @@
 #ifdef CONFIG_YELLOWFIN
 	{yellowfin_probe, 0},
 #endif
+#ifdef CONFIG_VIA_RHINE
+	{via_rhine_probe, 0},
+#endif
 	{NULL, 0},
 };
 
@@ -242,6 +247,9 @@
 struct devprobe mca_probes[] __initdata = {
 #ifdef CONFIG_ULTRAMCA 
 	{ultramca_probe, 0},
+#endif
+#ifdef CONFIG_NE2_MCA
+	{ne2_probe, 0},
 #endif
 #ifdef CONFIG_ELMC		/* 3c523 */
 	{elmc_probe, 0},
diff -u --recursive --new-file v2.1.125/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.1.125/linux/drivers/net/eepro100.c	Mon Aug  3 12:45:45 1998
+++ linux/drivers/net/eepro100.c	Tue Oct 20 17:04:29 1998
@@ -1,13 +1,13 @@
 /* drivers/net/eepro100.c: An Intel i82557 Ethernet driver for Linux. */
 /*
    NOTICE: this version tested with kernels 1.3.72 and later only!
-	Written 1996-1997 by Donald Becker.
+	Written 1996-1998 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU Public License, incorporated herein by reference.
 
 	This driver is for the Intel EtherExpress Pro 100B boards.
-	It should work with other i82557 boards (if any others exist).
+	It should work with other i82557 and i82558 boards.
 	To use a built-in driver, install as drivers/net/eepro100.c.
 	To use as a module, use the compile-command at the end of the file.
 
@@ -15,11 +15,13 @@
 	Center of Excellence in Space Data and Information Sciences
 	   Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771
 	For updates see
-	<base href="http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html">
+		http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html
+	There is also a mailing list based at
+		linux-eepro100@cesdis.gsfc.nasa.gov
 */
 
 static const char *version =
-"eepro100.c:v0.36 10/20/97 Donald Becker linux-eepro100@cesdis.gsfc.nasa.gov\n";
+"eepro100.c:v1.06 10/16/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n";
 
 /* A few user-configurable values that apply to all boards.
    First set are undocumented and spelled per Intel recommendations. */
@@ -33,125 +35,60 @@
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
    Lower values use more memory, but are faster. */
-/*
- * NOTE! The value of 2000 means that this optimization never gets
- * used. Rationale: it seems to be broken when in low-memory situations,
- * apparently when alloc_skb() can return NULL the clever list of
- * copy-buffers can get buggered. 
- *
- * My personal suspicion is that the allocation failure will cause
- * us to not remove the skb from the list of available buffers, but
- * we'd already have done a "skb_push()" with the data we got, so
- * the buffer stays on the list but the available memory in it
- * shrinks until we panic.
- *
- * Donald, when you fix this you can shrink this value again.
- *
- *		Linus
- */
-static int rx_copybreak = 2000;
+static int rx_copybreak = 200;
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 200;
 
-#ifdef MODULE
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
+/* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */
+static int multicast_filter_limit = 64;
+
 #include <linux/module.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
 
 #include <linux/version.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/timer.h>
-#include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/delay.h>
-#include <asm/processor.h>		/* Processor type for cache alignment. */
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
-
-/* A nominally proper method to handle version dependencies is to use
-   LINUX_VERSION_CODE in version.h, but that triggers recompiles w/'make'. */
-#define VERSION(v,p,s) (((v)<<16)+(p<<8)+s)
-#ifdef MODULE
-#if (LINUX_VERSION_CODE < VERSION(1,3,0))
-#define KERNEL_1_2
-#else /* 1.3.0 */
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
-#define NEW_MULTICAST
-#define LINUX_1_4
-#else
-#warning "This driver is tested for 1.3.44 and later development kernels only."
-#endif /* 1.3.44 */
-#endif
-#else
-
-#if (LINUX_VERSION_CODE >= 0x10344)
-#define NEW_MULTICAST
 #include <linux/delay.h>
-#endif
 
-#ifdef HAVE_HEADER_CACHE
-#define LINUX_1_4
-#define NEW_MULTICAST
-#else
-#ifdef ETH_P_DDCMP				/* Warning: Bogus!  This means IS_LINUX_1_3. */
-#define KERNEL_1_3
-#else
-#define KERNEL_1_2
-#endif
-#endif
+#include <asm/spinlock.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+
+/*
+ * Module documentation
+ */
+MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
+MODULE_DESCRIPTION("Intel i82557/i82558 PCI EtherExpressPro driver");
+MODULE_PARM(debug, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(congenb, "i");
+MODULE_PARM(txfifo, "i");
+MODULE_PARM(rxfifo, "i");
+MODULE_PARM(txdmacount, "i");
+MODULE_PARM(rxdmacount, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(multicast_filter_limit, "i");
 
-#endif
-/* This should be in a header file. */
-#if (LINUX_VERSION_CODE < VERSION(1,3,44))
-struct device *init_etherdev(struct device *dev, int sizeof_priv,
-							 unsigned long *mem_startp);
-#endif
-#if LINUX_VERSION_CODE < 0x10300
-#define RUN_AT(x) (x)			/* What to put in timer->expires.  */
-#define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC)
-#define virt_to_bus(addr)  ((unsigned long)addr)
-#define bus_to_virt(addr) ((void*)addr)
-#else  /* 1.3.0 and later */
 #define RUN_AT(x) (jiffies + (x))
-#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
-#endif
 
-#if (LINUX_VERSION_CODE < 0x20123)
-#define test_and_set_bit(val, addr) set_bit(val, addr)
-#include <linux/bios32.h>
-#endif
+#define dev_free_skb(skb) dev_kfree_skb(skb);
 
-/* The total I/O port extent of the board.  Nominally 0x18, but rounded up
-   for PCI allocation. */
+/* The total I/O port extent of the board.
+   The registers beyond 0x18 only exist on the i82558. */
 #define SPEEDO3_TOTAL_SIZE 0x20
 
-#ifdef HAVE_DEVLIST
-struct netdev_entry eepro100_drv =
-{"EEPro-100", eepro100_init, SPEEDO3_TOTAL_SIZE, NULL};
-#endif
-
-#ifdef SPEEDO3_DEBUG
-int speedo_debug = SPEEDO3_DEBUG;
-#else
-int speedo_debug = 3;
-#endif
+int speedo_debug = 0;
 
 /*
 				Theory of Operation
@@ -183,7 +120,7 @@
 Despite the extra space overhead in each receive skbuff, the driver must use
 the simplified Rx buffer mode to assure that only a single data buffer is
 associated with each RxFD. The driver implements this by reserving space
-for the Rx descriptor at the head of each Rx skbuff
+for the Rx descriptor at the head of each Rx skbuff.
 
 The Speedo-3 has receive and command unit base addresses that are added to
 almost all descriptor pointers.  The driver sets these to zero, so that all
@@ -198,10 +135,13 @@
 
 The driver must use the complex Tx command+descriptor mode in order to
 have a indirect pointer to the skbuff data section.  Each Tx command block
-(TxCB) is associated with a single, immediately appended Tx buffer descriptor
+(TxCB) is associated with two immediately appended Tx Buffer Descriptor
 (TxBD).  A fixed ring of these TxCB+TxBD pairs are kept as part of the
 speedo_private data structure for each adapter instance.
 
+The newer i82558 explicitly supports this structure, and can read the two
+TxBDs in the same PCI burst as the TxCB.
+
 This ring structure is used for all normal transmit packets, but the
 transmit packet descriptors aren't long enough for most non-Tx commands such
 as CmdConfigure.  This is complicated by the possibility that the chip has
@@ -290,26 +230,19 @@
 #define PKT_BUF_SZ		1536
 
 /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  ((400*HZ)/1000)
+#define TX_TIMEOUT  ((800*HZ)/1000)
 
 /* How to wait for the command unit to accept a command.
    Typically this takes 0 ticks. */
-static inline void wait_for_cmd_done(int cmd_ioaddr)
+static inline void wait_for_cmd_done(long cmd_ioaddr)
 {
-  short wait = 100;
-  do   ;
-  while(inb(cmd_ioaddr) && --wait >= 0);
+	int wait = 100;
+	do   ;
+	while(inb(cmd_ioaddr) && --wait >= 0);
 }
 
 /* Operational parameter that usually are not changed. */
 
-#ifndef PCI_VENDOR_ID_INTEL		/* Now defined in linux/pci.h */
-#define PCI_VENDOR_ID_INTEL		0x8086 /* Hmmmm, how did they pick that? */
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82557
-#define PCI_DEVICE_ID_INTEL_82557	0x1229
-#endif
-
 /* The rest of these values should never change. */
 
 /* Offsets to the various registers.
@@ -364,17 +297,24 @@
 	u16 size;
 };
 
-/* Elements of the RxFD.status word. */
-#define RX_COMPLETE 0x8000
+/* Selected elements of the Tx/RxFD.status word. */
+enum RxFD_bits {
+	RxComplete=0x8000, RxOK=0x2000,
+	RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010,
+	RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002,
+	StatusComplete=0x8000,
+};
 
 struct TxFD {					/* Transmit frame descriptor set. */
 	s32 status;
 	u32 link;					/* void * */
 	u32 tx_desc_addr;			/* Always points to the tx_buf_addr element. */
 	s32 count;					/* # of TBD (=1), Tx start thresh., etc. */
-	/* This constitutes a single "TBD" entry -- we only use one. */
-	u32 tx_buf_addr;			/* void *, frame to be transmitted.  */
-	s32 tx_buf_size;			/* Length of Tx frame. */
+	/* This constitutes two "TBD" entries -- we only use one. */
+	u32 tx_buf_addr0;			/* void *, frame to be transmitted.  */
+	s32 tx_buf_size0;			/* Length of Tx frame. */
+	u32 tx_buf_addr1;			/* void *, frame to be transmitted.  */
+	s32 tx_buf_size1;			/* Length of Tx frame. */
 };
 
 /* Elements of the dump_statistics block. This block must be lword aligned. */
@@ -402,6 +342,7 @@
 	char devname[8];			/* Used only for kernel debugging. */
 	const char *product_name;
 	struct device *next_module;
+	spinlock_t lock;
 	struct TxFD	tx_ring[TX_RING_SIZE];	/* Commands (usually CmdTxPacket). */
 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
@@ -409,9 +350,6 @@
 	/* Rx descriptor ring & addresses of receive-in-place skbuffs. */
 	struct RxFD *rx_ringp[RX_RING_SIZE];
 	struct sk_buff* rx_skbuff[RX_RING_SIZE];
-#if (LINUX_VERSION_CODE < 0x10300)	/* Kernel v1.2.*. */
-	struct RxFD saved_skhead[RX_RING_SIZE];	/* Saved skbuff header chunk. */
-#endif
 	struct RxFD *last_rxf;	/* Last command sent. */
 	struct enet_statistics stats;
 	struct speedo_stats lstats;
@@ -419,10 +357,9 @@
 	long last_rx_time;			/* Last Rx, in jiffies, to handle Rx hang. */
 	unsigned int cur_rx, cur_tx;		/* The next free ring entry */
 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
-	struct descriptor config_cmd;	/* A configure command, with header... */
-	u8 config_cmd_data[22];			/* .. and setup parameters. */
 	int mc_setup_frm_len;			 	/* The length of an allocated.. */
 	struct descriptor *mc_setup_frm; 	/* ..multicast setup frame. */
+	int mc_setup_busy;					/* Avoid double-use of setup frame. */
 	char rx_mode;						/* Current PROMISC/ALLMULTI setting. */
 	unsigned int tx_full:1;				/* The Tx queue is full. */
 	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
@@ -436,11 +373,16 @@
 /* The parameters for a CmdConfigure operation.
    There are so many options that it would be difficult to document each bit.
    We mostly use the default or recommended settings. */
-const char basic_config_cmd[22] = {
+const char i82557_config_cmd[22] = {
 	22, 0x08, 0, 0,  0, 0x80, 0x32, 0x03,  1, /* 1=Use MII  0=Use AUI */
 	0, 0x2E, 0,  0x60, 0,
 	0xf2, 0x48,   0, 0x40, 0xf2, 0x80, 		/* 0x40=Force full-duplex */
 	0x3f, 0x05, };
+const char i82558_config_cmd[22] = {
+	22, 0x08, 0, 1,  0, 0x80, 0x22, 0x03,  1, /* 1=Use MII  0=Use AUI */
+	0, 0x2E, 0,  0x60, 0x08, 0x88,
+	0x68, 0, 0x40, 0xf2, 0xBD, 		/* 0xBD->0xFD=Force full-duplex */
+	0x31, 0x05, };
 
 /* PHY media interface chips. */
 static const char *phys[] = {
@@ -452,12 +394,12 @@
 					 S80C24, I82555, DP83840A=10, };
 static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 };
 
-static void speedo_found1(struct device *dev, int ioaddr, int irq,
-						  int options, int card_idx);
+static void speedo_found1(struct device *dev, long ioaddr, int irq,
+						  int card_idx);
 
-static int read_eeprom(int ioaddr, int location);
-static int mdio_read(int ioaddr, int phy_id, int location);
-static int mdio_write(int ioaddr, int phy_id, int location, int value);
+static int read_eeprom(long ioaddr, int location, int addr_len);
+static int mdio_read(long ioaddr, int phy_id, int location);
+static int mdio_write(long ioaddr, int phy_id, int location, int value);
 static int speedo_open(struct device *dev);
 static void speedo_timer(unsigned long data);
 static void speedo_init_rx_ring(struct device *dev);
@@ -466,9 +408,7 @@
 static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static int speedo_close(struct device *dev);
 static struct enet_statistics *speedo_get_stats(struct device *dev);
-#ifdef HAVE_PRIVATE_IOCTL
 static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd);
-#endif
 static void set_rx_mode(struct device *dev);
 
 
@@ -477,109 +417,101 @@
 /* 'options' is used to pass a transceiver override or full-duplex flag
    e.g. "options=16" for FD, "options=32" for 100mbps-only. */
 static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-#ifdef MODULE
 static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+#ifdef MODULE
 static int debug = -1;			/* The debug level */
 #endif
 
+#ifdef honor_default_port
+/* Optional driver feature to allow forcing the transceiver setting.
+   Not recommended. */
+static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100,
+						   0x2000, 0x2100, 0x0400, 0x3100};
+#endif
+
 /* A list of all installed Speedo devices, for removing the driver module. */
 static struct device *root_speedo_dev = NULL;
 
 int eepro100_init(struct device *dev)
 {
 	int cards_found = 0;
+	static int pci_index = 0;
 
-	if (pci_present()) {
-		static int pci_index = 0;
+	if (! pcibios_present())
+		return cards_found;
 
-		for (; pci_index < 8; pci_index++) {
-			unsigned char pci_bus, pci_device_fn, pci_latency;
-#if (LINUX_VERSION_CODE >= VERSION(2,1,85))
-			unsigned int pci_irq_line;
-			struct pci_dev *pdev;
-#else
-			unsigned char pci_irq_line;
-#endif
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
-			int pci_ioaddr;
-#else
-			long pci_ioaddr;
-#endif
-			unsigned short pci_command;
-
-			if (pcibios_find_device(PCI_VENDOR_ID_INTEL,
-						PCI_DEVICE_ID_INTEL_82557,
-						pci_index, &pci_bus,
-						&pci_device_fn))
-			  break;
-#if (LINUX_VERSION_CODE >= VERSION(2,1,85))
-			pdev = pci_find_slot(pci_bus, pci_device_fn);
-			pci_irq_line = pdev->irq;
-			pci_ioaddr = pdev->base_address[1];
-#else
-			pcibios_read_config_byte(pci_bus, pci_device_fn,
-									 PCI_INTERRUPT_LINE, &pci_irq_line);
-			/* Note: BASE_ADDRESS_0 is for memory-mapping the registers. */
-			pcibios_read_config_dword(pci_bus, pci_device_fn,
-									  PCI_BASE_ADDRESS_1, &pci_ioaddr);
-#endif
-			/* Remove I/O space marker in bit 0. */
-			pci_ioaddr &= ~3;
-			if (speedo_debug > 2)
-				printk("Found Intel i82557 PCI Speedo at I/O %#x, IRQ %d.\n",
-					   (int)pci_ioaddr, pci_irq_line);
-
-			/* Get and check the bus-master and latency values. */
-			pcibios_read_config_word(pci_bus, pci_device_fn,
-									 PCI_COMMAND, &pci_command);
-			if ( ! (pci_command & PCI_COMMAND_MASTER)) {
-				printk("  PCI Master Bit has not been set! Setting...\n");
-				pci_command |= PCI_COMMAND_MASTER;
-				pcibios_write_config_word(pci_bus, pci_device_fn,
-										  PCI_COMMAND, pci_command);
-			}
-			pcibios_read_config_byte(pci_bus, pci_device_fn,
-										 PCI_LATENCY_TIMER, &pci_latency);
-			if (pci_latency < 10) {
-				printk("  PCI latency timer (CFLT) is unreasonably low at %d."
-					   "  Setting to 255 clocks.\n", pci_latency);
-				pcibios_write_config_byte(pci_bus, pci_device_fn,
-										  PCI_LATENCY_TIMER, 255);
-			} else if (speedo_debug > 1)
-				printk("  PCI latency timer (CFLT) is %#x.\n", pci_latency);
-
-#ifdef MODULE
-			speedo_found1(dev, pci_ioaddr, pci_irq_line, options[cards_found],
-						  cards_found);
-#else
-			speedo_found1(dev, pci_ioaddr, pci_irq_line,
-						  dev ? dev->mem_start : 0, -1);
-#endif
-			dev = NULL;
-			cards_found++;
+	for (; pci_index < 8; pci_index++) {
+		unsigned char pci_bus, pci_device_fn, pci_latency;
+		long ioaddr;
+		int irq;
+
+		u16 pci_command, new_command;
+
+		if (pcibios_find_device(PCI_VENDOR_ID_INTEL,
+								PCI_DEVICE_ID_INTEL_82557,
+								pci_index, &pci_bus,
+								&pci_device_fn))
+			break;
+		{
+			struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
+			ioaddr = pdev->base_address[1];		/* Use [0] to mem-map */
+			irq = pdev->irq;
 		}
+		/* Remove I/O space marker in bit 0. */
+		ioaddr &= ~3;
+		if (speedo_debug > 2)
+			printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n",
+				   ioaddr, irq);
+
+		/* Get and check the bus-master and latency values. */
+		pcibios_read_config_word(pci_bus, pci_device_fn,
+								 PCI_COMMAND, &pci_command);
+		new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+		if (pci_command != new_command) {
+			printk(KERN_INFO "  The PCI BIOS has not enabled this"
+				   " device!  Updating PCI command %4.4x->%4.4x.\n",
+				   pci_command, new_command);
+			pcibios_write_config_word(pci_bus, pci_device_fn,
+									  PCI_COMMAND, new_command);
+		}
+		pcibios_read_config_byte(pci_bus, pci_device_fn,
+								 PCI_LATENCY_TIMER, &pci_latency);
+		if (pci_latency < 32) {
+			printk("  PCI latency timer (CFLT) is unreasonably low at %d."
+				   "  Setting to 32 clocks.\n", pci_latency);
+			pcibios_write_config_byte(pci_bus, pci_device_fn,
+									  PCI_LATENCY_TIMER, 32);
+		} else if (speedo_debug > 1)
+			printk("  PCI latency timer (CFLT) is %#x.\n", pci_latency);
+
+		speedo_found1(dev, ioaddr, irq, cards_found);
+		dev = NULL;
+		cards_found++;
 	}
 
 	return cards_found;
 }
 
-static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
+static void speedo_found1(struct device *dev, long ioaddr, int irq,
 						  int card_idx)
 {
 	static int did_version = 0;			/* Already printed version info. */
 	struct speedo_private *sp;
 	char *product;
-	int i;
+	int i, option;
 	u16 eeprom[0x40];
 
 	if (speedo_debug > 0  &&  did_version++ == 0)
 		printk(version);
 
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
 	dev = init_etherdev(dev, sizeof(struct speedo_private));
-#else
-	dev = init_etherdev(dev, sizeof(struct speedo_private), 0);
-#endif
+
+	if (dev->mem_start > 0)
+		option = dev->mem_start;
+	else if (card_idx >= 0  &&  options[card_idx] >= 0)
+		option = options[card_idx];
+	else
+		option = 0;
 
 	/* Read the station address EEPROM before doing the reset.
 	   Perhaps this should even be done before accepting the device,
@@ -587,8 +519,10 @@
 	{
 		u16 sum = 0;
 		int j;
+		int addr_len = read_eeprom(ioaddr, 0, 6) == 0xffff ? 8 : 6;
+
 		for (j = 0, i = 0; i < 0x40; i++) {
-			u16 value = read_eeprom(ioaddr, i);
+			u16 value = read_eeprom(ioaddr, i, addr_len);
 			eeprom[i] = value;
 			sum += value;
 			if (i < 3) {
@@ -614,7 +548,7 @@
 	else
 		product = "Intel EtherExpress Pro 10/100";
 
-	printk(KERN_INFO "%s: %s at %#3x, ", dev->name, product, ioaddr);
+	printk(KERN_INFO "%s: %s at %#3lx, ", dev->name, product, ioaddr);
 
 	for (i = 0; i < 5; i++)
 		printk("%2.2X:", dev->dev_addr[i]);
@@ -643,17 +577,6 @@
 		if (eeprom[7] & 0x0700)
 			printk(KERN_INFO "    Secondary interface chip %s.\n",
 				   phys[(eeprom[7]>>8)&7]);
-#if defined(notdef)
-		/* ToDo: Read and set PHY registers through MDIO port. */
-		for (i = 0; i < 2; i++)
-			printk(KERN_INFO"  MDIO register %d is %4.4x.\n",
-				   i, mdio_read(ioaddr, eeprom[6] & 0x1f, i));
-		for (i = 5; i < 7; i++)
-			printk(KERN_INFO"  MDIO register %d is %4.4x.\n",
-				   i, mdio_read(ioaddr, eeprom[6] & 0x1f, i));
-		printk(KERN_INFO"  MDIO register %d is %4.4x.\n",
-			   25, mdio_read(ioaddr, eeprom[6] & 0x1f, 25));
-#endif
 		if (((eeprom[6]>>8) & 0x3f) == DP83840
 			||  ((eeprom[6]>>8) & 0x3f) == DP83840A) {
 			int mdi_reg23 = mdio_read(ioaddr, eeprom[6] & 0x1f, 23) | 0x0422;
@@ -663,13 +586,13 @@
 				   mdi_reg23);
 			mdio_write(ioaddr, eeprom[6] & 0x1f, 23, mdi_reg23);
 		}
-		if ((options >= 0) && (options & 0x60)) {
+		if ((option >= 0) && (option & 0x70)) {
 			printk(KERN_INFO "  Forcing %dMbs %s-duplex operation.\n",
-				   (options & 0x20 ? 100 : 10),
-				   (options & 0x10 ? "full" : "half"));
+				   (option & 0x20 ? 100 : 10),
+				   (option & 0x10 ? "full" : "half"));
 			mdio_write(ioaddr, eeprom[6] & 0x1f, 0,
-					   ((options & 0x20) ? 0x2000 : 0) | 	/* 100mbps? */
-					   ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
+					   ((option & 0x20) ? 0x2000 : 0) | 	/* 100mbps? */
+					   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
 		}
 
 		/* Perform a system self-test. */
@@ -678,11 +601,7 @@
 		self_test_results[1] = -1;
 		outl(virt_to_bus(self_test_results) | 1, ioaddr + SCBPort);
 		do {
-#ifdef _LINUX_DELAY_H
 			udelay(10);
-#else
-			SLOW_DOWN_IO;
-#endif
 		} while (self_test_results[1] == -1  &&  --boguscnt >= 0);
 
 		if (boguscnt < 0) {		/* Test optimized out. */
@@ -704,8 +623,6 @@
 	}
 #endif  /* kernel_bloat */
 
-	outl(0, ioaddr + SCBPort);
-
 	/* We do a request_region() only to register /proc/ioports info. */
 	request_region(ioaddr, SPEEDO3_TOTAL_SIZE, "Intel Speedo3 Ethernet");
 
@@ -719,12 +636,12 @@
 	sp->next_module = root_speedo_dev;
 	root_speedo_dev = dev;
 
+	sp->full_duplex = option >= 0 && (option & 0x10) ? 1 : 0;
 	if (card_idx >= 0) {
 		if (full_duplex[card_idx] >= 0)
 			sp->full_duplex = full_duplex[card_idx];
-	} else
-		sp->full_duplex = options >= 0 && (options & 0x10) ? 1 : 0;
-	sp->default_port = options >= 0 ? (options & 0x0f) : 0;
+	}
+	sp->default_port = option >= 0 ? (option & 0x0f) : 0;
 
 	sp->phy[0] = eeprom[6];
 	sp->phy[1] = eeprom[7];
@@ -738,12 +655,8 @@
 	dev->hard_start_xmit = &speedo_start_xmit;
 	dev->stop = &speedo_close;
 	dev->get_stats = &speedo_get_stats;
-#ifdef NEW_MULTICAST
 	dev->set_multicast_list = &set_rx_mode;
-#endif
-#ifdef HAVE_PRIVATE_IOCTL
 	dev->do_ioctl = &speedo_ioctl;
-#endif
 
 	return;
 }
@@ -760,38 +673,31 @@
 #define EE_ENB			(0x4800 | EE_CS)
 
 /* Delay between EEPROM clock transitions.
-   This is a "nasty" timing loop, but PC compatible machines are defined
-   to delay an ISA compatible period for the SLOW_DOWN_IO macro.  */
-#ifdef _LINUX_DELAY_H
+   This will actually work with no delay on 33Mhz PCI.  */
 #define eeprom_delay(nanosec)		udelay(1);
-#else
-#define eeprom_delay(nanosec)	do { int _i = 3; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
-#endif
 
 /* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD	(5 << 6)
-#define EE_READ_CMD		(6 << 6)
-#define EE_ERASE_CMD	(7 << 6)
+#define EE_WRITE_CMD	(5 << addr_len)
+#define EE_READ_CMD		(6 << addr_len)
+#define EE_ERASE_CMD	(7 << addr_len)
 
-static int read_eeprom(int ioaddr, int location)
+static int read_eeprom(long ioaddr, int location, int addr_len)
 {
-	int i;
 	unsigned short retval = 0;
 	int ee_addr = ioaddr + SCBeeprom;
 	int read_cmd = location | EE_READ_CMD;
+	int i;
 
 	outw(EE_ENB & ~EE_CS, ee_addr);
 	outw(EE_ENB, ee_addr);
 
 	/* Shift the read command bits out. */
-	for (i = 10; i >= 0; i--) {
+	for (i = 12; i >= 0; i--) {
 		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
 		outw(EE_ENB | dataval, ee_addr);
 		eeprom_delay(100);
 		outw(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
 		eeprom_delay(150);
-		outw(EE_ENB | dataval, ee_addr);	/* Finish EEPROM a clock tick. */
-		eeprom_delay(250);
 	}
 	outw(EE_ENB, ee_addr);
 
@@ -808,16 +714,11 @@
 	return retval;
 }
 
-static int mdio_read(int ioaddr, int phy_id, int location)
+static int mdio_read(long ioaddr, int phy_id, int location)
 {
-	int val, boguscnt = 64*4;		/* <64 usec. to complete, typ 27 ticks */
+	int val, boguscnt = 64*10;		/* <64 usec. to complete, typ 27 ticks */
 	outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
 	do {
-#ifdef _LINUX_DELAY_H
-		udelay(16);
-#else
-		SLOW_DOWN_IO;
-#endif
 		val = inl(ioaddr + SCBCtrlMDI);
 		if (--boguscnt < 0) {
 			printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val);
@@ -826,17 +727,12 @@
 	return val & 0xffff;
 }
 
-static int mdio_write(int ioaddr, int phy_id, int location, int value)
+static int mdio_write(long ioaddr, int phy_id, int location, int value)
 {
-	int val, boguscnt = 64*4;		/* <64 usec. to complete, typ 27 ticks */
+	int val, boguscnt = 64*10;		/* <64 usec. to complete, typ 27 ticks */
 	outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
 		 ioaddr + SCBCtrlMDI);
 	do {
-#ifdef _LINUX_DELAY_H
-		udelay(16);
-#else
-		SLOW_DOWN_IO;
-#endif
 		val = inl(ioaddr + SCBCtrlMDI);
 		if (--boguscnt < 0) {
 			printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val);
@@ -850,24 +746,38 @@
 speedo_open(struct device *dev)
 {
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
-	int ioaddr = dev->base_addr;
+	long ioaddr = dev->base_addr;
 
 #ifdef notdef
 	/* We could reset the chip, but should not need to. */
+	/* In fact we MUST NOT, unless we also re-do the init */
 	outl(0, ioaddr + SCBPort);
-	for (i = 40; i >= 0; i--)
-		SLOW_DOWN_IO;			/* At least 250ns */
+	udelay(10);
 #endif
 
-	if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ,
-					"Intel EtherExpress Pro 10/100 Ethernet", dev)) {
-		return -EAGAIN;
-	}
+	/* This had better be initialized before we initialize the interrupt! */
+	sp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
 
 	if (speedo_debug > 1)
 		printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
 
-	MOD_INC_USE_COUNT;
+#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us
+	/* Retrigger negotiation to reset previous errors. */
+	if ((sp->phy[0] & 0x8000) == 0) {
+		int phy_addr = sp->phy[0] & 0x1f ;
+		/* Use 0x3300 for restarting NWay, other values to force xcvr:
+		   0x0000 10-HD
+		   0x0100 10-FD
+		   0x2000 100-HD
+		   0x2100 100-FD
+		*/
+#ifdef honor_default_port
+		mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]);
+#else
+		mdio_write(ioaddr, phy_addr, 0, 0x3300);
+#endif
+	}
+#endif
 
 	/* Load the statistics block address. */
 	wait_for_cmd_done(ioaddr + SCBCmd);
@@ -921,6 +831,7 @@
 	/* Setup the chip and configure the multicast list. */
 	sp->mc_setup_frm = NULL;
 	sp->mc_setup_frm_len = 0;
+	sp->mc_setup_busy = 0;
 	sp->rx_mode = -1;			/* Invalid -> always reset the mode. */
 	set_rx_mode(dev);
 
@@ -928,6 +839,24 @@
 		printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
 	}
+
+	wait_for_cmd_done(ioaddr + SCBCmd);
+	outw(CU_DUMPSTATS, ioaddr + SCBCmd);
+	/* No need to wait for the command unit to accept here. */
+	if ((sp->phy[0] & 0x8000) == 0)
+		mdio_read(ioaddr, sp->phy[0] & 0x1f, 0);
+
+	/*
+	 * Request the IRQ last, after we have set up all data structures.
+	 * It would be bad to get an interrupt before we're ready.
+	 */
+	if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ,
+					"Intel EtherExpress Pro 10/100 Ethernet", dev)) {
+		return -EAGAIN;
+	}
+
+	MOD_INC_USE_COUNT;
+
 	/* Set the timer.  The timer serves a dual purpose:
 	   1) to monitor the media interface (e.g. link beat) and perhaps switch
 	   to an alternate media type
@@ -939,8 +868,6 @@
 	sp->timer.function = &speedo_timer;					/* timer handler */
 	add_timer(&sp->timer);
 
-	wait_for_cmd_done(ioaddr + SCBCmd);
-	outw(CU_DUMPSTATS, ioaddr + SCBCmd);
 	return 0;
 }
 
@@ -949,24 +876,22 @@
 {
 	struct device *dev = (struct device *)data;
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
-	int tickssofar = jiffies - sp->last_rx_time;
 
 	if (speedo_debug > 3) {
-		int ioaddr = dev->base_addr;
-		printk(KERN_DEBUG "%s: Media selection tick, status %4.4x.\n",
+		long ioaddr = dev->base_addr;
+		printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
 	}
-	if (sp->rx_bug) {
-		if (tickssofar > 2*HZ  || sp->rx_mode < 0) {
-			/* We haven't received a packet in a Long Time.  We might have been
-			   bitten by the receiver hang bug.  This can be cleared by sending
-			   a set multicast list command. */
-			set_rx_mode(dev);
-		}
-		/* We must continue to monitor the media. */
-		sp->timer.expires = RUN_AT(2*HZ); 			/* 2.0 sec. */
-		add_timer(&sp->timer);
+	if (sp->rx_mode < 0  ||
+		(sp->rx_bug  && jiffies - sp->last_rx_time > 2*HZ)) {
+		/* We haven't received a packet in a Long Time.  We might have been
+		   bitten by the receiver hang bug.  This can be cleared by sending
+		   a set multicast list command. */
+		set_rx_mode(dev);
 	}
+	/* We must continue to monitor the media. */
+	sp->timer.expires = RUN_AT(2*HZ); 			/* 2.0 sec. */
+	add_timer(&sp->timer);
 }
 
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
@@ -978,43 +903,32 @@
 	int i;
 
 	sp->cur_rx = 0;
-	sp->dirty_rx = RX_RING_SIZE - 1;
 
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		struct sk_buff *skb;
-#ifndef KERNEL_1_2
 		skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
-#else
-		skb = alloc_skb(PKT_BUF_SZ, GFP_ATOMIC);
-#endif
 		sp->rx_skbuff[i] = skb;
 		if (skb == NULL)
-			break;			/* Bad news!  */
+			break;			/* OK.  Just initially short of Rx bufs. */
 		skb->dev = dev;			/* Mark as being used by this device. */
-
-#if LINUX_VERSION_CODE >= 0x10300
 		rxf = (struct RxFD *)skb->tail;
-		skb_reserve(skb, sizeof(struct RxFD));
-#else
-		/* Save the data in the header region -- it's restored later. */
-		rxf = (struct RxFD *)(skb->data - sizeof(struct RxFD));
-		memcpy(&sp->saved_skhead[i], rxf, sizeof(struct RxFD));
-#endif
 		sp->rx_ringp[i] = rxf;
+		skb_reserve(skb, sizeof(struct RxFD));
 		if (last_rxf)
 			last_rxf->link = virt_to_bus(rxf);
 		last_rxf = rxf;
 		rxf->status = 0x00000001; 			/* '1' is flag value only. */
 		rxf->link = 0;						/* None yet. */
-#if LINUX_VERSION_CODE < 0x10300
 		/* This field unused by i82557, we use it as a consistency check. */
-		rxf->rx_buf_addr = virt_to_bus(skb->data);
+#ifdef final_version
+		rxf->rx_buf_addr = 0xffffffff;
 #else
 		rxf->rx_buf_addr = virt_to_bus(skb->tail);
 #endif
 		rxf->count = 0;
 		rxf->size = PKT_BUF_SZ;
 	}
+	sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 	/* Mark the last entry as end-of-list. */
 	last_rxf->status = 0xC0000002; 			/* '2' is flag value only. */
 	sp->last_rxf = last_rxf;
@@ -1023,40 +937,35 @@
 static void speedo_tx_timeout(struct device *dev)
 {
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
-	int ioaddr = dev->base_addr;
-	int i;
+	long ioaddr = dev->base_addr;
 
 	printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
-		   "command %4.4x.\n",
-		   dev->name, inw(ioaddr + SCBStatus), inw(ioaddr + SCBCmd));
-#ifndef final_version
-	printk(KERN_WARNING "%s:  Tx timeout  fill index %d  scavenge index %d.\n",
-		   dev->name, sp->cur_tx, sp->dirty_tx);
-	printk(KERN_WARNING "    Tx queue ");
-	for (i = 0; i < TX_RING_SIZE; i++)
-	  printk(" %8.8x", (int)sp->tx_ring[i].status);
-	printk(".\n" KERN_WARNING "    Rx ring ");
-	for (i = 0; i < RX_RING_SIZE; i++)
-	  printk(" %8.8x", (int)sp->rx_ringp[i]->status);
-	printk(".\n");
-
-#else
-	dev->if_port ^= 1;
-	printk(KERN_WARNING "  (Media type switching not yet implemented.)\n");
-	/* Do not do 'dev->tbusy = 0;' there -- it is incorrect. */
-#endif
+		   " %4.4x at %d/%d command %8.8x.\n",
+		   dev->name, inw(ioaddr + SCBStatus), inw(ioaddr + SCBCmd),
+		   sp->dirty_tx, sp->cur_tx,
+		   sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
 	if ((inw(ioaddr + SCBStatus) & 0x00C0) != 0x0080) {
-	  printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
-			 dev->name);
-	  outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]),
-		   ioaddr + SCBPointer);
-	  outw(CU_START, ioaddr + SCBCmd);
+		printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
+			   dev->name);
+		outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]),
+			 ioaddr + SCBPointer);
+		outw(CU_START, ioaddr + SCBCmd);
 	} else {
-	  outw(DRVR_INT, ioaddr + SCBCmd);
+		outw(DRVR_INT, ioaddr + SCBCmd);
 	}
-	/* Reset the MII transceiver. */
-	if ((sp->phy[0] & 0x8000) == 0)
-		mdio_write(ioaddr, sp->phy[0] & 0x1f, 0, 0x8000);
+#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us
+	/* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */
+	if ((sp->phy[0] & 0x8000) == 0) {
+		int phy_addr = sp->phy[0] & 0x1f;
+		mdio_write(ioaddr, phy_addr, 0, 0x0400);
+		mdio_write(ioaddr, phy_addr, 1, 0x0000);
+		mdio_write(ioaddr, phy_addr, 4, 0x0000);
+		mdio_write(ioaddr, phy_addr, 0, 0x8000);
+#ifdef honor_default_port
+		mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]);
+#endif
+	}
+#endif
 	sp->stats.tx_errors++;
 	dev->trans_start = jiffies;
 	return;
@@ -1066,7 +975,7 @@
 speedo_start_xmit(struct sk_buff *skb, struct device *dev)
 {
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
-	int ioaddr = dev->base_addr;
+	long ioaddr = dev->base_addr;
 	int entry;
 
 	/* Block a timer-based transmit from overlapping.  This could better be
@@ -1082,7 +991,7 @@
 			return 1;
 		}
 		speedo_tx_timeout(dev);
-		return 0;
+		return 1;
 	}
 
 	/* Caution: the write order is important here, set the base address
@@ -1091,8 +1000,8 @@
 	{	/* Prevent interrupts from changing the Tx ring from underneath us. */
 		unsigned long flags;
 
-		save_flags(flags);
-		cli();
+		spin_lock_irqsave(&sp->lock, flags);
+
 		/* Calculate the Tx descriptor entry. */
 		entry = sp->cur_tx++ % TX_RING_SIZE;
 
@@ -1103,29 +1012,31 @@
 		sp->tx_ring[entry].link =
 		  virt_to_bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]);
 		sp->tx_ring[entry].tx_desc_addr =
-		  virt_to_bus(&sp->tx_ring[entry].tx_buf_addr);
+		  virt_to_bus(&sp->tx_ring[entry].tx_buf_addr0);
 		/* The data region is always in one buffer descriptor, Tx FIFO
 		   threshold of 256. */
 		sp->tx_ring[entry].count = 0x01208000;
-		sp->tx_ring[entry].tx_buf_addr = virt_to_bus(skb->data);
-		sp->tx_ring[entry].tx_buf_size = skb->len;
+		sp->tx_ring[entry].tx_buf_addr0 = virt_to_bus(skb->data);
+		sp->tx_ring[entry].tx_buf_size0 = skb->len;
 		/* Todo: perhaps leave the interrupt bit set if the Tx queue is more
 		   than half full.  Argument against: we should be receiving packets
 		   and scavenging the queue.  Argument for: if so, it shouldn't
 		   matter. */
 		sp->last_cmd->command &= ~(CmdSuspend | CmdIntr);
 		sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+
 		/* Trigger the command unit resume. */
 		wait_for_cmd_done(ioaddr + SCBCmd);
 		outw(CU_RESUME, ioaddr + SCBCmd);
-		restore_flags(flags);
+
+		spin_unlock_irqrestore(&sp->lock, flags);
 	}
 
 	/* Leave room for set_rx_mode() to fill two entries. */
 	if (sp->cur_tx - sp->dirty_tx > TX_RING_SIZE - 3)
 		sp->tx_full = 1;
 	else
-		dev->tbusy = 0;
+		clear_bit(0, (void*)&dev->tbusy);
 
 	dev->trans_start = jiffies;
 
@@ -1138,7 +1049,7 @@
 {
 	struct device *dev = (struct device *)dev_instance;
 	struct speedo_private *sp;
-	int ioaddr, boguscnt = max_interrupt_work;
+	long ioaddr, boguscnt = max_interrupt_work;
 	unsigned short status;
 
 #ifndef final_version
@@ -1150,11 +1061,9 @@
 
 	ioaddr = dev->base_addr;
 	sp = (struct speedo_private *)dev->priv;
+	spin_lock(&sp->lock);
+
 #ifndef final_version
-	if (dev->interrupt) {
-		printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
-		return;
-	}
 	dev->interrupt = 1;
 #endif
 
@@ -1174,19 +1083,6 @@
 			speedo_rx(dev);
 
 		if (status & 0x1000) {
-#ifdef notdef
-		  int i;
-		  printk(KERN_WARNING"%s: The EEPro100 receiver left the ready"
-				 " state -- %4.4x!  Index %d (%d).\n", dev->name, status,
-				 sp->cur_rx, sp->cur_rx % RX_RING_SIZE);
-		  printk(KERN_WARNING "   Rx ring:\n ");
-		  for (i = 0; i < RX_RING_SIZE; i++)
-			printk("   %d %8.8x %8.8x %8.8x %d %d.\n",
-				   i, sp->rx_ringp[i]->status, sp->rx_ringp[i]->link,
-				   sp->rx_ringp[i]->rx_buf_addr, sp->rx_ringp[i]->count,
-				   sp->rx_ringp[i]->size);
-#endif
-
 		  if ((status & 0x003c) == 0x0028) /* No more Rx buffers. */
 			outw(RX_RESUMENR, ioaddr + SCBCmd);
 		  else if ((status & 0x003c) == 0x0008) { /* No resources (why?!) */
@@ -1209,14 +1105,15 @@
 				if (speedo_debug > 5)
 					printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n",
 						   entry, status);
-				if ((status & 0x8000) == 0)
+				if ((status & StatusComplete) == 0)
 					break;			/* It still hasn't been processed. */
 				/* Free the original skb. */
 				if (sp->tx_skbuff[entry]) {
 					sp->stats.tx_packets++;	/* Count only user packets. */
-					dev_kfree_skb(sp->tx_skbuff[entry]);
+					dev_free_skb(sp->tx_skbuff[entry]);
 					sp->tx_skbuff[entry] = 0;
-				}
+				} else if ((sp->tx_ring[entry].status&0x70000) == CmdNOp << 16)
+					sp->mc_setup_busy = 0;
 				dirty_tx++;
 			}
 
@@ -1233,7 +1130,7 @@
 				&& dirty_tx > sp->cur_tx - TX_RING_SIZE + 2) {
 				/* The ring is no longer full, clear tbusy. */
 				sp->tx_full = 0;
-				dev->tbusy = 0;
+				clear_bit(0, (void*)&dev->tbusy);
 				mark_bh(NET_BH);
 			}
 
@@ -1253,19 +1150,8 @@
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
 
-#ifndef final_version
-	/* Special code for testing *only*. */
-	{
-		static int stopit = 100;
-		if (dev->start == 0  &&  --stopit < 0) {
-			printk(KERN_ALERT "%s: Emergency stop, interrupt is stuck.\n",
-				   dev->name);
-			free_irq(irq, dev);
-		}
-	}
-#endif
-
 	dev->interrupt = 0;
+	spin_unlock(&sp->lock);
 	return;
 }
 
@@ -1275,150 +1161,104 @@
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
 	int entry = sp->cur_rx % RX_RING_SIZE;
 	int status;
+	int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx;
 
 	if (speedo_debug > 4)
 		printk(KERN_DEBUG " In speedo_rx().\n");
 	/* If we own the next entry, it's a new packet. Send it up. */
-	while ((status = sp->rx_ringp[entry]->status) & RX_COMPLETE) {
+	while (sp->rx_ringp[entry] != NULL &&
+		   (status = sp->rx_ringp[entry]->status) & RxComplete) {
 
+		if (--rx_work_limit < 0)
+			break;
 		if (speedo_debug > 4)
 			printk(KERN_DEBUG "  speedo_rx() status %8.8x len %d.\n", status,
 				   sp->rx_ringp[entry]->count & 0x3fff);
-		if (status & 0x0200) {
-			printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, "
-				   "status %8.8x!\n", dev->name, status);
-		} else if ( ! (status & 0x2000)) {
-			/* There was a fatal error.  This *should* be impossible. */
-			sp->stats.rx_errors++;
-			printk(KERN_ERR "%s: Anomalous event in speedo_rx(), status %8.8x.\n",
-				   dev->name, status);
+		if ((status & (RxErrTooBig|RxOK)) != RxOK) {
+			if (status & RxErrTooBig)
+				printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, "
+					   "status %8.8x!\n", dev->name, status);
+			else if ( ! (status & 0x2000)) {
+				/* There was a fatal error.  This *should* be impossible. */
+				sp->stats.rx_errors++;
+				printk(KERN_ERR "%s: Anomalous event in speedo_rx(), "
+					   "status %8.8x.\n",
+					   dev->name, status);
+			}
 		} else {
-			/* Malloc up new buffer, compatible with net-2e. */
 			int pkt_len = sp->rx_ringp[entry]->count & 0x3fff;
 			struct sk_buff *skb;
-			int rx_in_place = 0;
 
 			/* Check if the packet is long enough to just accept without
 			   copying to a properly sized skbuff. */
-			if (pkt_len > rx_copybreak) {
-				struct sk_buff *newskb;
-				char *temp;
-
-				/* Pass up the skb already on the Rx ring. */
-				skb = sp->rx_skbuff[entry];
-#ifdef KERNEL_1_2
-				temp = skb->data;
-				if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp)
-					printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match"
-						   " in speedo_rx: %p vs. %p / %p.\n", dev->name,
-						   bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
-						   temp, skb->data);
-				/* Get a fresh skbuff to replace the filled one. */
-				newskb = alloc_skb(PKT_BUF_SZ, GFP_ATOMIC);
-#else
-				temp = skb_put(skb, pkt_len);
-				if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp)
-					printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match"
-						   " in speedo_rx: %8.8x vs. %p / %p.\n", dev->name,
-						   sp->rx_ringp[entry]->rx_buf_addr, skb->head, temp);
-				/* Get a fresh skbuff to replace the filled one. */
-				newskb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
-#endif
-				if (newskb) {
-					struct RxFD *rxf;
-					rx_in_place = 1;
-					sp->rx_skbuff[entry] = newskb;
-					newskb->dev = dev;
-#ifdef KERNEL_1_2
-					/* Restore the data in the old header region. */
-					memcpy(skb->data - sizeof(struct RxFD),
-						   &sp->saved_skhead[entry], sizeof(struct RxFD));
-					/* Save the data in this header region. */
-					rxf = (struct RxFD *)(newskb->data - sizeof(struct RxFD));
-					sp->rx_ringp[entry] = rxf;
-					memcpy(&sp->saved_skhead[entry], rxf, sizeof(struct RxFD));
-					rxf->rx_buf_addr = virt_to_bus(newskb->data);
-#else
-					rxf = sp->rx_ringp[entry] = (struct RxFD *)newskb->tail;
-					skb_reserve(newskb, sizeof(struct RxFD));
-					/* Unused by i82557, consistency check only. */
-					rxf->rx_buf_addr = virt_to_bus(newskb->tail);
-#endif
-					rxf->status = 0x00000001;
-				} else			/* No memory, drop the packet. */
-				  skb = 0;
-			} else
-#ifdef KERNEL_1_2
-				skb = alloc_skb(pkt_len, GFP_ATOMIC);
-#else
-				skb = dev_alloc_skb(pkt_len + 2);
-#endif
-			if (skb == NULL) {
-				int i;
-				printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n", dev->name);
-				/* Check that at least two ring entries are free.
-				   If not, free one and mark stats->rx_dropped++. */
-				/* ToDo: This is not correct!!!!  We should count the number
-				   of linked-in Rx buffer to very that we have at least two
-				   remaining. */
-				for (i = 0; i < RX_RING_SIZE; i++)
-					if (! ((sp->rx_ringp[(entry+i) % RX_RING_SIZE]->status)
-						   & RX_COMPLETE))
-						break;
-
-				if (i > RX_RING_SIZE -2) {
-					sp->stats.rx_dropped++;
-					sp->rx_ringp[entry]->status = 0;
-					sp->cur_rx++;
-				}
-				break;
-			}
-			skb->dev = dev;
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
-			if (! rx_in_place) {
-				skb_reserve(skb, 2);	/* 16 byte align the data fields */
-#if defined(__i386__)   &&  notyet
+			if (pkt_len < rx_copybreak
+				&& (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
+				skb->dev = dev;
+				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
+				/* 'skb_put()' points to the start of sk_buff data area. */
+#if 1 || USE_IP_CSUM
 				/* Packet is in one chunk -- we can copy + cksum. */
-				eth_io_copy_and_sum(skb, bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
-									pkt_len, 0);
+				eth_copy_and_sum(skb,
+								 bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
+								 pkt_len, 0);
+				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
 					   bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), pkt_len);
 #endif
+			} else {
+				void *temp;
+				/* Pass up the already-filled skbuff. */
+				skb = sp->rx_skbuff[entry];
+				if (skb == NULL) {
+					printk(KERN_ERR "%s: Inconsistent Rx descriptor chain.\n",
+						   dev->name);
+					break;
+				}
+				sp->rx_skbuff[entry] = NULL;
+				temp = skb_put(skb, pkt_len);
+				if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp)
+					printk(KERN_ERR "%s: Rx consistency error -- the skbuff "
+						   "addresses do not match in speedo_rx: %p vs. %p "
+						   "/ %p.\n", dev->name,
+						   bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
+						   skb->head, temp);
+				sp->rx_ringp[entry] = NULL;
 			}
 			skb->protocol = eth_type_trans(skb, dev);
-#else
-#ifdef KERNEL_1_3
-#warning This code has only been tested with later 1.3.* kernels.
-			skb->len = pkt_len;
-			memcpy(skb->data, bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
-				   pkt_len);
-			/* Needed for 1.3.*. */
-			skb->protocol = eth_type_trans(skb, dev);
-#else	/* KERNEL_1_2 */
-			skb->len = pkt_len;
-			if (! rx_in_place) {
-				memcpy(skb->data,
-					   bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), pkt_len);
-			}
-#endif
-#endif
 			netif_rx(skb);
 			sp->stats.rx_packets++;
 		}
+		entry = (++sp->cur_rx) % RX_RING_SIZE;
+	}
 
-		/*	ToDo: This is better than before, but should be checked. */
-		{
-			struct RxFD *rxf = sp->rx_ringp[entry];
-			rxf->status = 0xC0000003; 		/* '3' for verification only */
-			rxf->link = 0;			/* None yet. */
-			rxf->count = 0;
-			rxf->size = PKT_BUF_SZ;
-			sp->last_rxf->link = virt_to_bus(rxf);
-			sp->last_rxf->status &= ~0xC0000000;
-			sp->last_rxf = rxf;
-			entry = (++sp->cur_rx) % RX_RING_SIZE;
+	/* Refill the Rx ring buffers. */
+	for (; sp->dirty_rx < sp->cur_rx; sp->dirty_rx++) {
+		struct RxFD *rxf;
+		entry = sp->dirty_rx % RX_RING_SIZE;
+		if (sp->rx_skbuff[entry] == NULL) {
+			struct sk_buff *skb;
+			/* Get a fresh skbuff to replace the consumed one. */
+			skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
+			sp->rx_skbuff[entry] = skb;
+			if (skb == NULL) {
+				sp->rx_ringp[entry] = NULL;
+				break;			/* Better luck next time!  */
+			}
+			rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail;
+			skb->dev = dev;
+			skb_reserve(skb, sizeof(struct RxFD));
+			rxf->rx_buf_addr = virt_to_bus(skb->tail);
+		} else {
+			rxf = sp->rx_ringp[entry];
 		}
+		rxf->status = 0xC0000001; 	/* '1' for driver use only. */
+		rxf->link = 0;			/* None yet. */
+		rxf->count = 0;
+		rxf->size = PKT_BUF_SZ;
+		sp->last_rxf->link = virt_to_bus(rxf);
+		sp->last_rxf->status &= ~0xC0000000;
+		sp->last_rxf = rxf;
 	}
 
 	sp->last_rx_time = jiffies;
@@ -1428,7 +1268,7 @@
 static int
 speedo_close(struct device *dev)
 {
-	int ioaddr = dev->base_addr;
+	long ioaddr = dev->base_addr;
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
 	int i;
 
@@ -1454,7 +1294,7 @@
 		sp->rx_skbuff[i] = 0;
 		/* Clear the Rx descriptors. */
 		if (skb)
-			dev_kfree_skb(skb);
+			dev_free_skb(skb);
 	}
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
@@ -1462,7 +1302,7 @@
 		sp->tx_skbuff[i] = 0;
 		/* Clear the Tx descriptors. */
 		if (skb)
-			dev_kfree_skb(skb);
+			dev_free_skb(skb);
 	}
 	if (sp->mc_setup_frm) {
 		kfree(sp->mc_setup_frm);
@@ -1507,7 +1347,7 @@
 speedo_get_stats(struct device *dev)
 {
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
-	int ioaddr = dev->base_addr;
+	long ioaddr = dev->base_addr;
 
 	if (sp->lstats.done_marker == 0xA007) {	/* Previous dump finished */
 		sp->stats.tx_aborted_errors += sp->lstats.tx_coll16_errs;
@@ -1530,11 +1370,10 @@
 	return &sp->stats;
 }
 
-#ifdef HAVE_PRIVATE_IOCTL
 static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd)
 {
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
-	int ioaddr = dev->base_addr;
+	long ioaddr = dev->base_addr;
 	u16 *data = (u16 *)&rq->ifr_data;
 	int phy = sp->phy[0] & 0x1f;
 
@@ -1545,7 +1384,7 @@
 		data[3] = mdio_read(ioaddr, data[0], data[1]);
 		return 0;
 	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
-		if (!capable(CAP_NET_ADMIN))
+		if (!suser())
 			return -EPERM;
 		mdio_write(ioaddr, data[0], data[1], data[2]);
 		return 0;
@@ -1553,7 +1392,6 @@
 		return -EOPNOTSUPP;
 	}
 }
-#endif  /* HAVE_PRIVATE_IOCTL */
 
 /* Set or clear the multicast filter for this adaptor.
    This is very ugly with Intel chips -- we usually have to execute an
@@ -1568,14 +1406,16 @@
 set_rx_mode(struct device *dev)
 {
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
-	int ioaddr = dev->base_addr;
+	long ioaddr = dev->base_addr;
+	struct descriptor *last_cmd;
 	char new_rx_mode;
 	unsigned long flags;
 	int entry, i;
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		new_rx_mode = 3;
-	} else if (dev->flags & IFF_ALLMULTI) {
+	} else if ((dev->flags & IFF_ALLMULTI)  ||
+			   dev->mc_count > multicast_filter_limit) {
 		new_rx_mode = 1;
 	} else
 		new_rx_mode = 0;
@@ -1588,57 +1428,54 @@
 	}
 
 	if (new_rx_mode != sp->rx_mode) {
-		/* We must change the configuration. Construct a CmdConfig frame. */
-		memcpy(sp->config_cmd_data, basic_config_cmd,sizeof(basic_config_cmd));
-		sp->config_cmd_data[1] = (txfifo << 4) | rxfifo;
-		sp->config_cmd_data[4] = rxdmacount;
-		sp->config_cmd_data[5] = txdmacount + 0x80;
-		sp->config_cmd_data[15] = (new_rx_mode & 2) ? 0x49 : 0x48;
-		sp->config_cmd_data[19] = sp->full_duplex ? 0xC0 : 0x80;
-		sp->config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05;
+		u8 *config_cmd_data;
+
+		spin_lock_irqsave(&sp->lock, flags);
+		entry = sp->cur_tx++ % TX_RING_SIZE;
+		last_cmd = sp->last_cmd;
+		sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+
+		sp->tx_skbuff[entry] = 0;			/* Redundant. */
+		sp->tx_ring[entry].status = (CmdSuspend | CmdConfigure) << 16;
+		sp->tx_ring[entry].link =
+			virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]);
+		config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr;
+		/* Construct a full CmdConfig frame. */
+		memcpy(config_cmd_data, i82558_config_cmd, sizeof(i82558_config_cmd));
+		config_cmd_data[1] = (txfifo << 4) | rxfifo;
+		config_cmd_data[4] = rxdmacount;
+		config_cmd_data[5] = txdmacount + 0x80;
+		config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0;
+		config_cmd_data[19] |= sp->full_duplex ? 0x40 : 0;
+		config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05;
 		if (sp->phy[0] & 0x8000) {			/* Use the AUI port instead. */
-		  sp->config_cmd_data[15] |= 0x80;
-		  sp->config_cmd_data[8] = 0;
+			config_cmd_data[15] |= 0x80;
+			config_cmd_data[8] = 0;
 		}
-		save_flags(flags);
-		cli();
-		/* Fill the "real" tx_ring frame with a no-op and point it to us. */
-		entry = sp->cur_tx++ % TX_RING_SIZE;
-		sp->tx_skbuff[entry] = 0;	/* Nothing to free. */
-		sp->tx_ring[entry].status = CmdNOp << 16;
-		sp->tx_ring[entry].link = virt_to_bus(&sp->config_cmd);
-		sp->config_cmd.status = 0;
-		sp->config_cmd.command = CmdSuspend | CmdConfigure;
-		sp->config_cmd.link =
-		  virt_to_bus(&(sp->tx_ring[sp->cur_tx % TX_RING_SIZE]));
-		sp->last_cmd->command &= ~CmdSuspend;
-		/* Immediately trigger the command unit resume. */
+		/* Trigger the command unit resume. */
+		last_cmd->command &= ~CmdSuspend;
+
 		wait_for_cmd_done(ioaddr + SCBCmd);
 		outw(CU_RESUME, ioaddr + SCBCmd);
-		sp->last_cmd = &sp->config_cmd;
-		restore_flags(flags);
-		if (speedo_debug > 5) {
-			int i;
-			printk(KERN_DEBUG " CmdConfig frame in entry %d.\n", entry);
-			for(i = 0; i < 32; i++)
-				printk(" %2.2x", ((unsigned char *)&sp->config_cmd)[i]);
-			printk(".\n");
-		}
+
+		spin_unlock_irqrestore(&sp->lock, flags);
 	}
 
-	if (new_rx_mode == 0  &&  dev->mc_count < 3) {
-		/* The simple case of 0-2 multicast list entries occurs often, and
+	if (new_rx_mode == 0  &&  dev->mc_count < 4) {
+		/* The simple case of 0-3 multicast list entries occurs often, and
 		   fits within one tx_ring[] entry. */
-		u16 *setup_params, *eaddrs;
 		struct dev_mc_list *mclist;
+		u16 *setup_params, *eaddrs;
 
-		save_flags(flags);
-		cli();
+		spin_lock_irqsave(&sp->lock, flags);
 		entry = sp->cur_tx++ % TX_RING_SIZE;
+		last_cmd = sp->last_cmd;
+		sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+
 		sp->tx_skbuff[entry] = 0;
 		sp->tx_ring[entry].status = (CmdSuspend | CmdMulticastList) << 16;
 		sp->tx_ring[entry].link =
-		  virt_to_bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]);
+			virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]);
 		sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */
 		setup_params = (u16 *)&sp->tx_ring[entry].tx_desc_addr;
 		*setup_params++ = dev->mc_count*6;
@@ -1651,36 +1488,42 @@
 			*setup_params++ = *eaddrs++;
 		}
 
-		sp->last_cmd->command &= ~CmdSuspend;
+		last_cmd->command &= ~CmdSuspend;
+
 		/* Immediately trigger the command unit resume. */
 		wait_for_cmd_done(ioaddr + SCBCmd);
 		outw(CU_RESUME, ioaddr + SCBCmd);
-		sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
-		restore_flags(flags);
+
+		spin_unlock_irqrestore(&sp->lock, flags);
 	} else if (new_rx_mode == 0) {
-		/* This does not work correctly, but why not? */
 		struct dev_mc_list *mclist;
-		u16 *eaddrs;
+		u16 *setup_params, *eaddrs;
 		struct descriptor *mc_setup_frm = sp->mc_setup_frm;
-		u16 *setup_params = (u16 *)mc_setup_frm->params;
 		int i;
 
 		if (sp->mc_setup_frm_len < 10 + dev->mc_count*6
 			|| sp->mc_setup_frm == NULL) {
-			/* Allocate a new frame, 10bytes + addrs, with a few
-			   extra entries for growth. */
+			/* Allocate a full setup frame, 10bytes + <max addrs>. */
 			if (sp->mc_setup_frm)
 				kfree(sp->mc_setup_frm);
-			sp->mc_setup_frm_len = 10 + dev->mc_count*6 + 24;
+			sp->mc_setup_busy = 0;
+			sp->mc_setup_frm_len = 10 + multicast_filter_limit*6;
 			sp->mc_setup_frm = kmalloc(sp->mc_setup_frm_len, GFP_ATOMIC);
 			if (sp->mc_setup_frm == NULL) {
-			  printk(KERN_ERR "%s: Failed to allocate a setup frame.\n", dev->name);
+				printk(KERN_ERR "%s: Failed to allocate a setup frame.\n",
+					   dev->name);
 				sp->rx_mode = -1; /* We failed, try again. */
 				return;
 			}
 		}
+		/* If we are busy, someone might be quickly adding to the MC list.
+		   Try again later when the list changes stop. */
+		if (sp->mc_setup_busy) {
+			sp->rx_mode = -1;
+			return;
+		}
 		mc_setup_frm = sp->mc_setup_frm;
-		/* Construct the new setup frame. */
+		/* Fill the setup frame. */
 		if (speedo_debug > 1)
 			printk(KERN_DEBUG "%s: Constructing a setup frame at %p, "
 				   "%d bytes.\n",
@@ -1688,7 +1531,7 @@
 		mc_setup_frm->status = 0;
 		mc_setup_frm->command = CmdSuspend | CmdIntr | CmdMulticastList;
 		/* Link set below. */
-		setup_params = (u16 *)mc_setup_frm->params;
+		setup_params = (u16 *)&mc_setup_frm->params;
 		*setup_params++ = dev->mc_count*6;
 		/* Fill in the multicast addresses. */
 		for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
@@ -1700,13 +1543,12 @@
 		}
 
 		/* Disable interrupts while playing with the Tx Cmd list. */
-		save_flags(flags);
-		cli();
-		entry = sp->cur_tx++ % TX_RING_SIZE;
+		spin_lock_irqsave(&sp->lock, flags);
 
-		if (speedo_debug > 5)
-			printk(" CmdMCSetup frame length %d in entry %d.\n",
-				   dev->mc_count, entry);
+		entry = sp->cur_tx++ % TX_RING_SIZE;
+		last_cmd = sp->last_cmd;
+		sp->last_cmd = mc_setup_frm;
+		sp->mc_setup_busy++;
 
 		/* Change the command to a NoOp, pointing to the CmdMulti command. */
 		sp->tx_skbuff[entry] = 0;
@@ -1715,41 +1557,25 @@
 
 		/* Set the link in the setup frame. */
 		mc_setup_frm->link =
-		  virt_to_bus(&(sp->tx_ring[sp->cur_tx % TX_RING_SIZE]));
+			virt_to_bus(&(sp->tx_ring[(entry+1) % TX_RING_SIZE]));
+
+		last_cmd->command &= ~CmdSuspend;
 
-		sp->last_cmd->command &= ~CmdSuspend;
 		/* Immediately trigger the command unit resume. */
 		wait_for_cmd_done(ioaddr + SCBCmd);
 		outw(CU_RESUME, ioaddr + SCBCmd);
-		sp->last_cmd = mc_setup_frm;
-		restore_flags(flags);
-		if (speedo_debug > 1)
-			printk(KERN_DEBUG "%s: Last command at %p is %4.4x.\n",
-				   dev->name, sp->last_cmd, sp->last_cmd->command);
+
+		spin_unlock_irqrestore(&sp->lock, flags);
+
+		if (speedo_debug > 5)
+			printk(" CmdMCSetup frame length %d in entry %d.\n",
+				   dev->mc_count, entry);
 	}
 
 	sp->rx_mode = new_rx_mode;
 }
 
 #ifdef MODULE
-#if (LINUX_VERSION_CODE < VERSION(1,3,38))	/* 1.3.38 and later */
-char kernel_version[] = UTS_RELEASE;
-#endif
-
-#if LINUX_VERSION_CODE > 0x20118
-MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
-MODULE_DESCRIPTION("Intel i82557/i82558 EtherExpressPro driver");
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(congenb, "i");
-MODULE_PARM(txfifo, "i");
-MODULE_PARM(rxfifo, "i");
-MODULE_PARM(txdmacount, "i");
-MODULE_PARM(rxdmacount, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(max_interrupt_work, "i");
-#endif
 
 int
 init_module(void)
@@ -1796,7 +1622,8 @@
 
 /*
  * Local variables:
- *  compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c"
+ *  compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
+ *  SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
  *  c-indent-level: 4
  *  c-basic-offset: 4
  *  tab-width: 4
diff -u --recursive --new-file v2.1.125/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- v2.1.125/linux/drivers/net/eth16i.c	Thu Feb 12 20:56:08 1998
+++ linux/drivers/net/eth16i.c	Fri Oct  9 11:56:59 1998
@@ -1,122 +1,207 @@
 /* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
-
-   Written 1994-95 by Mika Kuoppala
-
-   Copyright (C) 1994, 1995 by Mika Kuoppala
-   Based on skeleton.c and at1700.c by Donald Becker
+   
+   Written 1994-1998 by Mika Kuoppala
+   
+   Copyright (C) 1994-1998 by Mika Kuoppala
+   Based on skeleton.c and heavily on at1700.c by Donald Becker
 
    This software may be used and distributed according to the terms
    of the GNU Public Licence, incorporated herein by reference.
 
-   The author may be reached as miku@elt.icl.fi
+   The author may be reached as miku@iki.fi
 
    This driver supports following cards :
 	- ICL EtherTeam 16i
-	- ICL EtherTeam 32 EISA
+	- ICL EtherTeam 32 EISA 
+	  (Uses true 32 bit transfers rather than 16i compability mode)
+
+   Example Module usage:
+        insmod eth16i.o ioaddr=0x2a0 mediatype=bnc
+
+	mediatype can be one of the following: bnc,tp,dix,auto,eprom
 
+	'auto' will try to autoprobe mediatype.
+	'eprom' will use whatever type defined in eprom.
+
+   I have benchmarked driver with PII/300Mhz as a ftp client
+   and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec.
+   
    Sources:
      - skeleton.c  a sample network driver core for linux,
        written by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
-     - at1700.c a driver for Allied Telesis AT1700, written
+     - at1700.c a driver for Allied Telesis AT1700, written 
        by Donald Becker.
      - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
        written by Markku Viima
      - The Fujitsu MB86965 databook.
-
-   Valuable assistance from:
-	Markku Viima (ICL)
-	Ari Valve (ICL)
+   
+   Author thanks following persons due to their valueble assistance:    
+        Markku Viima (ICL)
+	Ari Valve (ICL)      
+	Donald Becker
+	Kurt Huwig <kurt@huwig.de>
 
    Revision history:
 
    Version	Date		Description
-
-   0.01		15.12-94	Initial version (card detection)
+   
+   0.01         15.12-94        Initial version (card detection)
    0.02         23.01-95        Interrupt is now hooked correctly
    0.03         01.02-95        Rewrote initialization part
    0.04         07.02-95        Base skeleton done...
-				Made a few changes to signature checking
-				to make it a bit reliable.
-				- fixed bug in tx_buf mapping
-				- fixed bug in initialization (DLC_EN
-				  wasn't enabled when initialization
-				  was done.)
-   0.05		08.02-95	If there were more than one packet to send,
-				transmit was jammed due to invalid
-				register write...now fixed
-   0.06         19.02-95        Rewrote interrupt handling
+                                Made a few changes to signature checking
+                                to make it a bit reliable.
+                                - fixed bug in tx_buf mapping
+                                - fixed bug in initialization (DLC_EN
+                                  wasn't enabled when initialization
+                                  was done.)
+   0.05         08.02-95        If there were more than one packet to send,
+                                transmit was jammed due to invalid
+                                register write...now fixed
+   0.06         19.02-95        Rewrote interrupt handling        
    0.07         13.04-95        Wrote EEPROM read routines
                                 Card configuration now set according to
-				data read from EEPROM
+                                data read from EEPROM
    0.08         23.06-95        Wrote part that tries to probe used interface
                                 port if AUTO is selected
 
-   0.09         01.09-95	Added module support
-
-   0.10         04.09-95	Fixed receive packet allocation to work
-        			with kernels > 1.3.x
+   0.09         01.09-95        Added module support
+   
+   0.10         04.09-95        Fixed receive packet allocation to work
+                                with kernels > 1.3.x
+      
+   0.20		20.09-95	Added support for EtherTeam32 EISA	
 
-   0.20		20.09-95	Added support for EtherTeam32 EISA
-
-   0.21         17.10-95        Removed the unnecessary extern
+   0.21         17.10-95        Removed the unnecessary extern 
 				init_etherdev() declaration. Some
 				other cleanups.
+   				
+   0.22		22.02-96	Receive buffer was not flushed
+				correctly when faulty packet was
+				received. Now fixed.
+
+   0.23		26.02-96	Made resetting the adapter	
+			 	more reliable.
+   
+   0.24		27.02-96	Rewrote faulty packet handling in eth16i_rx
+
+   0.25		22.05-96	kfree() was missing from cleanup_module.
+
+   0.26		11.06-96	Sometimes card was not found by 
+				check_signature(). Now made more reliable.
+   
+   0.27		23.06-96	Oops. 16 consecutive collisions halted 
+				adapter. Now will try to retransmit 
+				MAX_COL_16 times before finally giving up.
+   
+   0.28	        28.10-97	Added dev_id parameter (NULL) for free_irq
+
+   0.29         29.10-97        Multiple card support for module users
+
+   0.30         30.10-97        Fixed irq allocation bug.
+                                (request_irq moved from probe to open)
+
+   0.30a        21.08-98        Card detection made more relaxed. Driver
+                                had problems with some TCP/IP-PROM boots
+				to find the card. Suggested by 
+				Kurt Huwig <kurt@huwig.de>
+
+   0.31         28.08-98        Media interface port can now be selected
+                                with module parameters or kernel
+				boot parameters. 
+
+   0.32         31.08-98        IRQ was never freed if open/close 
+                                pair wasn't called. Now fixed.
+   
+   0.33         10.09-98        When eth16i_open() was called after
+                                eth16i_close() chip never recovered.
+				Now more shallow reset is made on
+				close.
+
    Bugs:
-	In some cases the interface autoprobing code doesn't find
-	the correct interface type. In this case you can
-	manually choose the interface type in DOS with E16IC.EXE which is
+	In some cases the media interface autoprobing code doesn't find 
+	the correct interface type. In this case you can 
+	manually choose the interface type in DOS with E16IC.EXE which is 
 	configuration software for EtherTeam16i and EtherTeam32 cards.
+	This is also true for IRQ setting. You cannot use module
+	parameter to configure IRQ of the card (yet). 
 
    To do:
 	- Real multicast support
+	- Rewrite the media interface autoprobing code. Its _horrible_ !
+	- Possibly merge all the MB86965 specific code to external
+	  module for use by eth16.c and Donald's at1700.c
+	- IRQ configuration with module parameter. I will do
+	  this when i will get enough info about setting
+	  irq without configuration utility.
 */
 
-static char *version =
-	"eth16i.c: v0.21 17-10-95 Mika Kuoppala (miku@elt.icl.fi)\n";
+static char *version = 
+    "eth16i.c: v0.33 10-09-98 Mika Kuoppala (miku@iki.fi)\n";
 
 #include <linux/module.h>
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
+#include <linux/types.h>		  
+#include <linux/fcntl.h>		  
+#include <linux/interrupt.h>		  
+#include <linux/ptrace.h>		  
+#include <linux/ioport.h>		  
+#include <linux/in.h>		  
+#include <linux/malloc.h>		  
+#include <linux/string.h>		  
 #include <linux/errno.h>
-#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
+#include <asm/system.h>		  
+#include <asm/bitops.h>		  
+#include <asm/io.h>		  
 #include <asm/dma.h>
-#include <asm/delay.h>
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#if LINUX_VERSION_CODE >= 0x20123
+#include <linux/init.h>
+#else
+#define __init
+#define __initdata
+#define __initfunc(x) x
+#endif
+
+#if LINUX_VERSION_CODE < 0x20138
+#define test_and_set_bit(val,addr) set_bit(val,addr)
+#endif
+
+#if LINUX_VERSION_CODE < 0x020100
+typedef struct enet_statistics eth16i_stats_type;
+#else
+typedef struct net_device_stats eth16i_stats_type;
+#endif
 
 /* Few macros */
-#define BIT(a)		        ( (1 << (a)) )
-#define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
+#define BIT(a)		       ( (1 << (a)) )  
+#define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) 
 #define BITCLR(ioaddr, bnum)   ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
 
 /* This is the I/O address space for Etherteam 16i adapter. */
-#define ETH16I_IO_EXTENT 32
+#define ETH16I_IO_EXTENT       32
 
 /* Ticks before deciding that transmit has timed out */
-#define TIMEOUT_TICKS          30
+#define TX_TIMEOUT             (400*HZ/1000)
 
 /* Maximum loop count when receiving packets */
-#define MAX_RX_LOOP            40
+#define MAX_RX_LOOP            20
 
 /* Some interrupt masks */
-#define ETH16I_INTR_ON	       0x8f82
+#define ETH16I_INTR_ON	       0xef8a       /* Higher is receive mask */
 #define ETH16I_INTR_OFF	       0x0000
-
+	 
 /* Buffers header status byte meanings */
 #define PKT_GOOD               BIT(5)
 #define PKT_GOOD_RMT           BIT(4)
@@ -131,6 +216,7 @@
 #define NET_BUSY               BIT(6)
 #define TX_PKT_RCD             BIT(5)
 #define CR_LOST                BIT(4)
+#define TX_JABBER_ERR	       BIT(3)
 #define COLLISION              BIT(2)
 #define COLLISIONS_16          BIT(1)
 
@@ -142,7 +228,7 @@
 #define ALIGN_ERR              BIT(2)
 #define CRC_ERR                BIT(1)
 #define RX_BUF_OVERFLOW        BIT(0)
-
+              
 /* Transmit Interrupt Enable Register (DLCR2) */
 #define TX_INTR_REG            2
 #define TX_INTR_DONE           BIT(7)
@@ -181,18 +267,18 @@
 #define SRAM_CYCLE_TIME_100NS  BIT(6)
 #define SYSTEM_BUS_WIDTH_8     BIT(5)       /* 1 = 8bit, 0 = 16bit */
 #define BUFFER_WIDTH_8         BIT(4)       /* 1 = 8bit, 0 = 16bit */
-#define TBS1                   BIT(3)
+#define TBS1                   BIT(3)       
 #define TBS0                   BIT(2)
-#define MBS1                   BIT(1)       /* 00=8kb,  01=16kb  */
-#define MBS0                   BIT(0)       /* 10=32kb, 11=64kb  */
+#define SRAM_BS1               BIT(1)       /* 00=8kb,  01=16kb  */
+#define SRAM_BS0               BIT(0)       /* 10=32kb, 11=64kb  */
 
-#ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */
-#define ETH16I_TX_BUF_SIZE     2             /* 2 = 8kb, 3 = 16kb */
-#endif
-#define TX_BUF_1x2048            0
-#define TX_BUF_2x2048            1
-#define TX_BUF_2x4098            2
-#define TX_BUF_2x8192            3
+#ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */ 
+#define ETH16I_TX_BUF_SIZE     3             /* 2 = 8kb, 3 = 16kb */
+#endif                                      
+#define TX_BUF_1x2048          0
+#define TX_BUF_2x2048          1
+#define TX_BUF_2x4098          2
+#define TX_BUF_2x8192          3
 
 /* Configuration Register 1 (DLCR7) */
 #define CONFIG_REG_1           7
@@ -212,18 +298,21 @@
 #define HASH_TABLE_RB          1
 
 /* Buffer memory ports */
-#define BUFFER_MEM_PORT_LB    8
-#define DATAPORT              BUFFER_MEM_PORT_LB
-#define BUFFER_MEM_PORT_HB    9
+#define BUFFER_MEM_PORT_LB     8
+#define DATAPORT               BUFFER_MEM_PORT_LB
+#define BUFFER_MEM_PORT_HB     9
 
 /* 16 Collision control register (BMPR11) */
 #define COL_16_REG             11
 #define HALT_ON_16             0x00
 #define RETRANS_AND_HALT_ON_16 0x02
 
+/* Maximum number of attempts to send after 16 concecutive collisions */
+#define MAX_COL_16	       10
+
 /* DMA Burst and Transceiver Mode Register (BMPR13) */
 #define TRANSCEIVER_MODE_REG   13
-#define TRANSCEIVER_MODE_RB    2
+#define TRANSCEIVER_MODE_RB    2         
 #define IO_BASE_UNLOCK	       BIT(7)
 #define LOWER_SQUELCH_TRESH    BIT(6)
 #define LINK_TEST_DISABLE      BIT(5)
@@ -232,9 +321,8 @@
 
 /* Filter Self Receive Register (BMPR14)  */
 #define FILTER_SELF_RX_REG     14
-#define SKIP_RECEIVE_PACKET    BIT(2)
+#define SKIP_RX_PACKET         BIT(2)
 #define FILTER_SELF_RECEIVE    BIT(0)
-#define RX_BUF_SKIP_PACKET     SKIP_RECEIVE_PACKET | FILTER_SELF_RECEIVE
 
 /* EEPROM Control Register (BMPR 16) */
 #define EEPROM_CTRL_REG        16
@@ -254,19 +342,20 @@
 #define EEPROM_READ            0x80
 
 /* NMC93CSx6 EEPROM Addresses */
-#define E_NODEID_0                     0x02
-#define E_NODEID_1                     0x03
-#define E_NODEID_2                     0x04
-#define E_PORT_SELECT                  0x14
-  #define E_PORT_BNC                   0
-  #define E_PORT_DIX                   1
-  #define E_PORT_TP                    2
-  #define E_PORT_AUTO                  3
-#define E_PRODUCT_CFG                  0x30
-
+#define E_NODEID_0             0x02
+#define E_NODEID_1             0x03
+#define E_NODEID_2             0x04
+#define E_PORT_SELECT          0x14
+  #define E_PORT_BNC           0x00
+  #define E_PORT_DIX           0x01
+  #define E_PORT_TP            0x02
+  #define E_PORT_AUTO          0x03
+  #define E_PORT_FROM_EPROM    0x04
+#define E_PRODUCT_CFG          0x30
+ 
 
 /* Macro to slow down io between EEPROM clock transitions */
-#define eeprom_slow_io() 	udelay(100)	/* FIXME: smaller but right value here */
+#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0)
 
 /* Jumperless Configuration Register (BMPR19) */
 #define JUMPERLESS_CONFIG      19
@@ -277,31 +366,24 @@
 #define RESET                  ID_ROM_0
 
 /* This is the I/O address list to be probed when seeking the card */
-static unsigned int eth16i_portlist[] __initdata = {
-	0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
-};
+static unsigned int eth16i_portlist[] =
+   { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 };
 
-static unsigned int eth32i_portlist[] __initdata = {
-	0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
-	0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0
-};
+static unsigned int eth32i_portlist[] =
+   { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
+     0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 };
 
 /* This is the Interrupt lookup table for Eth16i card */
-static unsigned int eth16i_irqmap[] __initdata = {
-	9, 10, 5, 15
-};
+static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15, 0 };
+#define NUM_OF_ISA_IRQS    4
 
 /* This is the Interrupt lookup table for Eth32i card */
-static unsigned int eth32i_irqmap[] __initdata = {
-	3, 5, 7, 9, 10, 11, 12, 15
-};
-
+static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15, 0 };  
 #define EISA_IRQ_REG	0xc89
+#define NUM_OF_EISA_IRQS   8
 
-static unsigned int eth16i_tx_buf_map[] = {
-	2048, 2048, 4096, 8192 
-};
-unsigned int boot = 1;
+static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
+static unsigned int boot = 1;
 
 /* Use 0 for production, 1 for verification, >2 for debug */
 #ifndef ETH16I_DEBUG
@@ -310,60 +392,76 @@
 static unsigned int eth16i_debug = ETH16I_DEBUG;
 
 /* Information for each board */
-struct eth16i_local
-{
-	struct net_device_stats stats;
-	unsigned int tx_started:1;
-	unsigned char tx_queue;	       /* Number of packets in transmit buffer */
-	unsigned short tx_queue_len;
-	unsigned int tx_buf_size;
-	unsigned long open_time;
+
+struct eth16i_local {
+	eth16i_stats_type stats;
+	unsigned char     tx_started;
+	unsigned char     tx_buf_busy;
+	unsigned short    tx_queue;  /* Number of packets in transmit buffer */
+	unsigned short    tx_queue_len;         
+	unsigned int      tx_buf_size;
+	unsigned long     open_time;
+	unsigned long     tx_buffered_packets;  
+	unsigned long     col_16;
 };
 
 /* Function prototypes */
 
-extern int eth16i_probe(struct device *dev);
+extern int     eth16i_probe(struct device *dev);
+
+static int     eth16i_probe1(struct device *dev, int ioaddr);
+static int     eth16i_check_signature(int ioaddr);
+static int     eth16i_probe_port(int ioaddr);
+static void    eth16i_set_port(int ioaddr, int porttype);
+static int     eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l);
+static int     eth16i_receive_probe_packet(int ioaddr);
+static int     eth16i_get_irq(int ioaddr);
+static int     eth16i_read_eeprom(int ioaddr, int offset);
+static int     eth16i_read_eeprom_word(int ioaddr);
+static void    eth16i_eeprom_cmd(int ioaddr, unsigned char command);
+static int     eth16i_open(struct device *dev);
+static int     eth16i_close(struct device *dev);
+static int     eth16i_tx(struct sk_buff *skb, struct device *dev);
+static void    eth16i_rx(struct device *dev);
+static void    eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void    eth16i_reset(struct device *dev);
+static void    eth16i_skip_packet(struct device *dev);
+static void    eth16i_multicast(struct device *dev); 
+static void    eth16i_select_regbank(unsigned char regbank, int ioaddr);
+static void    eth16i_initialize(struct device *dev);
+
+#if 0
+static int     eth16i_set_irq(struct device *dev);
+#endif
+
+#ifdef MODULE
+static ushort  eth16i_parse_mediatype(const char* s);
+#endif
 
-static int eth16i_probe1(struct device *dev, short ioaddr);
-static int eth16i_check_signature(short ioaddr);
-static int eth16i_probe_port(short ioaddr);
-static void eth16i_set_port(short ioaddr, int porttype);
-static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l);
-static int eth16i_receive_probe_packet(short ioaddr);
-static int eth16i_get_irq(short ioaddr);
-static int eth16i_read_eeprom(int ioaddr, int offset);
-static int eth16i_read_eeprom_word(int ioaddr);
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command);
-static int eth16i_open(struct device *dev);
-static int eth16i_close(struct device *dev);
-static int eth16i_tx(struct sk_buff *skb, struct device *dev);
-static void eth16i_rx(struct device *dev);
-static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void eth16i_multicast(struct device *dev);
-static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
-static void eth16i_initialize(struct device *dev);
-static struct net_device_stats *eth16i_get_stats(struct device *dev);
+static struct enet_statistics *eth16i_get_stats(struct device *dev);
 
 static char *cardname = "ICL EtherTeam 16i/32";
 
-#ifdef HAVE_DEVLIST
+#ifdef HAVE_DEVLIST 
+
 /* Support for alternate probe manager */
-/struct netdev_entry eth16i_drv =
-   {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list};
+/struct netdev_entry eth16i_drv = 
+ {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; 
 
 #else  /* Not HAVE_DEVLIST */
+
 __initfunc(int eth16i_probe(struct device *dev))
 {
 	int i;
 	int ioaddr;
 	int base_addr = dev ? dev->base_addr : 0;
+    
+	if(eth16i_debug > 4) 
+		printk(KERN_DEBUG "Probing started for %s\n", cardname);
 
-	if(eth16i_debug > 4)
-		printk("Probing started for %s\n", cardname);
-
-	if(base_addr > 0x1ff)		/* Check only single location */
+	if(base_addr > 0x1ff)           /* Check only single location */
 		return eth16i_probe1(dev, base_addr);
-	else if(base_addr != 0)		/* Don't probe at all */
+	else if(base_addr != 0)         /* Don't probe at all */
 		return ENXIO;
 
 	/* Seek card from the ISA io address space */
@@ -377,88 +475,107 @@
 	/* Seek card from the EISA io address space */
 	for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) {
 		if(check_region(ioaddr, ETH16I_IO_EXTENT))
-	continue;
+			continue;
 		if(eth16i_probe1(dev, ioaddr) == 0)
-	return 0;
-	 }
+			return 0;
+	}
 
 	return ENODEV;
 }
-#endif	/* Not HAVE_DEVLIST */
+#endif  /* Not HAVE_DEVLIST */
 
-__initfunc(static int eth16i_probe1(struct device *dev, short ioaddr))
+__initfunc(static int eth16i_probe1(struct device *dev, int ioaddr))
 {
 	static unsigned version_printed = 0;
-	unsigned int irq = 0;
-	boot = 1;          /* To inform initialization that we are in boot probe */
+	boot = 1;  /* To inform initilization that we are in boot probe */
 
 	/*
-		 The MB86985 chip has on register which holds information in which
-		 io address the chip lies. First read this register and compare
-		 it to our current io address and if match then this could
-		 be our chip.
-	*/
+	  The MB86985 chip has on register which holds information in which 
+	  io address the chip lies. First read this register and compare
+	  it to our current io address and if match then this could
+	  be our chip.
+	  */
 
 	if(ioaddr < 0x1000) {
-		if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr)
+	
+		if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] 
+		   != ioaddr)
 			return -ENODEV;
 	}
 
 	/* Now we will go a bit deeper and try to find the chip's signature */
 
-	if(eth16i_check_signature(ioaddr) != 0) /* Can we find the signature here */
+	if(eth16i_check_signature(ioaddr) != 0) 
 		return -ENODEV;
 
-	/*
-		 Now it seems that we have found an ethernet chip in this particular
-		 ioaddr. The MB86985 chip has this feature, that when you read a
-		 certain register it will increase its io base address to next
-		 configurable slot. Now when we have found the chip, first thing is
-		 to make sure that the chip's ioaddr will hold still here.
-	*/
+	/* 
+	   Now it seems that we have found a ethernet chip in this particular
+	   ioaddr. The MB86985 chip has this feature, that when you read a 
+	   certain register it will increase it's io base address to next
+	   configurable slot. Now when we have found the chip, first thing is
+	   to make sure that the chip's ioaddr will hold still here.
+	   */
 
 	eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
 	outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
 
-	outb(0x00, ioaddr + RESET);             /* Will reset some parts of chip */
-	BITSET(ioaddr + CONFIG_REG_0, BIT(7));  /* This will disable the data link */
+	outb(0x00, ioaddr + RESET);             /* Reset some parts of chip */
+	BITSET(ioaddr + CONFIG_REG_0, BIT(7));  /* Disable the data link */
 
 	if(dev == NULL)
-		dev = init_etherdev(0, sizeof(struct eth16i_local));
+		dev = init_etherdev(0, 0);
 
 	if( (eth16i_debug & version_printed++) == 0)
-		printk(version);
+		printk(KERN_INFO "%s", version);
 
 	dev->base_addr = ioaddr;
+	
+#if 0
+	if(dev->irq) {
+		if(eth16i_set_irq(dev)) {
+			dev->irq = eth16i_get_irq(ioaddr);
+		}
+
+	}
+	else {
+#endif
 
-	irq = eth16i_get_irq(ioaddr);
-	dev->irq = irq;
+	dev->irq = eth16i_get_irq(ioaddr);
 
 	/* Try to obtain interrupt vector */
-	if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i", dev)) {
-		printk("%s: %s at %#3x, but is unusable due
-		       conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq);
-		return EAGAIN;
+
+	if (request_irq(dev->irq, (void *)&eth16i_interrupt, 0, "eth16i", dev)) {	
+		printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n", 
+		       dev->name, cardname, ioaddr, dev->irq);
+		return -EAGAIN;
 	}
 
-	printk("%s: %s at %#3x, IRQ %d, ",
-	 dev->name, cardname, ioaddr, dev->irq);
+#if 0
+	irq2dev_map[dev->irq] = dev;
+#endif
+
+	printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ",
+	       dev->name, cardname, ioaddr, dev->irq);
 
 	/* Let's grab the region */
 	request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i");
 
 	/* Now we will have to lock the chip's io address */
 	eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
-	outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
+	outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); 
 
-	eth16i_initialize(dev);	 /* Initialize rest of the chip's registers */
+	eth16i_initialize(dev);   /* Initialize rest of the chip's registers */
 
 	/* Now let's same some energy by shutting down the chip ;) */
 	BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
 
 	/* Initialize the device structure */
-	if(dev->priv == NULL)
+	if(dev->priv == NULL) {
 		dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
+		if(dev->priv == NULL)
+			return -ENOMEM;
+	}
+
 	memset(dev->priv, 0, sizeof(struct eth16i_local));
 
 	dev->open               = eth16i_open;
@@ -478,7 +595,7 @@
 
 static void eth16i_initialize(struct device *dev)
 {
-	short ioaddr = dev->base_addr;
+	int ioaddr = dev->base_addr;
 	int i, node_w = 0;
 	unsigned char node_byte = 0;
 
@@ -489,11 +606,9 @@
 		((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
 	}
 
-	for(i = 0; i < 6; i++) 
-	{
+	for(i = 0; i < 6; i++) { 
 		outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
-		if(boot) 
-		{
+		if(boot) {
 			printk("%02x", inb(ioaddr + NODE_ID_0 + i));
 			if(i != 5)
 				printk(":");
@@ -502,14 +617,14 @@
 
 	/* Now we will set multicast addresses to accept none */
 	eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
-	for(i = 0; i < 8; i++)
+	for(i = 0; i < 8; i++) 
 		outb(0x00, ioaddr + HASH_TABLE_0 + i);
 
 	/*
-		 Now let's disable the transmitter and receiver, set the buffer ram
-		 cycle time, bus width and buffer data path width. Also we shall
-		 set transmit buffer size and total buffer size.
-	*/
+	  Now let's disable the transmitter and receiver, set the buffer ram 
+	  cycle time, bus width and buffer data path width. Also we shall
+	  set transmit buffer size and total buffer size.
+	  */
 
 	eth16i_select_regbank(2, ioaddr);
 
@@ -519,38 +634,56 @@
 	if( (node_w & 0xFF00) == 0x0800)
 		node_byte |= BUFFER_WIDTH_8;
 
-	node_byte |= MBS1;
+	node_byte |= SRAM_BS1;
 
 	if( (node_w & 0x00FF) == 64)
-		node_byte |= MBS0;
+		node_byte |= SRAM_BS0;
 
 	node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
 
 	outb(node_byte, ioaddr + CONFIG_REG_0);
 
 	/* We shall halt the transmitting, if 16 collisions are detected */
-	outb(RETRANS_AND_HALT_ON_16, ioaddr + COL_16_REG);
+	outb(HALT_ON_16, ioaddr + COL_16_REG);
 
-	if(boot) /* Now set port type */
-	{
-		char *porttype[] = {"BNC", "DIX", "TP", "AUTO"};
+#ifdef MODULE
+	/* if_port already set by init_module() */
+#else
+	dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ? 
+		dev->mem_start : E_PORT_FROM_EPROM;
+#endif
 
-		ushort ptype = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
-		dev->if_port = (ptype & 0x00FF);
+	/* Set interface port type */
+	if(boot) {
+		char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" };
 
-		printk(" %s interface.\n", porttype[dev->if_port]);
+		switch(dev->if_port)
+		{
+
+		case E_PORT_FROM_EPROM:
+			dev->if_port = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
+			break;
+
+		case E_PORT_AUTO:
+			dev->if_port = eth16i_probe_port(ioaddr);
+			break;
+			
+		case E_PORT_BNC:
+		case E_PORT_TP:
+		case E_PORT_DIX:
+			break;
+		}
 
-		if(ptype == E_PORT_AUTO)
-			ptype = eth16i_probe_port(ioaddr);
+		printk(" %s interface.\n", porttype[dev->if_port]);
 
-		eth16i_set_port(ioaddr, ptype);
+		eth16i_set_port(ioaddr, dev->if_port);
 	}
 
 	/* Set Receive Mode to normal operation */
 	outb(MODE_2, ioaddr + RECEIVE_MODE_REG);
 }
 
-static int eth16i_probe_port(short ioaddr)
+static int eth16i_probe_port(int ioaddr)
 {
 	int i;
 	int retcode;
@@ -579,136 +712,163 @@
 		eth16i_set_port(ioaddr, i);
 
 		if(eth16i_debug > 1)
-			printk("Set port number %d\n", i);
+			printk(KERN_DEBUG "Set port number %d\n", i);
 
 		retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64);
-		if(retcode == 0) 
-		{
+		if(retcode == 0) {
 			retcode = eth16i_receive_probe_packet(ioaddr);
-			if(retcode != -1) 
-			{
+			if(retcode != -1) {
 				if(eth16i_debug > 1)
-					printk("Eth16i interface port found at %d\n", i);
+					printk(KERN_DEBUG "Eth16i interface port found at %d\n", i);
 				return i;
 			}
 		}
 		else {
 			if(eth16i_debug > 1)
-				printk("TRANSMIT_DONE timeout\n");
+				printk(KERN_DEBUG "TRANSMIT_DONE timeout when probing interface port\n");
 		}
 	}
 
 	if( eth16i_debug > 1)
-		printk("Using default port\n");
+		printk(KERN_DEBUG "Using default port\n");
 
 	return E_PORT_BNC;
 }
 
-static void eth16i_set_port(short ioaddr, int porttype)
-{
+static void eth16i_set_port(int ioaddr, int porttype)
+{ 
 	unsigned short temp = 0;
 
 	eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
 	outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG);
 
 	temp |= DIS_AUTO_PORT_SEL;
-	switch(porttype) 
-	{
 
-		case E_PORT_BNC :
-			temp |= AUI_SELECT;
-			break;
+	switch(porttype) {
 
-		case E_PORT_TP :
-			break;
+	case E_PORT_BNC :
+		temp |= AUI_SELECT;
+		break;
+
+	case E_PORT_TP :
+		break;
+
+	case E_PORT_DIX :
+		temp |= AUI_SELECT;
+		BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
+		break;
+	}  
 
-		case E_PORT_DIX :
-			temp |= AUI_SELECT;
-			BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
-			break;
-	}
 	outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
 
 	if(eth16i_debug > 1) {
-		printk("TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
-		printk("TRANSCEIVER_MODE_REG = %x\n", inb(ioaddr+TRANSCEIVER_MODE_REG));
+		printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
+		printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n", 
+		       inb(ioaddr+TRANSCEIVER_MODE_REG));
 	}
 }
 
-static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l)
+static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l)
 {
 	int starttime;
 
 	outb(0xff, ioaddr + TX_STATUS_REG);
 
 	outw(l, ioaddr + DATAPORT);
-	outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
+	outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);  
 
 	starttime = jiffies;
-	outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
+	outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); 
 
-	while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) 
-		if( (jiffies - starttime) > TIMEOUT_TICKS)
-			break;
-	return(0);
+	while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
+		if( (jiffies - starttime) > TX_TIMEOUT) {
+			return -1;
+		}
+	}
+
+	return 0;
 }
 
-static int eth16i_receive_probe_packet(short ioaddr)
+static int eth16i_receive_probe_packet(int ioaddr)
 {
 	int starttime;
 
 	starttime = jiffies;
 
-	while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) 
-	{
-		if( (jiffies - starttime) > TIMEOUT_TICKS) 
-		{
+	while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
+		if( (jiffies - starttime) > TX_TIMEOUT) {
+
 			if(eth16i_debug > 1)
-				printk("Timeout occurred waiting transmit packet received\n");
+				printk(KERN_DEBUG "Timeout occured waiting transmit packet received\n");
 			starttime = jiffies;
-			while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) 
-			{
-				if( (jiffies - starttime) > TIMEOUT_TICKS) 
-				{
+			while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
+				if( (jiffies - starttime) > TX_TIMEOUT) {
 					if(eth16i_debug > 1)
-						printk("Timeout occurred waiting receive packet\n");
+						printk(KERN_DEBUG "Timeout occured waiting receive packet\n");
 					return -1;
 				}
 			}
 
 			if(eth16i_debug > 1)
-				printk("RECEIVE_PACKET\n");
+				printk(KERN_DEBUG "RECEIVE_PACKET\n");
 			return(0); /* Found receive packet */
 		}
 	}
 
 	if(eth16i_debug > 1) {
-		printk("TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
-		printk("RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
+		printk(KERN_DEBUG "TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
+		printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
 	}
 
 	return(0); /* Return success */
 }
 
-static int eth16i_get_irq(short ioaddr)
+#if 0
+static int eth16i_set_irq(struct device* dev)
+{
+	const int ioaddr = dev->base_addr;
+	const int irq = dev->irq;
+	int i = 0;
+
+	if(ioaddr < 0x1000) {		
+		while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq)
+			i++;
+	
+		if(i < NUM_OF_ISA_IRQS) {
+			u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
+			cbyte = (cbyte & 0x3F) | (i << 6);
+			outb(cbyte, ioaddr + JUMPERLESS_CONFIG);
+			return 0;
+		}
+	}
+	else {
+		printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name);
+	}
+	
+	return -1;
+
+}
+#endif
+
+static int eth16i_get_irq(int ioaddr)
 {
 	unsigned char cbyte;
 
 	if( ioaddr < 0x1000) {
 		cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
-	return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
-	} else {	/* Oh..the card is EISA so method getting IRQ different */
-	unsigned short index = 0;
-	cbyte = inb(ioaddr + EISA_IRQ_REG);
-	while( (cbyte & 0x01) == 0) {
-		cbyte = cbyte >> 1;
-		index++;
-				}
-	return( eth32i_irqmap[ index ] );
+		return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
+	} else {  /* Oh..the card is EISA so method getting IRQ different */
+		unsigned short index = 0;
+		cbyte = inb(ioaddr + EISA_IRQ_REG);
+		while( (cbyte & 0x01) == 0) {
+			cbyte = cbyte >> 1;
+			index++;
+		}
+		return( eth32i_irqmap[ index ] );
 	}
 }
 
-static int eth16i_check_signature(short ioaddr)
+static int eth16i_check_signature(int ioaddr)
 {
 	int i;
 	unsigned char creg[4] = { 0 };
@@ -718,36 +878,37 @@
 		creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
 
 		if(eth16i_debug > 1)
-	printk("eth16i: read signature byte %x at %x\n", creg[i],
-				 ioaddr + TRANSMIT_MODE_REG + i);
+			printk("eth16i: read signature byte %x at %x\n", 
+			       creg[i],
+			       ioaddr + TRANSMIT_MODE_REG + i);
 	}
 
 	creg[0] &= 0x0F;      /* Mask collision cnr */
 	creg[2] &= 0x7F;      /* Mask DCLEN bit */
 
-#if 0
-/*
-	This was removed because the card was sometimes left to state
-  	from which it couldn't be find anymore. If there is need
-	to have a more strict check still this have to be fixed.
-*/
-	if( !( (creg[0] == 0x06) && (creg[1] == 0x41)) ) {
+#ifdef 0
+	/* 
+	   This was removed because the card was sometimes left to state
+	   from which it couldn't be find anymore. If there is need
+	   to more strict check still this have to be fixed.
+	   */
+	if( ! ((creg[0] == 0x06) && (creg[1] == 0x41)) ) {
 		if(creg[1] != 0x42)
 			return -1;
 	}
 #endif
 
-	if( !( (creg[2] == 0x36) && (creg[3] == 0xE0)) ) 
-	{
-		creg[2] &= 0x42;
+	if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
+		creg[2] &= 0x40;
 		creg[3] &= 0x03;
-
-		if( !( (creg[2] == 0x42) && (creg[3] == 0x00)) )
+		
+		if( !((creg[2] == 0x40) && (creg[3] == 0x00)) )
 			return -1;
 	}
-
+	
 	if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
 		return -1;
+	
 	if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
 		return -1;
 
@@ -763,20 +924,22 @@
 	data = eth16i_read_eeprom_word(ioaddr);
 	outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
 
-	return(data);
+	return(data);  
 }
 
 static int eth16i_read_eeprom_word(int ioaddr)
 {
 	int i;
 	int data = 0;
-
+     
 	for(i = 16; i > 0; i--) {
 		outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
 		eeprom_slow_io();
 		outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
 		eeprom_slow_io();
-		data = (data << 1) | ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
+		data = (data << 1) | 
+			((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
+		
 		eeprom_slow_io();
 	}
 
@@ -800,25 +963,26 @@
 		eeprom_slow_io();
 		outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
 		eeprom_slow_io();
-	}
+	} 
 }
 
 static int eth16i_open(struct device *dev)
 {
 	struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
 	int ioaddr = dev->base_addr;
-
+	
 	/* Powerup the chip */
 	outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
 
 	/* Initialize the chip */
-	eth16i_initialize(dev);
+	eth16i_initialize(dev);  
 
 	/* Set the transmit buffer size */
 	lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
 
-	if(eth16i_debug > 3)
-		printk("%s: transmit buffer size %d\n", dev->name, lp->tx_buf_size);
+	if(eth16i_debug > 0)
+		printk(KERN_DEBUG "%s: transmit buffer size %d\n", 
+		       dev->name, lp->tx_buf_size);
 
 	/* Now enable Transmitter and Receiver sections */
 	BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
@@ -832,15 +996,13 @@
 	lp->tx_queue_len = 0;
 
 	/* Turn on interrupts*/
-	outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
+	outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);  
 
 	dev->tbusy = 0;
 	dev->interrupt = 0;
 	dev->start = 1;
 
-#ifdef MODULE
 	MOD_INC_USE_COUNT;
-#endif
 
 	return 0;
 }
@@ -850,23 +1012,26 @@
 	struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
 	int ioaddr = dev->base_addr;
 
-	lp->open_time = 0;
+	eth16i_reset(dev);
+
+	/* Turn off interrupts*/
+	outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);  
 
-	dev->tbusy = 1;
 	dev->start = 0;
+	dev->tbusy = 1;
+
+	lp->open_time = 0;
 
 	/* Disable transmit and receive */
 	BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
 
 	/* Reset the chip */
-	outb(0xff, ioaddr + RESET);
+	/* outb(0xff, ioaddr + RESET); */
+	/* outw(0xffff, ioaddr + TX_STATUS_REG);    */
+	
+	outb(0x00, ioaddr + CONFIG_REG_1);
 
-	/* Save some energy by switching off power */
-	BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
-
-#ifdef MODULE
 	MOD_DEC_USE_COUNT;
-#endif
 
 	return 0;
 }
@@ -875,88 +1040,120 @@
 {
 	struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
 	int ioaddr = dev->base_addr;
+	int status = 0;
 
 	if(dev->tbusy) {
-		/*
-			 If we get here, some higher level has decided that we are broken.
-			 There should really be a "kick me" function call instead.
-		*/
+		
+		/* 
+		   If we get here, some higher level has decided that 
+		   we are broken. There should really be a "kick me" 
+		   function call instead. 
+		   */
 
 		int tickssofar = jiffies - dev->trans_start;
-		if(tickssofar < TIMEOUT_TICKS)	/* Let's not rush with our timeout, */
-			return 1;                     /* wait a couple of ticks first     */
+		if(tickssofar < TX_TIMEOUT)  
+			return 1;                     
 
-		printk("%s: transmit timed out with status %04x, %s ?\n", dev->name,
-		 inw(ioaddr + TX_STATUS_REG),
-		 (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
-		 "IRQ conflict" : "network cable problem");
+		outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
 
-		/* Let's dump all registers */
-		if(eth16i_debug > 0) {
-			printk("%s: timeout regs: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
-			 dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2),
-			 inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5),
-			 inb(ioaddr + 6), inb(ioaddr + 7));
+		printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n", 
+		       dev->name,
+		       inw(ioaddr + TX_STATUS_REG), 
+		       (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? 
+		       "IRQ conflict" : "network cable problem");
 
+		dev->trans_start = jiffies;
 
-			printk("lp->tx_queue = %d\n", lp->tx_queue);
-			printk("lp->tx_queue_len = %d\n", lp->tx_queue_len);
-			printk("lp->tx_started = %d\n", lp->tx_started);
+		/* Let's dump all registers */
+		if(eth16i_debug > 0) { 
+			printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
+			       dev->name, inb(ioaddr + 0), 
+			       inb(ioaddr + 1), inb(ioaddr + 2), 
+			       inb(ioaddr + 3), inb(ioaddr + 4), 
+			       inb(ioaddr + 5),
+			       inb(ioaddr + 6), inb(ioaddr + 7));
+
+			printk(KERN_DEBUG "%s: transmit start reg: %02x. collision reg %02x\n",
+			       dev->name, inb(ioaddr + TRANSMIT_START_REG),
+			       inb(ioaddr + COL_16_REG));
+
+			printk(KERN_DEBUG "lp->tx_queue = %d\n", lp->tx_queue);
+			printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len);
+			printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started);
 
 		}
 
 		lp->stats.tx_errors++;
 
-		/* Now let's try to restart the adaptor */
-
-		BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
-		outw(0xffff, ioaddr + RESET);
-		eth16i_initialize(dev);
-		outw(0xffff, ioaddr + TX_STATUS_REG);
-		BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
+		eth16i_reset(dev);
 
-		lp->tx_started = 0;
-		lp->tx_queue = 0;
-		lp->tx_queue_len = 0;
+		dev->trans_start = jiffies;
 
 		outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
 
-		dev->tbusy = 0;
-		dev->trans_start = jiffies;
 	}
 
-	/* Block a timer based transmitter from overlapping. This could better be
-		 done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+	/* 
+	   If some higher layer thinks we've missed an tx-done interrupt
+	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
+	   itself 
+	   */
+	
+	if(skb == NULL) {
+#if LINUX_VERSION_CODE < 0x020100
+		dev_tint(dev);
+#endif
+		if(eth16i_debug > 0) 
+			printk(KERN_WARNING "%s: Missed tx-done interrupt.\n", dev->name);
+		return 0;
+	}
+
+	/* Block a timer based transmitter from overlapping. 
+	   This could better be done with atomic_swap(1, dev->tbusy), 
+	   but set_bit() works as well. */
 
+	set_bit(0, (void *)&lp->tx_buf_busy);
+	
 	/* Turn off TX interrupts */
 	outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
 
-	if(test_and_set_bit(0, (void *)&dev->tbusy) != 0)
-		printk("%s: Transmitter access conflict.\n", dev->name);
+	if(test_and_set_bit(0, (void *)&dev->tbusy) != 0) {
+		printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
+		status = -1;
+	}
 	else {
-		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+		ushort length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 		unsigned char *buf = skb->data;
 
-		outw(length, ioaddr + DATAPORT);
-
-		if( ioaddr < 0x1000 )
-			outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
-		else 
-		{
-			unsigned char frag = length % 4;
-
-			outsl(ioaddr + DATAPORT, buf, length >> 2);
+		if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) {
+			if(eth16i_debug > 0) 
+				printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name);  
+		} 
+		else {
+			outw(length, ioaddr + DATAPORT);
 
-			if( frag != 0 ) 
-			{
-				outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
-				if( frag == 3 )
-					outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC) + 2), 1);
+			if( ioaddr < 0x1000 ) 
+				outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
+			else {
+				unsigned char frag = length % 4;
+
+				outsl(ioaddr + DATAPORT, buf, length >> 2);
+
+				if( frag != 0 ) {
+					outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
+					if( frag == 3 ) 
+						outsw(ioaddr + DATAPORT, 
+						      (buf + (length & 0xFFFC) + 2), 1);
+				}
 			}
-		}
 
-		lp->tx_queue++;
-		lp->tx_queue_len += length + 2;
+			lp->tx_buffered_packets++;
+			lp->tx_queue++;
+			lp->tx_queue_len += length + 2;
+			
+		}
+		
+		lp->tx_buf_busy = 0;
 
 		if(lp->tx_started == 0) {
 			/* If the transmitter is idle..always trigger a transmit */
@@ -971,15 +1168,21 @@
 			/* There is still more room for one more packet in tx buffer */
 			dev->tbusy = 0;
 		}
-
+		
 		outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
+		
 		/* Turn TX interrupts back on */
 		/* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
-	}
+		status = 0;
+	} 
+
+#if LINUX_VERSION_CODE >= 0x020100
 	dev_kfree_skb(skb);
+#else
+	dev_kfree_skb(skb, FREE_WRITE);
+#endif
 
-	return 0;
+	return status;
 }
 
 static void eth16i_rx(struct device *dev)
@@ -989,71 +1192,63 @@
 	int boguscount = MAX_RX_LOOP;
 
 	/* Loop until all packets have been read */
-	while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) 
-	{
-		/* Read status byte from receive buffer */
+	while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
+
+		/* Read status byte from receive buffer */ 
 		ushort status = inw(ioaddr + DATAPORT);
 
-		if(eth16i_debug > 4)
-			printk("%s: Receiving packet mode %02x status %04x.\n",
-				dev->name, inb(ioaddr + RECEIVE_MODE_REG), status);
+		/* Get the size of the packet from receive buffer */
+		ushort pkt_len = inw(ioaddr + DATAPORT);
 
-		if( !(status & PKT_GOOD) ) 
-		{
-			/* Hmm..something went wrong. Let's check what error occurred */
+		if(eth16i_debug > 4)
+			printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n", 
+			       dev->name, 
+			       inb(ioaddr + RECEIVE_MODE_REG), status);
+		
+		if( !(status & PKT_GOOD) ) {
 			lp->stats.rx_errors++;
-			if( status & PKT_SHORT)
+
+			if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) {
 				lp->stats.rx_length_errors++;
-			if( status & PKT_ALIGN_ERR )
-				lp->stats.rx_frame_errors++;
-			if( status & PKT_CRC_ERR )
-				lp->stats.rx_crc_errors++;
-			if( status & PKT_RX_BUF_OVERFLOW)
-				lp->stats.rx_over_errors++;
+				eth16i_reset(dev);
+				return;		
+			}
+			else { 
+				eth16i_skip_packet(dev);
+				lp->stats.rx_dropped++;
+			}	
 		}
-		else
-		{	 /* Ok so now we should have a good packet */
+		else {   /* Ok so now we should have a good packet */
 			struct sk_buff *skb;
-			/* Get the size of the packet from receive buffer */
-			ushort pkt_len = inw(ioaddr + DATAPORT);
-
-			if(pkt_len > ETH_FRAME_LEN) 
-			{
-				printk("%s: %s claimed a very large packet, size of %d bytes.\n",
-				dev->name, cardname, pkt_len);
-				outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
-				lp->stats.rx_dropped++;
-				break;
-			}
 
 			skb = dev_alloc_skb(pkt_len + 3);
-			if( skb == NULL ) 
-			{
-				printk("%s: Couldn't allocate memory for packet (len %d)\n",
-				dev->name, pkt_len);
-				outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
+			if( skb == NULL ) {
+				printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n", 
+				       dev->name, pkt_len);
+				eth16i_skip_packet(dev);
 				lp->stats.rx_dropped++;
 				break;
 			}
+
 			skb->dev = dev;
 			skb_reserve(skb,2);
-			/*
-				Now let's get the packet out of buffer.
-				size is (pkt_len + 1) >> 1, cause we are now reading words
-				and it has to be even aligned.
-			*/
-
-			if( ioaddr < 0x1000)
-				insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), (pkt_len + 1) >> 1);
-			else 
-			{
+			
+			/* 
+			   Now let's get the packet out of buffer.
+			   size is (pkt_len + 1) >> 1, cause we are now reading words
+			   and it have to be even aligned.
+			   */ 
+			
+			if(ioaddr < 0x1000) 
+				insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), 
+				     (pkt_len + 1) >> 1);
+			else {	
 				unsigned char *buf = skb_put(skb, pkt_len);
 				unsigned char frag = pkt_len % 4;
 
 				insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
 
-				if(frag != 0) 
-				{
+				if(frag != 0) {
 					unsigned short rest[2];
 					rest[0] = inw( ioaddr + DATAPORT );
 					if(frag == 3)
@@ -1067,13 +1262,13 @@
 			netif_rx(skb);
 			lp->stats.rx_packets++;
 
-			if( eth16i_debug > 5 ) 
-			{
+			if( eth16i_debug > 5 ) {
 				int i;
-				printk("%s: Received packet of length %d.\n", dev->name, pkt_len);
-				for(i = 0; i < 14; i++)
-					printk(" %02x", skb->data[i]);
-				printk(".\n");
+				printk(KERN_DEBUG "%s: Received packet of length %d.\n", 
+				       dev->name, pkt_len);
+				for(i = 0; i < 14; i++) 
+					printk(KERN_DEBUG " %02x", skb->data[i]);
+				printk(KERN_DEBUG ".\n");
 			}
 
 		} /* else */
@@ -1087,16 +1282,16 @@
 	{
 		int i;
 
-		for(i = 0; i < 20; i++) 
-		{
-			if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == RX_BUFFER_EMPTY)
+		for(i = 0; i < 20; i++) {
+			if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 
+			    RX_BUFFER_EMPTY)
 				break;
 			inw(ioaddr + DATAPORT);
-			outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
+			outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
 		}
 
 		if(eth16i_debug > 1)
-			printk("%s: Flushed receive buffer.\n", dev->name);
+			printk(KERN_DEBUG "%s: Flushed receive buffer.\n", dev->name);
 	}
 #endif
 
@@ -1108,126 +1303,302 @@
 	struct device *dev = dev_id;
 	struct eth16i_local *lp;
 	int ioaddr = 0,
-			status;
+		status;
 
 	if(dev == NULL) {
-		printk("eth16i_interrupt(): irq %d for unknown device. \n", irq);
+		printk(KERN_WARNING "eth16i_interrupt(): irq %d for unknown device. \n", irq);
 		return;
 	}
 
 	/* Turn off all interrupts from adapter */
 	outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
 
+	set_bit(0, (void *)&dev->tbusy);  	/* Set the device busy so that */
+	/* eth16i_tx wont be called */
+
+	if(dev->interrupt)
+		printk(KERN_WARNING "%s: Re-entering the interrupt handler.\n", dev->name);
 	dev->interrupt = 1;
 
 	ioaddr = dev->base_addr;
 	lp = (struct eth16i_local *)dev->priv;
-	status = inw(ioaddr + TX_STATUS_REG);			/* Get the status */
-	outw(status, ioaddr + TX_STATUS_REG);			/* Clear status bits */
+	status = inw(ioaddr + TX_STATUS_REG);      /* Get the status */
+	outw(status, ioaddr + TX_STATUS_REG);      /* Clear status bits */
 
 	if(eth16i_debug > 3)
-		printk("%s: Interrupt with status %04x.\n", dev->name, status);
+		printk(KERN_DEBUG "%s: Interrupt with status %04x.\n", dev->name, status);
+
+	if( status & 0x7f00 ) {
+
+		lp->stats.rx_errors++;
+
+		if(status & (BUS_RD_ERR << 8) ) 
+			printk(KERN_WARNING "%s: Bus read error.\n",dev->name);
+		if(status & (SHORT_PKT_ERR << 8) )   lp->stats.rx_length_errors++;
+		if(status & (ALIGN_ERR << 8) )       lp->stats.rx_frame_errors++;
+		if(status & (CRC_ERR << 8) )	    lp->stats.rx_crc_errors++;
+		if(status & (RX_BUF_OVERFLOW << 8) ) lp->stats.rx_over_errors++;
+	}
+	if( status & 0x001a) {
+
+		lp->stats.tx_errors++;
+
+		if(status & CR_LOST) lp->stats.tx_carrier_errors++;
+		if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++;
 
-	if( status & 0x00ff ) {			/* Let's check the transmit status reg */
-		if(status & TX_DONE) 
-		{	/* The transmit has been done */
-			lp->stats.tx_packets++; 
-			if(lp->tx_queue) 
-			{	/* Are there still packets ? */
+#if 0	       
+		if(status & COLLISION) {
+			lp->stats.collisions += 
+				((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4);
+		}
+#endif
+		if(status & COLLISIONS_16) {
+			if(lp->col_16 < MAX_COL_16) { 
+				lp->col_16++;
+				lp->stats.collisions++;
+				/* Resume transmitting, skip failed packet */
+				outb(0x02, ioaddr + COL_16_REG);
+			}
+			else {
+				printk(KERN_WARNING "%s: bailing out due to many consecutive 16-in-a-row collisions. Network cable problem?\n", dev->name);
+			}
+		}
+	}
+
+	if( status & 0x00ff ) {          /* Let's check the transmit status reg */
+
+		if(status & TX_DONE) {         /* The transmit has been done */
+			lp->stats.tx_packets = lp->tx_buffered_packets;
+			lp->col_16 = 0;		   
+
+			if(lp->tx_queue) {           /* Is there still packets ? */
 				/* There was packet(s) so start transmitting and write also
-				   how many packets there is to be sent */
+				   how many packets there is to be sended */
 				outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
 				lp->tx_queue = 0;
 				lp->tx_queue_len = 0;
+				lp->tx_started = 1;
 				dev->trans_start = jiffies;
-				dev->tbusy = 0;
-				mark_bh(NET_BH);
+				mark_bh(NET_BH); 
 			}
-			else 
-			{
+			else {
 				lp->tx_started = 0;
-				dev->tbusy = 0;
 				mark_bh(NET_BH);
 			}
 		}
 	}
 
-	if( ( status & 0xff00 ) ||
-		 ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
-		eth16i_rx(dev);	/* We have packet in receive buffer */
-	}
-
+	if( ( status & 0x8000 ) || 
+	    ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
+		eth16i_rx(dev);  /* We have packet in receive buffer */
+	}  
+	
 	dev->interrupt = 0;
-
+	
 	/* Turn interrupts back on */
 	outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
+	
+	if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
+		/* There is still more room for one more packet in tx buffer */
+		dev->tbusy = 0;
+	}
+	
 	return;
 }
 
-static void eth16i_multicast(struct device *dev)
+static void eth16i_skip_packet(struct device *dev)
+{	 
+	int ioaddr = dev->base_addr;
+
+	inw(ioaddr + DATAPORT);
+	inw(ioaddr + DATAPORT);
+	inw(ioaddr + DATAPORT);
+
+	outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
+	while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0);
+}
+
+static void eth16i_reset(struct device *dev)
 {
-	short ioaddr = dev->base_addr;
+	struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
+	int ioaddr = dev->base_addr;
+
+	if(eth16i_debug > 1) 
+		printk(KERN_DEBUG "%s: Resetting device.\n", dev->name);
+
+	BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
+	outw(0xffff, ioaddr + TX_STATUS_REG);    
+	eth16i_select_regbank(2, ioaddr);
+
+	lp->tx_started = 0;
+	lp->tx_buf_busy = 0;
+	lp->tx_queue = 0;
+	lp->tx_queue_len = 0;    
+
+	dev->interrupt = 0;
+	dev->start = 1;
+	dev->tbusy = 0;
+	BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
+}
 
-	if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
+static void eth16i_multicast(struct device *dev)
+{
+	int ioaddr = dev->base_addr;
+  
+	if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
 	{
 		dev->flags|=IFF_PROMISC;	/* Must do this */
-		outb(3, ioaddr + RECEIVE_MODE_REG);
+		outb(3, ioaddr + RECEIVE_MODE_REG);    
 	} else {
 		outb(2, ioaddr + RECEIVE_MODE_REG);
 	}
 }
 
-static struct net_device_stats *eth16i_get_stats(struct device *dev)
+static struct enet_statistics *eth16i_get_stats(struct device *dev)
 {
 	struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
 
 	return &lp->stats;
 }
 
-static void eth16i_select_regbank(unsigned char banknbr, short ioaddr)
+static void eth16i_select_regbank(unsigned char banknbr, int ioaddr)
 {
 	unsigned char data;
 
 	data = inb(ioaddr + CONFIG_REG_1);
-	outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
+	outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); 
 }
 
 #ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_eth16i = {
-	devicename,
-	0, 0, 0, 0,
-	0, 0,
-	0, 0, 0, NULL, eth16i_probe
+
+static ushort eth16i_parse_mediatype(const char* s)
+{
+	if(!s)
+		return E_PORT_FROM_EPROM;
+	
+        if (!strncmp(s, "bnc", 3))
+		return E_PORT_BNC;
+        else if (!strncmp(s, "tp", 2))
+                return E_PORT_TP;
+        else if (!strncmp(s, "dix", 3))
+                return E_PORT_DIX;
+        else if (!strncmp(s, "auto", 4))
+		return E_PORT_AUTO;
+	else
+		return E_PORT_FROM_EPROM;
+}
+
+#define MAX_ETH16I_CARDS 4  /* Max number of Eth16i cards per module */
+#define NAMELEN          8  /* number of chars for storing dev->name */
+
+static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, };
+static struct device dev_eth16i[MAX_ETH16I_CARDS] = {
+	{
+		NULL,
+		0, 0, 0, 0,
+		0, 0,
+		0, 0, 0, NULL, NULL
+	},
 };
 
-int io = 0x2a0;
-int irq = 0;
+static int ioaddr[MAX_ETH16I_CARDS] = { 0, };
+#if 0
+static int irq[MAX_ETH16I_CARDS] = { 0, };
+#endif
+static char* mediatype[MAX_ETH16I_CARDS] = { 0, };
+static int debug = -1;
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
+#if (LINUX_VERSION_CODE >= 0x20115) 
+MODULE_AUTHOR("Mika Kuoppala <miku@iki.fi>");
+MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver");
+
+MODULE_PARM(ioaddr, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
+MODULE_PARM_DESC(ioaddr, "eth16i io base address");
+
+#if 0
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
+MODULE_PARM_DESC(irq, "eth16i interrupt request number");
+#endif
+
+MODULE_PARM(mediatype, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "s");
+MODULE_PARM_DESC(mediatype, "eth16i interfaceport mediatype");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "eth16i debug level (0-4)");
+#endif
 
 int init_module(void)
 {
-	if(io == 0)
-		printk("eth16i: You should not use auto-probing with insmod!\n");
+	int this_dev, found = 0;
 
-	dev_eth16i.base_addr = io;
-	dev_eth16i.irq = irq;
-	if( register_netdev( &dev_eth16i ) != 0 ) {
-		printk("eth16i: register_netdev() returned non-zero.\n");
-		return -EIO;
-	}
+	for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
+	{
+		struct device *dev = &dev_eth16i[this_dev];
+	
+		dev->name = namelist + (NAMELEN*this_dev);
+		dev->irq = 0; /* irq[this_dev]; */
+		dev->base_addr = ioaddr[this_dev];
+		dev->init = eth16i_probe;
+
+	        if(debug != -1)
+			eth16i_debug = debug;
+
+		if(eth16i_debug > 1)
+			printk(KERN_NOTICE "eth16i(%d): interface type %s\n", this_dev, mediatype[this_dev] ? mediatype[this_dev] : "none" );
 
+		dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
+
+		if(ioaddr[this_dev] == 0)
+		{
+			if(this_dev != 0) break; /* Only autoprobe 1st one */
+
+			printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
+		}
+
+		if(register_netdev(dev) != 0)
+		{
+			printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
+			       ioaddr[this_dev]);
+	    
+			if(found != 0) return 0;
+			return -ENXIO;
+		}
+
+		found++;
+	}
 	return 0;
 }
-
+	
 void cleanup_module(void)
 {
-	unregister_netdev( &dev_eth16i );
-	free_irq( dev_eth16i.irq, &dev_eth16i );
-	release_region( dev_eth16i.base_addr, ETH16I_IO_EXTENT );
-}
+	int this_dev;
 
+	for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
+	{
+		struct device* dev = &dev_eth16i[this_dev];
+		
+		if(dev->priv != NULL)
+		{
+			unregister_netdev(dev);
+			kfree(dev->priv);
+			dev->priv = NULL;
+			
+			free_irq(dev->irq, dev);
+			release_region(dev->base_addr, ETH16I_IO_EXTENT);
+			
+		}
+	}
+}
 #endif /* MODULE */
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eth16i.c"
+ *  alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict -prototypes -O6 -c eth16i.c"
+ *  tab-width: 8
+ *  c-basic-offset: 8
+ *  c-indent-level: 8
+ * End:
+ */
+
+/* End of file eth16i.c */
diff -u --recursive --new-file v2.1.125/linux/drivers/net/ethertap.c linux/drivers/net/ethertap.c
--- v2.1.125/linux/drivers/net/ethertap.c	Fri Oct  9 13:27:09 1998
+++ linux/drivers/net/ethertap.c	Fri Oct 23 08:12:32 1998
@@ -329,7 +329,7 @@
 
 #ifdef MODULE
 
-int unit;
+static int unit;
 MODULE_PARM(unit,"i");
 
 static char devicename[9] = { 0, };
diff -u --recursive --new-file v2.1.125/linux/drivers/net/hamradio/baycom_epp.c linux/drivers/net/hamradio/baycom_epp.c
--- v2.1.125/linux/drivers/net/hamradio/baycom_epp.c	Tue Jul 21 00:15:31 1998
+++ linux/drivers/net/hamradio/baycom_epp.c	Fri Oct  9 12:20:27 1998
@@ -1010,14 +1010,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static int epp_preempt(void *handle)
-{
-        /* we cannot relinquish the port in the middle of an operation */
-        return 1;
-}
-
-/* --------------------------------------------------------------------- */
-
 static void epp_wakeup(void *handle)
 {
         struct device *dev = (struct device *)handle;
@@ -1070,8 +1062,8 @@
         }
 #endif
 	memset(&bc->modem, 0, sizeof(bc->modem));
-        if (!(bc->pdev = parport_register_device(pp, dev->name, epp_preempt, epp_wakeup, 
-                                                 epp_interrupt, PARPORT_DEV_LURK, dev))) {
+        if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup, 
+                                                 epp_interrupt, PARPORT_DEV_EXCL, dev))) {
                 printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);
                 return -ENXIO;
         }
diff -u --recursive --new-file v2.1.125/linux/drivers/net/hamradio/baycom_par.c linux/drivers/net/hamradio/baycom_par.c
--- v2.1.125/linux/drivers/net/hamradio/baycom_par.c	Tue Jun  9 11:57:29 1998
+++ linux/drivers/net/hamradio/baycom_par.c	Fri Oct  9 12:20:27 1998
@@ -357,14 +357,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static int par96_preempt(void *handle)
-{
-	/* we cannot relinquish the port in the middle of an operation */
-	return 1;
-}
-
-/* --------------------------------------------------------------------- */
-
 static void par96_wakeup(void *handle)
 {
         struct device *dev = (struct device *)handle;
@@ -396,8 +388,8 @@
 	}
 	memset(&bc->modem, 0, sizeof(bc->modem));
 	bc->hdrv.par.bitrate = 9600;
-	if (!(bc->pdev = parport_register_device(pp, dev->name, par96_preempt, par96_wakeup, 
-						 par96_interrupt, PARPORT_DEV_LURK, dev))) {
+	if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup, 
+						 par96_interrupt, PARPORT_DEV_EXCL, dev))) {
 		printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", pp->base);
 		return -ENXIO;
 	}
diff -u --recursive --new-file v2.1.125/linux/drivers/net/hamradio/dmascc.c linux/drivers/net/hamradio/dmascc.c
--- v2.1.125/linux/drivers/net/hamradio/dmascc.c	Thu Sep 17 17:53:36 1998
+++ linux/drivers/net/hamradio/dmascc.c	Fri Oct  9 11:56:59 1998
@@ -966,6 +966,7 @@
 {
   struct scc_priv *priv = dev->priv;
   int cb, cmd = priv->cmd;
+  unsigned long flags;
 
   /* See Figure 2-15. Only overrun and EOF need to be checked. */
   
@@ -976,9 +977,12 @@
   } else if (rc & END_FR) {
     /* End of frame. Get byte count */
     if (dev->dma) {
+        flags=claim_dma_lock();
 	disable_dma(dev->dma);
 	clear_dma_ff(dev->dma);
 	cb = BUF_SIZE - get_dma_residue(dev->dma) - 2;
+	release_dma_lock(flags);
+	
     } else {
 	cb = priv->rx_ptr - 2;
     }
@@ -1013,9 +1017,13 @@
     }
     /* Get ready for new frame */
     if (dev->dma) {
+      
+      flags=claim_dma_lock();
       set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]);
       set_dma_count(dev->dma, BUF_SIZE);
       enable_dma(dev->dma);
+      release_dma_lock(flags);
+      
     } else {
       priv->rx_ptr = 0;
     }
@@ -1102,6 +1110,7 @@
   struct scc_info *info = priv->info;
   int i, cmd = priv->cmd;
   int st, dst, res;
+  unsigned long flags;
 
   /* Read status and reset interrupt bit */
   st = read_scc(cmd, R0);
@@ -1118,9 +1127,11 @@
     /* Get remaining bytes */
     i = priv->tx_tail;
     if (dev->dma) {
+      flags=claim_dma_lock();
       disable_dma(dev->dma);
       clear_dma_ff(dev->dma);
       res = get_dma_residue(dev->dma);
+      release_dma_lock(flags);
     } else {
       res = priv->tx_len[i] - priv->tx_ptr;
       if (res) write_scc(cmd, R0, RES_Tx_P);
@@ -1133,9 +1144,11 @@
     /* Check if another frame is available and we are allowed to transmit */
     if (priv->tx_count && (jiffies - priv->tx_start) < priv->param.txtime) {
       if (dev->dma) {
+        flags=claim_dma_lock();
 	set_dma_addr(dev->dma, (int) priv->tx_buf[priv->tx_tail]);
 	set_dma_count(dev->dma, priv->tx_len[priv->tx_tail]);
 	enable_dma(dev->dma);
+	release_dma_lock(flags);
       } else {
 	/* If we have an ESCC, we are allowed to write data bytes
 	   immediately. Otherwise we have to wait for the next
@@ -1170,12 +1183,14 @@
     if (st & DCD) {
       if (dev->dma) {
 	/* Program DMA controller */
+	flags=claim_dma_lock();
 	disable_dma(dev->dma);
 	clear_dma_ff(dev->dma);
 	set_dma_mode(dev->dma, DMA_MODE_READ);
 	set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]);
 	set_dma_count(dev->dma, BUF_SIZE);
 	enable_dma(dev->dma);
+	release_dma_lock(flags);
 	/* Configure PackeTwin DMA */
 	if (info->type == TYPE_TWIN) {
 	  outb_p((dev->dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3,
@@ -1195,7 +1210,12 @@
       }
     } else {
       /* Disable DMA */
-      if (dev->dma) disable_dma(dev->dma);
+      if (dev->dma)
+      {
+      	flags=claim_dma_lock();
+      	disable_dma(dev->dma);
+      	release_dma_lock(flags);
+      }
       /* Disable receiver */
       write_scc(cmd, R3, Rx8);
       /* DMA disable, RX int disable, Ext int enable */
@@ -1228,11 +1248,13 @@
     while (read_scc(cmd, R0) & Rx_CH_AV) read_scc(cmd, R8);
     priv->rx_over = 0;
     if (dev->dma) {
+      flags=claim_dma_lock();
       disable_dma(dev->dma);
       clear_dma_ff(dev->dma);
       set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]);
       set_dma_count(dev->dma, BUF_SIZE);
       enable_dma(dev->dma);
+      release_dma_lock(flags);
     } else {
       priv->rx_ptr = 0;
     }
@@ -1245,6 +1267,7 @@
   struct scc_priv *priv = dev->priv;
   struct scc_info *info = priv->info;
   int cmd = priv->cmd;
+  unsigned long flags;
 
   switch (priv->tx_state) {
   case TX_OFF:
@@ -1266,12 +1289,16 @@
     priv->tx_state = TX_ACTIVE;
     if (dev->dma) {
       /* Program DMA controller */
+      
+      flags=claim_dma_lock();
       disable_dma(dev->dma);
       clear_dma_ff(dev->dma);
       set_dma_mode(dev->dma, DMA_MODE_WRITE);
       set_dma_addr(dev->dma, (int) priv->tx_buf[priv->tx_tail]);
       set_dma_count(dev->dma, priv->tx_len[priv->tx_tail]);
       enable_dma(dev->dma);
+      release_dma_lock(flags);
+      
       /* Configure PackeTwin DMA */
       if (info->type == TYPE_TWIN) {
 	outb_p((dev->dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3,
diff -u --recursive --new-file v2.1.125/linux/drivers/net/hostess_sv11.c linux/drivers/net/hostess_sv11.c
--- v2.1.125/linux/drivers/net/hostess_sv11.c	Wed Sep  9 14:51:08 1998
+++ linux/drivers/net/hostess_sv11.c	Fri Oct 16 23:30:21 1998
@@ -1,3 +1,5 @@
+#define LINUX_21
+
 /*
  *	Comtrol SV11 card driver
  *
@@ -7,7 +9,7 @@
  *	Its a genuine Z85230
  *
  *	It supports DMA using two DMA channels in SYNC mode. The driver doesn't
- *	use these facilities (yet).
+ *	use these facilities
  *	
  *	The control port is at io+1, the data at io+3 and turning off the DMA
  *	is done by writing 0 to io+4
@@ -50,7 +52,7 @@
 
 /*
  *	Frame receive. Simple for our card as we do sync ppp and there
- *	is no funny garbage involved. This is very timing sensitive.
+ *	is no funny garbage involved
  */
  
 static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
@@ -58,13 +60,12 @@
 	/* Drop the CRC - its not a good idea to try and negotiate it ;) */
 	skb_trim(skb, skb->len-2);
 	skb->protocol=htons(ETH_P_WAN_PPP);
+	skb->mac.raw=skb->data;
 	skb->dev=c->netdevice;
 	/*
 	 *	Send it to the PPP layer. We dont have time to process
 	 *	it right now.
 	 */
-	skb->mac.raw = skb->data;
-	
 	netif_rx(skb);
 }
  
@@ -75,15 +76,24 @@
 static int hostess_open(struct device *d)
 {
 	struct sv11_device *sv11=d->priv;
-	int err;
+	int err = -1;
 	
 	/*
 	 *	Link layer up
 	 */
-	if(dma)
-		err=z8530_sync_dma_open(d, &sv11->sync.chanA);
-	else
-		err=z8530_sync_open(d, &sv11->sync.chanA);
+	switch(dma)
+	{
+		case 0:
+			err=z8530_sync_open(d, &sv11->sync.chanA);
+			break;
+		case 1:
+			err=z8530_sync_dma_open(d, &sv11->sync.chanA);
+			break;
+		case 2:
+			err=z8530_sync_txdma_open(d, &sv11->sync.chanA);
+			break;
+	}
+	
 	if(err)
 		return err;
 	/*
@@ -92,10 +102,18 @@
 	err=sppp_open(d);
 	if(err)
 	{
-		if(dma)
-			z8530_sync_dma_close(d, &sv11->sync.chanA);
-		else
-			z8530_sync_close(d, &sv11->sync.chanA);
+		switch(dma)
+		{
+			case 0:
+				z8530_sync_close(d, &sv11->sync.chanA);
+				break;
+			case 1:
+				z8530_sync_dma_close(d, &sv11->sync.chanA);
+				break;
+			case 2:
+				z8530_sync_txdma_close(d, &sv11->sync.chanA);
+				break;
+		}				
 		return err;
 	}
 	sv11->sync.chanA.rx_function=hostess_input;
@@ -123,10 +141,19 @@
 	 *	Link layer down
 	 */
 	d->tbusy=1;
-	if(dma)
-		z8530_sync_dma_close(d, &sv11->sync.chanA);
-	else
-		z8530_sync_close(d, &sv11->sync.chanA);
+	
+	switch(dma)
+	{
+		case 0:
+			z8530_sync_close(d, &sv11->sync.chanA);
+			break;
+		case 1:
+			z8530_sync_dma_close(d, &sv11->sync.chanA);
+			break;
+		case 2:
+			z8530_sync_txdma_close(d, &sv11->sync.chanA);
+			break;
+	}
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
@@ -135,10 +162,10 @@
 {
 	struct sv11_device *sv11=d->priv;
 	/* z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
-	return sppp_do_ioctl(d, ifr, cmd);
+	return sppp_do_ioctl(d, ifr,cmd);
 }
 
-static struct net_device_stats *hostess_get_stats(struct device *d)
+static struct enet_statistics *hostess_get_stats(struct device *d)
 {
 	struct sv11_device *sv11=d->priv;
 	if(sv11)
@@ -157,6 +184,7 @@
 	return z8530_queue_xmit(&sv11->sync.chanA, skb);
 }
 
+#ifdef LINUX_21
 static int hostess_neigh_setup(struct neighbour *n)
 {
 	if (n->nud_state == NUD_NONE) {
@@ -176,6 +204,15 @@
 	return 0;
 }
 
+#else
+
+static int return_0(struct device *d)
+{
+	return 0;
+}
+
+#endif
+
 /*
  *	Description block for a Comtrol Hostess SV11 card
  */
@@ -243,13 +280,17 @@
 		 *	You can have DMA off or 1 and 3 thats the lot
 		 *	on the Comtrol.
 		 */
-		dev->chanA.txdma=1;
-		dev->chanA.rxdma=3;
-		outb(14, iobase+4);		/* DMA on */
+		dev->chanA.txdma=3;
+		dev->chanA.rxdma=1;
+		outb(0x03|0x08, iobase+4);		/* DMA on */
 		if(request_dma(dev->chanA.txdma, "Hostess SV/11 (TX)")!=0)
 			goto fail;
-		if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0)
-			goto dmafail;
+			
+		if(dma==1)
+		{
+			if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0)
+				goto dmafail;
+		}
 	}
 	save_flags(flags);
 	cli();
@@ -259,7 +300,10 @@
 	 */
 	 
 	if(z8530_init(dev)!=0)
+	{
+		printk(KERN_ERR "Z8530 series device not found.\n");
 		goto dmafail2;
+	}
 	z8530_channel_load(&dev->chanB, z8530_dead_port);
 	if(dev->type==Z85C30)
 		z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
@@ -269,8 +313,6 @@
 	restore_flags(flags);
 
 
-	printk(KERN_INFO "begin loading hdlc\n");
-	
 	/*
 	 *	Now we can take the IRQ
 	 */
@@ -291,7 +333,6 @@
 			 *	Local fields
 			 */	
 			sprintf(sv->name,"hdlc%d", i);
-			printk("Filling in device '%s' at %p\n", sv->name, d);
 			
 			d->name = sv->name;
 			d->base_addr = iobase;
@@ -305,8 +346,12 @@
 			d->get_stats = hostess_get_stats;
 			d->set_multicast_list = NULL;
 			d->do_ioctl = hostess_ioctl;
+#ifdef LINUX_21			
 			d->neigh_setup = hostess_neigh_setup_dev;
 			dev_init_buffers(d);
+#else
+			d->init = return_0;
+#endif
 			d->set_mac_address = NULL;
 			
 			if(register_netdev(d)==-1)
@@ -322,11 +367,11 @@
 		}
 	}
 dmafail2:
-	if(!dma)
-		goto fail;
-	free_dma(dev->chanA.rxdma);
+	if(dma==1)
+		free_dma(dev->chanA.rxdma);
 dmafail:
-	free_dma(dev->chanA.txdma);
+	if(dma)
+		free_dma(dev->chanA.txdma);
 fail:
 	free_irq(irq, dev);
 fail2:
@@ -342,8 +387,11 @@
 	z8530_shutdown(&dev->sync);
 	unregister_netdev(&dev->netdev.dev);
 	free_irq(dev->sync.irq, dev);
-	free_dma(dev->sync.chanA.rxdma);
-	free_dma(dev->sync.chanA.txdma);
+	if(dma)
+	{
+		free_dma(dev->sync.chanA.rxdma);
+		free_dma(dev->sync.chanA.txdma);
+	}
 	release_region(dev->sync.chanA.ctrlio-1, 8);
 }
 
@@ -352,6 +400,7 @@
 static int io=0x200;
 static int irq=9;
 
+#ifdef LINUX_21
 MODULE_PARM(io,"i");
 MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
 MODULE_PARM(dma,"i");
@@ -361,12 +410,13 @@
 
 MODULE_AUTHOR("Bulding Number Three Ltd");
 MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
+#endif
 
 static struct sv11_device *sv11_unit;
 
 int init_module(void)
 {
-	printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n");
+	printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.01.\n");
 	printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");	
 	if(dma)
 		printk(KERN_WARNING "DMA mode probably wont work right now.\n");
diff -u --recursive --new-file v2.1.125/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v2.1.125/linux/drivers/net/lance.c	Tue Jul 28 14:21:08 1998
+++ linux/drivers/net/lance.c	Fri Oct  9 11:56:59 1998
@@ -377,6 +377,7 @@
 	unsigned char hpJ2405A = 0;			/* HP ISA adaptor */
 	int hp_builtin = 0;					/* HP on-board ethernet. */
 	static int did_version = 0;			/* Already printed version info. */
+	unsigned long flags;
 
 	/* First we look for special cases.
 	   Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
@@ -563,8 +564,11 @@
 			outw(0x7f04, ioaddr+LANCE_DATA); /* Clear the memory error bits. */
 			if (request_dma(dma, chipname))
 				continue;
+				
+			flags=claim_dma_lock();
 			set_dma_mode(dma, DMA_MODE_CASCADE);
 			enable_dma(dma);
+			release_dma_lock(flags);
 
 			/* Trigger an initialization. */
 			outw(0x0001, ioaddr+LANCE_DATA);
@@ -576,7 +580,9 @@
 				printk(", DMA %d.\n", dev->dma);
 				break;
 			} else {
+				flags=claim_dma_lock();
 				disable_dma(dma);
+				release_dma_lock(flags);
 				free_dma(dma);
 			}
 		}
@@ -649,8 +655,10 @@
 
 	/* The DMA controller is used as a no-operation slave, "cascade mode". */
 	if (dev->dma != 4) {
+		unsigned long flags=claim_dma_lock();
 		enable_dma(dev->dma);
 		set_dma_mode(dev->dma, DMA_MODE_CASCADE);
+		release_dma_lock(flags);
 	}
 
 	/* Un-Reset the LANCE, needed only for the NE2100. */
@@ -1121,7 +1129,11 @@
 	outw(0x0004, ioaddr+LANCE_DATA);
 
 	if (dev->dma != 4)
+	{
+		unsigned long flags=claim_dma_lock();
 		disable_dma(dev->dma);
+		release_dma_lock(flags);
+	}
 
 	free_irq(dev->irq, dev);
 
diff -u --recursive --new-file v2.1.125/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c
--- v2.1.125/linux/drivers/net/ltpc.c	Mon Feb 23 18:12:05 1998
+++ linux/drivers/net/ltpc.c	Fri Oct  9 11:56:59 1998
@@ -352,13 +352,17 @@
 	/* called *only* from idle, non-reentrant */
 	int dma = dev->dma;
 	int base = dev->base_addr;
+	unsigned long flags;
+
 
+	flags=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 	set_dma_mode(dma,DMA_MODE_READ);
 	set_dma_addr(dma,virt_to_bus(ltdmacbuf));
 	set_dma_count(dma,50);
 	enable_dma(dma);
+	release_dma_lock(flags);
 
 	inb_p(base+3);
 	inb_p(base+2);
@@ -370,13 +374,16 @@
 {
 	int dma = dev->dma;
 	int base = dev->base_addr;
+	unsigned long flags;
 
+	flags=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 	set_dma_mode(dma,DMA_MODE_READ);
 	set_dma_addr(dma,virt_to_bus(ltdmabuf));
 	set_dma_count(dma,800);
 	enable_dma(dma);
+	release_dma_lock(flags);
 
 	inb_p(base+3);
 	inb_p(base+2);
@@ -391,21 +398,25 @@
 	/* on entry, 0xfb and ltdmabuf holds data */
 	int dma = dev->dma;
 	int base = dev->base_addr;
-
-
+	unsigned long flags;
+	
+	flags=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 	set_dma_mode(dma,DMA_MODE_WRITE);
 	set_dma_addr(dma,virt_to_bus(ltdmabuf));
 	set_dma_count(dma,800);
 	enable_dma(dma);
-
+	release_dma_lock(flags);
+	
 	inb_p(base+3);
 	inb_p(base+2);
 
 	if ( wait_timeout(dev,0xfb) ) {
+		flags=claim_dma_lock();
 		printk("timed out in handlewrite, dma res %d\n",
 			get_dma_residue(dev->dma) );
+		release_dma_lock(flags);
 	}
 }
 
@@ -415,15 +426,17 @@
 	/* on exit, ltdmabuf holds data */
 	int dma = dev->dma;
 	int base = dev->base_addr;
+	unsigned long flags;
 
-
-
+	
+	flags=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 	set_dma_mode(dma,DMA_MODE_READ);
 	set_dma_addr(dma,virt_to_bus(ltdmabuf));
 	set_dma_count(dma,800);
 	enable_dma(dma);
+	release_dma_lock(flags);
 
 	inb_p(base+3);
 	inb_p(base+2);
@@ -435,14 +448,16 @@
 	/* on entry, 0xfa and ltdmacbuf holds command */
 	int dma = dev->dma;
 	int base = dev->base_addr;
+	unsigned long flags;
 
+	flags=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 	set_dma_mode(dma,DMA_MODE_WRITE);
 	set_dma_addr(dma,virt_to_bus(ltdmacbuf));
 	set_dma_count(dma,50);
 	enable_dma(dma);
-
+	release_dma_lock(flags);
 	inb_p(base+3);
 	inb_p(base+2);
 	if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n");
@@ -978,6 +993,7 @@
 	int probe3, probe4, probe9;
 	unsigned short straymask;
 	unsigned long flags;
+	unsigned long f;
 
 	err = ltpc_init(dev);
 	if (err) return err;
@@ -1089,6 +1105,7 @@
 	inb_p(base+6); /* tri-state interrupt line */
 
 	timeout = jiffies+100;
+	
 	while(timeout>jiffies) {
 		/* wait for the card to complete initialization */
 	}
@@ -1098,21 +1115,26 @@
 	/* set up both dma 1 and 3 for read call */
 
 	if (!request_dma(1,"ltpc")) {
+	
+		f=claim_dma_lock();
 		disable_dma(1);
 		clear_dma_ff(1);
 		set_dma_mode(1,DMA_MODE_WRITE);
 		set_dma_addr(1,virt_to_bus(ltdmabuf));
 		set_dma_count(1,sizeof(struct lt_mem));
 		enable_dma(1);
+		release_dma_lock(f);
 		dma|=1;
 	}
 	if (!request_dma(3,"ltpc")) {
+		f=claim_dma_lock();
 		disable_dma(3);
 		clear_dma_ff(3);
 		set_dma_mode(3,DMA_MODE_WRITE);
 		set_dma_addr(3,virt_to_bus(ltdmabuf));
 		set_dma_count(3,sizeof(struct lt_mem));
 		enable_dma(3);
+		release_dma_lock(f);
 		dma|=2;
 	}
 
@@ -1174,13 +1196,15 @@
 	if(debug&DEBUG_VERBOSE) {
 		printk("finishing up transfer\n");
 	}
-
+	
+	f=claim_dma_lock();
 	disable_dma(dma);
 	clear_dma_ff(dma);
 	set_dma_mode(dma,DMA_MODE_READ);
 	set_dma_addr(dma,virt_to_bus(ltdmabuf));
 	set_dma_count(dma,0x100);
 	enable_dma(dma);
+	release_dma_lock(f);
 
 	(void) inb_p(base+3);
 	(void) inb_p(base+2);
diff -u --recursive --new-file v2.1.125/linux/drivers/net/ne2.c linux/drivers/net/ne2.c
--- v2.1.125/linux/drivers/net/ne2.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/ne2.c	Sat Oct 17 15:33:45 1998
@@ -0,0 +1,698 @@
+/* ne2.c: A NE/2 Ethernet Driver for Linux. */
+/*
+   Based on the NE2000 driver written by Donald Becker (1992-94).
+   modified by Wim Dumon (Apr 1996)
+
+   This software may be used and distributed according to the terms
+   of the GNU Public License, incorporated herein by reference.
+
+   The author may be reached as wimpie@linux.cc.kuleuven.ac.be
+
+   Currently supported: NE/2
+   This patch was never tested on other MCA-ethernet adapters, but it
+   might work. Just give it a try and let me know if you have problems.
+   Also mail me if it really works, please!
+
+   Changelog:
+   Mon Feb  3 16:26:02 MET 1997
+   - adapted the driver to work with the 2.1.25 kernel
+   - multiple ne2 support (untested)
+   - module support (untested)
+
+   Fri Aug 28 00:18:36 CET 1998 (David Weinehall)
+   - fixed a few minor typos
+   - made the MODULE_PARM conditional (it only works with the v2.1.x kernels)
+   - fixed the module support (Now it's working...)
+
+   Mon Sep  7 19:01:44 CET 1998 (David Weinehall)
+   - added support for Arco Electronics AE/2-card (experimental)
+
+   Mon Sep 14 09:53:42 CET 1998 (David Weinehall)
+   - added support for Compex ENET-16MC/P (experimental) 
+
+   Tue Sep 15 16:21:12 CET 1998 (David Weinehall, Magnus Jonsson, Tomas Ogren)
+   - Miscellaneous bugfixes
+
+   Tue Sep 19 16:21:12 CET 1998 (Magnus Jonsson)
+   - Cleanup
+
+   Wed Sep 23 14:33:34 CET 1998 (David Weinehall)
+   - Restructuring and rewriting for v2.1.x compliance
+
+   Wed Oct 14 17:19:21 CET 1998 (David Weinehall)
+   - Added code that unregisters irq and proc-info
+   - Version# bump
+
+   *    WARNING
+	-------
+	This is alpha-test software.  It is not guaranteed to work. As a
+	matter of fact, I'm quite sure there are *LOTS* of bugs in here. I
+	would like to hear from you if you use this driver, even if it works.
+	If it doesn't work, be sure to send me a mail with the problems !
+*/
+
+static const char *version =
+"ne2.c:v0.90 Oct 14 1998 David Weinehall <tao@acc.umu.se>\n";
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/mca.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include "8390.h"
+
+
+
+/* Some defines that people can play with if so inclined. */
+
+/* Do we perform extra sanity checks on stuff ? */
+/* #define NE_SANITY_CHECK */
+
+/* Do we implement the read before write bugfix ? */
+/* #define NE_RW_BUGFIX */
+
+/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
+/* #define PACKETBUF_MEMSIZE	0x40 */
+
+
+/* ---- No user-serviceable parts below ---- */
+
+#define NE_BASE	 (dev->base_addr)
+#define NE_CMD	 	0x00
+#define NE_DATAPORT	0x10	/* NatSemi-defined port window offset. */
+#define NE_RESET	0x20	/* Issue a read to reset, a write to clear. */
+#define NE_IO_EXTENT	0x30
+
+#define NE1SM_START_PG	0x20	/* First page of TX buffer */
+#define NE1SM_STOP_PG 	0x40	/* Last page +1 of RX ring */
+#define NESM_START_PG	0x40	/* First page of TX buffer */
+#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
+
+/* From the .ADF file: */
+static unsigned int addresses[7]=
+		{0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0};
+static int irqs[4] = {3, 4, 5, 9};
+
+struct ne2_adapters_t {
+	unsigned int	id;
+	char		*name;
+};
+
+const struct ne2_adapters_t ne2_adapters[] = {
+	{ 0x6354, "Arco Ethernet Adapter AE/2" },
+	{ 0x70DE, "Compex ENET-16 MC/P" },
+	{ 0x7154, "Novell Ethernet Adapter NE/2" },
+	{ 0x0000, NULL }
+};
+
+extern int netcard_probe(struct device *dev);
+
+static int ne2_probe1(struct device *dev, int slot);
+
+static int ne_open(struct device *dev);
+static int ne_close(struct device *dev);
+
+static void ne_reset_8390(struct device *dev);
+static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
+		int ring_page);
+static void ne_block_input(struct device *dev, int count,
+		struct sk_buff *skb, int ring_offset);
+static void ne_block_output(struct device *dev, const int count,
+		const unsigned char *buf, const int start_page);
+
+
+/*
+ * Note that at boot, this probe only picks up one card at a time.
+ */
+
+__initfunc (int ne2_probe(struct device *dev))
+{
+	static int current_mca_slot = -1;
+	int i;
+	int adapter_found = 0;
+
+	/* Do not check any supplied i/o locations. 
+	   POS registers usually don't fail :) */
+
+	/* MCA cards have POS registers.  
+	   Autodetecting MCA cards is extremely simple. 
+	   Just search for the card. */
+
+	for(i = 0; (ne2_adapters[i].name != NULL) && !adapter_found; i++) {
+		current_mca_slot = 
+			mca_find_unused_adapter(ne2_adapters[i].id, 0);
+
+		if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) {
+			mca_set_adapter_name(current_mca_slot, 
+					ne2_adapters[i].name);
+			mca_mark_as_used(current_mca_slot);
+			
+			return ne2_probe1(dev, current_mca_slot);
+		}
+	}
+	return ENODEV;
+}
+
+
+static int ne2_procinfo(char *buf, int slot, struct device *dev)
+{
+	int len=0;
+
+	len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" );
+	len += sprintf(buf+len, "Driver written by Wim Dumon ");
+	len += sprintf(buf+len, "<wimpie@kotnet.org>\n"); 
+	len += sprintf(buf+len, "Modified by ");
+	len += sprintf(buf+len, "David Weinehall <tao@acc.umu.se>\n");
+	len += sprintf(buf+len, "and by Magnus Jonsson <bigfoot@acc.umu.se>\n");
+	len += sprintf(buf+len, "Based on the original NE2000 drivers\n" );
+	len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr);
+	len += sprintf(buf+len, "IRQ    : %d\n", dev->irq);
+
+#define HW_ADDR(i) dev->dev_addr[i]
+	len += sprintf(buf+len, "HW addr : %x:%x:%x:%x:%x:%x\n", 
+			HW_ADDR(0), HW_ADDR(1), HW_ADDR(2), 
+			HW_ADDR(3), HW_ADDR(4), HW_ADDR(5) );
+#undef HW_ADDR
+
+	return len;
+}
+
+
+__initfunc (static int ne2_probe1(struct device *dev, int slot))
+{
+	int i, base_addr, irq;
+	unsigned char POS;
+	unsigned char SA_prom[32];
+	const char *name = "NE/2";
+	int start_page, stop_page;
+	static unsigned version_printed = 0;
+
+	/* We should have a "dev" from Space.c or the static module table. */
+	if (dev == NULL) {
+		printk(KERN_ERR "ne2.c: Passed a NULL device.\n");
+		dev = init_etherdev(0, 0);
+	}
+
+	if (ei_debug && version_printed++ == 0)
+		printk(version);
+
+	printk("NE/2 ethercard found in slot %d:", slot);
+
+	/* Read base IO and IRQ from the POS-registers */
+	POS = mca_read_stored_pos(slot, 2);
+	if(!(POS % 2)) {
+		printk(" disabled.\n");
+		return ENODEV;
+	}
+
+	i = (POS & 0xE)>>1;
+	/* printk("Halleluja sdog, als er na de pijl een 1 staat is 1 - 1 == 0"
+	   " en zou het moeten werken -> %d\n", i);
+	   The above line was for remote testing, thanx to sdog ... */
+	base_addr = addresses[i - 1];
+	irq = irqs[(POS & 0x60)>>5];
+
+#ifdef DEBUG
+	printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS,
+			base_addr, irq);
+#endif
+
+#ifndef CRYNWR_WAY
+	/* Reset the card the way they do it in the Crynwr packet driver */
+	for (i=0; i<8; i++) 
+		outb(0x0, base_addr + NE_RESET);
+	inb(base_addr + NE_RESET);
+	outb(0x21, base_addr + NE_CMD);
+	if (inb(base_addr + NE_CMD) != 0x21) {
+		printk("NE/2 adapter not responding\n");
+		return ENODEV;
+	}
+
+	/* In the crynwr sources they do a RAM-test here. I skip it. I suppose
+	   my RAM is okay.  Suppose your memory is broken.  Then this test
+	   should fail and you won't be able to use your card.  But if I do not
+	   test, you won't be able to use your card, neither.  So this test
+	   won't help you. */
+
+#else  /* _I_ never tested it this way .. Go ahead and try ...*/
+	/* Reset card. Who knows what dain-bramaged state it was left in. */
+	{ 
+		unsigned long reset_start_time = jiffies;
+
+		/* DON'T change these to inb_p/outb_p or reset will fail on 
+		   clones.. */
+		outb(inb(base_addr + NE_RESET), base_addr + NE_RESET);
+
+		while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0)
+			if (jiffies - reset_start_time > 2*HZ/100) {
+				printk(" not found (no reset ack).\n");
+				return ENODEV;
+			}
+
+		outb_p(0xff, base_addr + EN0_ISR);         /* Ack all intr. */
+	}
+#endif
+
+
+	/* Read the 16 bytes of station address PROM.
+	   We must first initialize registers, similar to 
+	   NS8390_init(eifdev, 0).
+	   We can't reliably read the SAPROM address without this.
+	   (I learned the hard way!). */
+	{
+		struct { 
+			unsigned char value, offset; 
+		} program_seq[] = {
+						/* Select page 0 */
+			{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, 
+			{0x49,	EN0_DCFG},  /* Set WORD-wide (0x49) access. */
+			{0x00,	EN0_RCNTLO},  /* Clear the count regs. */
+			{0x00,	EN0_RCNTHI},
+			{0x00,	EN0_IMR},  /* Mask completion irq. */
+			{0xFF,	EN0_ISR},
+			{E8390_RXOFF, EN0_RXCR},  /* 0x20  Set to monitor */
+			{E8390_TXOFF, EN0_TXCR},  /* 0x02  and loopback mode. */
+			{32,	EN0_RCNTLO},
+			{0x00,	EN0_RCNTHI},
+			{0x00,	EN0_RSARLO},  /* DMA starting at 0x0000. */
+			{0x00,	EN0_RSARHI},
+			{E8390_RREAD+E8390_START, E8390_CMD},
+		};
+
+		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+			outb_p(program_seq[i].value, base_addr + 
+				program_seq[i].offset);
+
+	}
+	for(i = 0; i < 6 /*sizeof(SA_prom)*/; i+=1) {
+		SA_prom[i] = inb(base_addr + NE_DATAPORT);
+	}
+
+	start_page = NESM_START_PG;
+	stop_page = NESM_STOP_PG;
+
+	dev->irq=irq;
+
+	/* Snarf the interrupt now.  There's no point in waiting since we cannot
+	   share and the board will usually be enabled. */
+	{
+		int irqval = request_irq(dev->irq, ei_interrupt, 
+				0, name, NULL);
+		if (irqval) {
+			printk (" unable to get IRQ %d (irqval=%d).\n", 
+					dev->irq, +irqval);
+			return EAGAIN;
+		}
+	}
+
+	dev->base_addr = base_addr;
+
+	/* Allocate dev->priv and fill in 8390 specific dev fields. */
+	if (ethdev_init(dev)) {
+		printk (" unable to get memory for dev->priv.\n");
+		free_irq(dev->irq, NULL);
+		return -ENOMEM;
+	}
+
+	request_region(base_addr, NE_IO_EXTENT, name);
+
+	for(i = 0; i < ETHER_ADDR_LEN; i++) {
+		printk(" %2.2x", SA_prom[i]);
+		dev->dev_addr[i] = SA_prom[i];
+	}
+
+	printk("\n%s: %s found at %#x, using IRQ %d.\n",
+			dev->name, name, base_addr, dev->irq);
+
+	mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev);
+
+	ei_status.name = name;
+	ei_status.tx_start_page = start_page;
+	ei_status.stop_page = stop_page;
+	ei_status.word16 = (2 == 2);
+
+	ei_status.rx_start_page = start_page + TX_PAGES;
+#ifdef PACKETBUF_MEMSIZE
+	/* Allow the packet buffer size to be overridden by know-it-alls. */
+	ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
+#endif
+
+	ei_status.reset_8390 = &ne_reset_8390;
+	ei_status.block_input = &ne_block_input;
+	ei_status.block_output = &ne_block_output;
+	ei_status.get_8390_hdr = &ne_get_8390_hdr;
+	
+	ei_status.priv = slot;
+	
+	dev->open = &ne_open;
+	dev->stop = &ne_close;
+	NS8390_init(dev, 0);
+	return 0;
+}
+
+static int ne_open(struct device *dev)
+{
+	ei_open(dev);
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int ne_close(struct device *dev)
+{
+	if (ei_debug > 1)
+		printk("%s: Shutting down ethercard.\n", dev->name);
+	ei_close(dev);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/* Hard reset the card.  This used to pause for the same period that a
+   8390 reset command required, but that shouldn't be necessary. */
+static void ne_reset_8390(struct device *dev)
+{
+	unsigned long reset_start_time = jiffies;
+
+	if (ei_debug > 1) 
+		printk("resetting the 8390 t=%ld...", jiffies);
+
+	/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
+	outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+
+	ei_status.txing = 0;
+	ei_status.dmaing = 0;
+
+	/* This check _should_not_ be necessary, omit eventually. */
+	while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
+		if (jiffies - reset_start_time > 2*HZ/100) {
+			printk("%s: ne_reset_8390() did not complete.\n", 
+					dev->name);
+			break;
+		}
+	outb_p(ENISR_RESET, NE_BASE + EN0_ISR);	/* Ack intr. */
+}
+
+/* Grab the 8390 specific header. Similar to the block_input routine, but
+   we don't need to be concerned with ring wrap as the header will be at
+   the start of a page, so we optimize accordingly. */
+
+static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, 
+		int ring_page)
+{
+
+	int nic_base = dev->base_addr;
+
+	/* This *shouldn't* happen. 
+	   If it does, it's the last thing you'll see */
+	if (ei_status.dmaing) {
+		printk("%s: DMAing conflict in ne_get_8390_hdr "
+				"[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+				dev->name, ei_status.dmaing, ei_status.irqlock,
+				dev->interrupt);
+		return;
+	}
+
+	ei_status.dmaing |= 0x01;
+	outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+	outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+	outb_p(0, nic_base + EN0_RCNTHI);
+	outb_p(0, nic_base + EN0_RSARLO);		/* On page boundary */
+	outb_p(ring_page, nic_base + EN0_RSARHI);
+	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+	if (ei_status.word16)
+		insw(NE_BASE + NE_DATAPORT, hdr, 
+				sizeof(struct e8390_pkt_hdr)>>1);
+	else
+		insb(NE_BASE + NE_DATAPORT, hdr, 
+				sizeof(struct e8390_pkt_hdr));
+
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+}
+
+/* Block input and output, similar to the Crynwr packet driver.  If you
+   are porting to a new ethercard, look at the packet driver source for
+   hints. The NEx000 doesn't share the on-board packet memory -- you have
+   to put the packet out through the "remote DMA" dataport using outb. */
+
+static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, 
+		int ring_offset)
+{
+#ifdef NE_SANITY_CHECK
+	int xfer_count = count;
+#endif
+	int nic_base = dev->base_addr;
+	char *buf = skb->data;
+
+	/* This *shouldn't* happen. 
+	   If it does, it's the last thing you'll see */
+	if (ei_status.dmaing) {
+		printk("%s: DMAing conflict in ne_block_input "
+				"[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+				dev->name, ei_status.dmaing, ei_status.irqlock,
+				dev->interrupt);
+		return;
+	}
+	ei_status.dmaing |= 0x01;
+	outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+	outb_p(count & 0xff, nic_base + EN0_RCNTLO);
+	outb_p(count >> 8, nic_base + EN0_RCNTHI);
+	outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
+	outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
+	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+	if (ei_status.word16) {
+		insw(NE_BASE + NE_DATAPORT,buf,count>>1);
+		if (count & 0x01) {
+			buf[count-1] = inb(NE_BASE + NE_DATAPORT);
+#ifdef NE_SANITY_CHECK
+			xfer_count++;
+#endif
+		}
+	} else {
+		insb(NE_BASE + NE_DATAPORT, buf, count);
+	}
+
+#ifdef NE_SANITY_CHECK
+	/* This was for the ALPHA version only, but enough people have
+	   been encountering problems so it is still here.  If you see
+	   this message you either 1) have a slightly incompatible clone
+	   or 2) have noise/speed problems with your bus. */
+	if (ei_debug > 1) {	/* DMA termination address check... */
+		int addr, tries = 20;
+		do {
+			/* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
+			   -- it's broken for Rx on some cards! */
+			int high = inb_p(nic_base + EN0_RSARHI);
+			int low = inb_p(nic_base + EN0_RSARLO);
+			addr = (high << 8) + low;
+			if (((ring_offset + xfer_count) & 0xff) == low)
+				break;
+		} while (--tries > 0);
+		if (tries <= 0)
+			printk("%s: RX transfer address mismatch,"
+				"%#4.4x (expected) vs. %#4.4x (actual).\n",
+				dev->name, ring_offset + xfer_count, addr);
+	}
+#endif
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+}
+
+static void ne_block_output(struct device *dev, int count,
+		const unsigned char *buf, const int start_page)
+{
+	int nic_base = NE_BASE;
+	unsigned long dma_start;
+#ifdef NE_SANITY_CHECK
+	int retries = 0;
+#endif
+
+	/* Round the count up for word writes. Do we need to do this?
+	   What effect will an odd byte count have on the 8390?
+	   I should check someday. */
+	if (ei_status.word16 && (count & 0x01))
+		count++;
+
+	/* This *shouldn't* happen. 
+	   If it does, it's the last thing you'll see */
+	if (ei_status.dmaing) {
+		printk("%s: DMAing conflict in ne_block_output."
+				"[DMAstat:%d][irqlock:%d][intr:%ld]\n",
+				dev->name, ei_status.dmaing, ei_status.irqlock,
+				dev->interrupt);
+		return;
+	}
+	ei_status.dmaing |= 0x01;
+	/* We should already be in page 0, but to be safe... */
+	outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+#ifdef NE_SANITY_CHECK
+retry:
+#endif
+
+#ifdef NE8390_RW_BUGFIX
+	/* Handle the read-before-write bug the same way as the
+	   Crynwr packet driver -- the NatSemi method doesn't work.
+	   Actually this doesn't always work either, but if you have
+	   problems with your NEx000 this is better than nothing! */
+	outb_p(0x42, nic_base + EN0_RCNTLO);
+	outb_p(0x00, nic_base + EN0_RCNTHI);
+	outb_p(0x42, nic_base + EN0_RSARLO);
+	outb_p(0x00, nic_base + EN0_RSARHI);
+	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+	/* Make certain that the dummy read has occurred. */
+	SLOW_DOWN_IO;
+	SLOW_DOWN_IO;
+	SLOW_DOWN_IO;
+#endif
+
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);
+
+	/* Now the normal output. */
+	outb_p(count & 0xff, nic_base + EN0_RCNTLO);
+	outb_p(count >> 8,   nic_base + EN0_RCNTHI);
+	outb_p(0x00, nic_base + EN0_RSARLO);
+	outb_p(start_page, nic_base + EN0_RSARHI);
+
+	outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+	if (ei_status.word16) {
+		outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
+	} else {
+		outsb(NE_BASE + NE_DATAPORT, buf, count);
+	}
+
+	dma_start = jiffies;
+
+#ifdef NE_SANITY_CHECK
+	/* This was for the ALPHA version only, but enough people have
+	   been encountering problems so it is still here. */
+
+	if (ei_debug > 1) {		/* DMA termination address check... */
+		int addr, tries = 20;
+		do {
+			int high = inb_p(nic_base + EN0_RSARHI);
+			int low = inb_p(nic_base + EN0_RSARLO);
+			addr = (high << 8) + low;
+			if ((start_page << 8) + count == addr)
+				break;
+		} while (--tries > 0);
+		if (tries <= 0) {
+			printk("%s: Tx packet transfer address mismatch,"
+					"%#4.4x (expected) vs. %#4.4x (actual).\n",
+					dev->name, (start_page << 8) + count, addr);
+			if (retries++ == 0)
+				goto retry;
+		}
+	}
+#endif
+
+	while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
+		if (jiffies - dma_start > 2*HZ/100) {		/* 20ms */
+			printk("%s: timeout waiting for Tx RDC.\n", dev->name);
+			ne_reset_8390(dev);
+			NS8390_init(dev,1);
+			break;
+		}
+
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+	return;
+}
+
+
+#ifdef MODULE
+#define MAX_NE_CARDS	4	/* Max number of NE cards per module */
+#define NAMELEN		8	/* # of chars for storing dev->name */
+static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, };
+static struct device dev_ne[MAX_NE_CARDS] = {
+	{
+		NULL,		/* assign a chunk of namelist[] below */
+		0, 0, 0, 0,
+		0, 0,
+		0, 0, 0, NULL, NULL
+	},
+};
+
+static int io[MAX_NE_CARDS] = { 0, };
+static int irq[MAX_NE_CARDS]  = { 0, };
+static int bad[MAX_NE_CARDS]  = { 0, };	/* 0xbad = bad sig or no reset ack */
+
+#ifdef MODULE_PARM
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+#endif
+
+/* Module code fixed by David Weinehall */
+
+int init_module(void)
+{
+	int this_dev, found = 0;
+
+	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+		struct device *dev = &dev_ne[this_dev];
+		dev->name = namelist+(NAMELEN*this_dev);
+		dev->irq = irq[this_dev];
+		dev->mem_end = bad[this_dev];
+		dev->base_addr = io[this_dev];
+		dev->init = ne2_probe;
+		if (register_netdev(dev) != 0) {
+			if (found != 0) return 0;   /* Got at least one. */
+
+			printk(KERN_WARNING "ne2.c: No NE/2 card found.\n");
+			return -ENXIO;
+		}
+		found++;
+	}
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	int this_dev;
+
+	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+		struct device *dev = &dev_ne[this_dev];
+		if (dev->priv != NULL) {
+			mca_mark_as_unused(ei_status.priv);
+			mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
+			kfree(dev->priv);
+			dev->priv = NULL;
+			free_irq(dev->irq, dev);
+			/* removed (temporary) fot */
+			/* irq2dev_map[dev->irq] = NULL; */
+			release_region(dev->base_addr, NE_IO_EXTENT);
+			unregister_netdev(dev);
+		}
+	}
+}
+#endif /* MODULE */
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c ne2.c"
+ *  version-control: t
+ *  kept-new-versions: 5
+ * End:
+ */
diff -u --recursive --new-file v2.1.125/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v2.1.125/linux/drivers/net/ni65.c	Sun Jun  7 11:16:32 1998
+++ linux/drivers/net/ni65.c	Fri Oct  9 11:56:59 1998
@@ -351,6 +351,7 @@
 {
 	int i,j;
 	struct priv *p;
+	unsigned long flags;
 
 	for(i=0;i<NUM_CARDS;i++) {
 		if(check_region(ioaddr, cards[i].total_size))
@@ -417,12 +418,20 @@
 				int dma = dmatab[i];
 				if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
 					continue;
+					
+				flags=claim_dma_lock();
 				disable_dma(dma);
 				set_dma_mode(dma,DMA_MODE_CASCADE);
 				enable_dma(dma);
+				release_dma_lock(flags);
+				
 				ni65_init_lance(p,dev->dev_addr,0,0); /* trigger memory access */
+				
+				flags=claim_dma_lock();
 				disable_dma(dma);
 				free_dma(dma);
+				release_dma_lock(flags);
+				
 				if(readreg(CSR0) & CSR0_IDON)
 					break;
 			}
@@ -718,20 +727,25 @@
 {
 	 int i;
 	 struct priv *p = (struct priv *) dev->priv;
+	 unsigned long flags;
 
 	 p->lock = 0;
 	 p->xmit_queued = 0;
 
+	 flags=claim_dma_lock();
 	 disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */
 	 set_dma_mode(dev->dma,DMA_MODE_CASCADE);
 	 enable_dma(dev->dma);
+	 release_dma_lock(flags);
 
 	 outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */
 	 if( (i=readreg(CSR0) ) != 0x4)
 	 {
 		 printk(KERN_ERR "%s: can't RESET %s card: %04x\n",dev->name,
 							cards[p->cardno].cardname,(int) i);
+		 flags=claim_dma_lock();
 		 disable_dma(dev->dma);
+		 release_dma_lock(flags);
 		 return 0;
 	 }
 
@@ -782,7 +796,9 @@
 		 return 1; /* ->OK */
 	 }
 	 printk(KERN_ERR "%s: can't init lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
+	 flags=claim_dma_lock();
 	 disable_dma(dev->dma);
+	 release_dma_lock(flags);
 	 return 0; /* ->Error */
 }
 
@@ -1167,8 +1183,10 @@
 }
 
 #ifdef MODULE
+static char devicename[9] = { 0, };
+
 static struct device dev_ni65 = {
-	"				",	/* "ni6510": device name inserted by net_init.c */
+	devicename,	/* "ni6510": device name inserted by net_init.c */
 	0, 0, 0, 0,
 	0x360, 9,	 /* I/O address, IRQ */
 	0, 0, 0, NULL, ni65_probe };
diff -u --recursive --new-file v2.1.125/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v2.1.125/linux/drivers/net/plip.c	Thu Sep 17 17:53:36 1998
+++ linux/drivers/net/plip.c	Fri Oct  9 12:20:27 1998
@@ -242,7 +242,10 @@
 
 	pardev = parport_register_device(pb, dev->name, plip_preempt,
 					 plip_wakeup, plip_interrupt, 
-					 PARPORT_DEV_LURK, dev);
+					 0, dev);
+
+	if (!pardev)
+		return -ENODEV;
 
 	printk(KERN_INFO "%s", version);
 	printk(KERN_INFO "%s: Parallel port at %#3lx, using IRQ %d\n", dev->name,
diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c
--- v2.1.125/linux/drivers/net/sdla_fr.c	Sat Sep  5 16:46:40 1998
+++ linux/drivers/net/sdla_fr.c	Fri Oct  9 11:56:59 1998
@@ -650,8 +650,8 @@
 	dev->irq = wandev->irq;
 	dev->dma = wandev->dma;
 	dev->base_addr = wandev->ioport;
-	dev->mem_start = wandev->maddr;
-	dev->mem_end = wandev->maddr + wandev->msize - 1;
+	dev->mem_start = (unsigned long)wandev->maddr;
+	dev->mem_end = dev->mem_start + wandev->msize - 1;
 	/* Set transmit buffer queue length */
 	dev->tx_queue_len = 10;
 	/* Initialize socket buffers */
diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdla_ppp.c linux/drivers/net/sdla_ppp.c
--- v2.1.125/linux/drivers/net/sdla_ppp.c	Sat Sep  5 16:46:40 1998
+++ linux/drivers/net/sdla_ppp.c	Fri Oct  9 11:56:59 1998
@@ -412,8 +412,8 @@
 	dev->irq = wandev->irq;
 	dev->dma = wandev->dma;
 	dev->base_addr = wandev->ioport;
-	dev->mem_start = wandev->maddr;
-	dev->mem_end = wandev->maddr + wandev->msize - 1;
+	dev->mem_start = (unsigned long)wandev->maddr;
+	dev->mem_end = dev->mem_start + wandev->msize - 1;
 	/* Set transmit buffer queue length */
 	dev->tx_queue_len = 100;
 	/* Initialize socket buffers */
diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c
--- v2.1.125/linux/drivers/net/sdla_x25.c	Fri Oct  9 13:27:09 1998
+++ linux/drivers/net/sdla_x25.c	Fri Oct  9 11:56:59 1998
@@ -560,8 +560,8 @@
 	dev->irq	= wandev->irq;
 	dev->dma	= wandev->dma;
 	dev->base_addr	= wandev->ioport;
-	dev->mem_start	= wandev->maddr;
-	dev->mem_end	= wandev->maddr + wandev->msize - 1;
+	dev->mem_start	= (unsigned long)wandev->maddr;
+	dev->mem_end	= dev->mem_end + wandev->msize - 1;
 
         /* Set transmit buffer queue length */
         dev->tx_queue_len = 10;
diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdladrv.c linux/drivers/net/sdladrv.c
--- v2.1.125/linux/drivers/net/sdladrv.c	Wed Sep  9 14:51:08 1998
+++ linux/drivers/net/sdladrv.c	Fri Oct  9 11:56:59 1998
@@ -421,10 +421,10 @@
  			return err;
 		}
 	}
-	else if (!get_option_index(dpmbase_opt, virt_to_phys((void *)hw->dpmbase)))
+	else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase)))
 	{
 		printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n",
-			modname, hw->dpmbase)
+			modname, virt_to_phys(hw->dpmbase))
 		;
 		return -EINVAL;
 	} 
@@ -432,16 +432,14 @@
 	{
 		printk(KERN_ERR
 			"%s: 8K memory region at 0x%lX is not available!\n",
-			modname, hw->dpmbase)
-		;
+			modname, virt_to_phys(hw->dpmbase));
 		return -EINVAL;
 	} 
 	printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n",
-		modname, virt_to_phys((void *)hw->dpmbase))
-	;
+		modname, virt_to_phys(hw->dpmbase));
+
 	printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n",
-		modname, hw->memory / 1024)
-	;
+		modname, hw->memory / 1024);
 
 	/* Load firmware. If loader fails then shut down adapter */
 	err = sdla_load(hw, sfm, len);
@@ -830,7 +828,7 @@
 
 		/* Relocate window and copy block of data */
 		err = sdla_mapmem(hw, curvec);
-		memcpy((void*)buf, (void*)(hw->dpmbase + curpos), curlen);
+		memcpy(buf, (void *)((u8 *)hw->dpmbase + curpos), curlen);
 		addr       += curlen;
 		(char*)buf += curlen;
 		len        -= curlen;
@@ -872,7 +870,7 @@
 
 		/* Relocate window and copy block of data */
 		sdla_mapmem(hw, curvec);
-		memcpy((void*)(hw->dpmbase + curpos), (void*)buf, curlen);
+		memcpy((void*)((u8 *)hw->dpmbase + curpos), buf, curlen);
 		addr       += curlen;
 		(char*)buf += curlen;
 		len        -= curlen;
@@ -980,7 +978,7 @@
 
 	for (i = opt[0]; i && err; --i)
 	{
-		hw->dpmbase = (unsigned long )(phys_to_virt(opt[i]));
+		hw->dpmbase = phys_to_virt(opt[i]);
 		err = sdla_setdpm(hw);
 	}
 	return err;
@@ -1001,7 +999,7 @@
 
 	/* Shut down card and verify memory region */
 	sdla_down(hw);
-	if (check_memregion((void*)hw->dpmbase, hw->dpmsize))
+	if (check_memregion(hw->dpmbase, hw->dpmsize))
 		return -EINVAL
 	;
 
@@ -1154,7 +1152,7 @@
 
 	for (memsize = 0, winsize = hw->dpmsize;
 	     !sdla_mapmem(hw, memsize) &&
-		(test_memregion((void*)hw->dpmbase, winsize) == winsize)
+		(test_memregion(hw->dpmbase, winsize) == winsize)
 	     ;
 	     memsize += winsize)
 	;
@@ -1176,7 +1174,7 @@
 	if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
 		return -EIO
 	;
-	data = (void*)(hw->dpmbase + (sfminfo->dataoffs - hw->vector));
+	data = (void*)((u8 *)hw->dpmbase + (sfminfo->dataoffs - hw->vector));
 	memset(data, 0, sfminfo->datasize);
 
 	data[0x00] = make_config_byte(hw);
@@ -1229,7 +1227,7 @@
 static int sdla_start (sdlahw_t* hw, unsigned addr)
 {
 	unsigned port = hw->port;
-	unsigned char* bootp;
+	unsigned char *bootp;
 	int err, tmp, i;
 
 	if (!port) return -EFAULT;
@@ -1237,14 +1235,15 @@
 	switch (hw->type)
 	{
 	case SDLA_S502A:
-		bootp = (void*)(hw->dpmbase + 0x66);
+		bootp = hw->dpmbase;
+		bootp += 0x66;
 		break;
 
 	case SDLA_S502E:
 	case SDLA_S503:
 	case SDLA_S507:
 	case SDLA_S508:
-		bootp = (void*)hw->dpmbase;
+		bootp = hw->dpmbase;
 		break;
 
 	default:
@@ -1333,7 +1332,7 @@
 	hw->regs[1] = 0xFF;
 
 	/* Verify configuration options */
-	i = get_option_index(s502a_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+	i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
 	if (i == 0)
 		return -EINVAL
 	;
@@ -1372,7 +1371,7 @@
 	;
 
 	/* Verify configuration options */
-	i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+	i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
 	if (i == 0)
 		return -EINVAL
 	;
@@ -1416,7 +1415,7 @@
 	;
 
 	/* Verify configuration options */
-	i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+	i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
 	if (i == 0)
 		return -EINVAL
 	;
@@ -1458,7 +1457,7 @@
 	;
 
 	/* Verify configuration options */
-	i = get_option_index(s507_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+	i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
 	if (i == 0)
 		return -EINVAL
 	;
@@ -1515,7 +1514,7 @@
 	;
 
 	/* Verify configuration options */
-	i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+	i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
 	if (i == 0)
 		return -EINVAL
 	;
diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdlamain.c linux/drivers/net/sdlamain.c
--- v2.1.125/linux/drivers/net/sdlamain.c	Sat Sep  5 16:46:40 1998
+++ linux/drivers/net/sdlamain.c	Fri Oct  9 11:56:59 1998
@@ -269,9 +269,9 @@
 	card->hw.irq     = (conf->irq == 9) ? 2 : conf->irq;
 	/* Compute the virtual address of the card in kernel space */
 	if(conf->maddr)
-		card->hw.dpmbase = (unsigned long)phys_to_virt(conf->maddr);
+		card->hw.dpmbase = phys_to_virt(conf->maddr);
 	else	/* But 0 means NULL */
-		card->hw.dpmbase = conf->maddr;
+		card->hw.dpmbase = (void *)conf->maddr;
 
 	card->hw.dpmsize = SDLA_WINDOWSIZE;
 	card->hw.type    = conf->hw_opt[0];
@@ -470,8 +470,8 @@
 		}
 		/* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */
 		sti();	/* Not ideal but tough we have to do this */
-		if(copy_to_user((void*)(dump.ptr),
-			(void*)(card->hw.dpmbase + pos), len))	
+		if(copy_to_user((void *)dump.ptr,
+			(u8 *)card->hw.dpmbase + pos, len))	
 			return -EFAULT;
 		cli();
 		dump.length     -= len;
diff -u --recursive --new-file v2.1.125/linux/drivers/net/sktr.c linux/drivers/net/sktr.c
--- v2.1.125/linux/drivers/net/sktr.c	Wed Jul  1 19:38:54 1998
+++ linux/drivers/net/sktr.c	Fri Oct  9 11:56:59 1998
@@ -298,6 +298,7 @@
 __initfunc(static int sktr_isa_chk_card(struct device *dev, int ioaddr))
 {
 	int i, err;
+	unsigned long flags;
 
 	err = sktr_isa_chk_ioaddr(ioaddr);
 	if(err < 0)
@@ -373,9 +374,11 @@
                 }
         }
 
+	flags=claim_dma_lock();
 	disable_dma(dev->dma);
         set_dma_mode(dev->dma, DMA_MODE_CASCADE);
         enable_dma(dev->dma);
+        release_dma_lock(flags);
 
 	printk("%s: %s found at %#4x, using IRQ %d and DMA %d.\n",
                 dev->name, AdapterName, ioaddr, dev->irq, dev->dma);
@@ -1446,7 +1449,12 @@
 	sktr_disable_interrupts(dev);
    
 	if(dev->dma > 0) 
+	{
+		unsigned long flags=claim_dma_lock();
 		disable_dma(dev->dma);
+		release_dma_lock(flags);
+	}
+	
 	outw(0xFF00, dev->base_addr + SIFCMD);
 	if(dev->dma > 0)
 		outb(0xff, dev->base_addr + POSREG);
diff -u --recursive --new-file v2.1.125/linux/drivers/net/syncppp.c linux/drivers/net/syncppp.c
--- v2.1.125/linux/drivers/net/syncppp.c	Wed Sep  9 14:51:08 1998
+++ linux/drivers/net/syncppp.c	Sat Oct 17 15:33:45 1998
@@ -770,6 +770,7 @@
 	sp->obytes += skb->len;
 	/* Control is high priority so it doesnt get queued behind data */
 	skb->priority=1;
+	skb->dev = dev;
 	dev_queue_xmit(skb);
 }
 
@@ -811,6 +812,7 @@
 			ch->par2, ch->rel, ch->time0, ch->time1);
 	sp->obytes += skb->len;
 	skb->priority=1;
+	skb->dev = dev;
 	dev_queue_xmit(skb);
 }
 
@@ -861,9 +863,20 @@
 	{
 		case SPPPIOCCISCO:
 			sp->pp_flags|=PP_CISCO;
+			dev->type = ARPHRD_HDLC;
 			break;
 		case SPPPIOCPPP:
 			sp->pp_flags&=~PP_CISCO;
+			dev->type = ARPHRD_PPP;
+			break;
+		case SPPPIOCDEBUG:
+			sp->pp_flags&=~PP_DEBUG;
+			if(ifr->ifr_flags)
+			{
+				if(!capable(CAP_NET_ADMIN))
+					return -EPERM;
+				sp->pp_flags|=PP_DEBUG;
+			}
 			break;
 		default:
 			return -EINVAL;
@@ -908,7 +921,7 @@
 	dev->hard_header = sppp_hard_header;
 	dev->rebuild_header = sppp_rebuild_header;
 	dev->tx_queue_len = 10;
-	dev->type = ARPHRD_PPP;
+	dev->type = ARPHRD_HDLC;
 	dev->addr_len = 0;
 	dev->hard_header_len = sizeof(struct ppp_header);
 	dev->mtu = PPP_MTU;
@@ -924,7 +937,7 @@
 	dev->change_mtu = sppp_change_mtu;
 	dev->hard_header_cache = NULL;
 	dev->header_cache_update = NULL;
-	dev->flags = IFF_MULTICAST;
+	dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP;
 	dev_init_buffers(dev);
 }
 
diff -u --recursive --new-file v2.1.125/linux/drivers/net/syncppp.h linux/drivers/net/syncppp.h
--- v2.1.125/linux/drivers/net/syncppp.h	Wed Sep  9 14:51:08 1998
+++ linux/drivers/net/syncppp.h	Sat Oct 17 15:33:45 1998
@@ -20,6 +20,7 @@
 #ifndef _SYNCPPP_H_
 #define _SYNCPPP_H_ 1
 
+#ifdef __KERNEL__
 struct slcp {
 	u16	state;          /* state machine */
 	u32	magic;          /* local magic number */
@@ -71,7 +72,6 @@
 #define IPCP_STATE_ACK_SENT     2       /* IPCP state: conf-ack sent */
 #define IPCP_STATE_OPENED       3       /* IPCP state: opened */
 
-#ifdef __KERNEL__
 void sppp_attach (struct ppp_device *pd);
 void sppp_detach (struct device *dev);
 void sppp_input (struct device *dev, struct sk_buff *m);
@@ -85,5 +85,6 @@
 
 #define SPPPIOCCISCO	(SIOCDEVPRIVATE)
 #define SPPPIOCPPP	(SIOCDEVPRIVATE+1)
+#define SPPPIOCDEBUG	(SIOCDEVPRIVATE+2)
 
 #endif /* _SYNCPPP_H_ */
diff -u --recursive --new-file v2.1.125/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- v2.1.125/linux/drivers/net/via-rhine.c	Fri Oct  9 13:27:09 1998
+++ linux/drivers/net/via-rhine.c	Sat Oct 17 15:33:45 1998
@@ -65,7 +65,6 @@
 #define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
 
 /* Include files, designed to support most kernel versions 2.0.0 and later. */
-#include <linux/config.h>
 #include <linux/version.h>
 #ifdef MODULE
 #ifdef MODVERSIONS
@@ -512,9 +511,8 @@
 }
 
 #ifndef MODULE
-static int via_rhine_probe(struct device *dev)
+int via_rhine_probe(struct device *dev)
 {
-	printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
 	return pci_etherdev_probe(dev, pci_tbl);
 }
 #endif
@@ -523,8 +521,12 @@
 								 struct device *dev, long ioaddr, int irq,
 								 int chip_id, int card_idx)
 {
+	static int did_version = 0;		/* Already printed version info */
 	struct netdev_private *np;
 	int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+
+	if (debug > 0 && did_version++ == 0)
+		printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
 
 	dev = init_etherdev(dev, 0);
 
diff -u --recursive --new-file v2.1.125/linux/drivers/net/z85230.c linux/drivers/net/z85230.c
--- v2.1.125/linux/drivers/net/z85230.c	Wed Sep  9 14:51:08 1998
+++ linux/drivers/net/z85230.c	Sat Oct 17 15:33:45 1998
@@ -152,8 +152,9 @@
 	3,	ENT_HM|RxCRC_ENAB|Rx8,
 	5,	TxCRC_ENAB|RTS|TxENAB|Tx8|DTR,
 	9,	0,		/* Disable interrupts */
+	6,	0xFF,
 	7,	FLAG,
-	10,	ABUNDER|MARKIDLE|NRZ|CRCPS,
+	10,	ABUNDER|NRZ|CRCPS,/*MARKIDLE ??*/
 	11,	TCTRxCP,
 	14,	DISDPLL,
 	15,	DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE,
@@ -176,8 +177,9 @@
 	3,	ENT_HM|RxCRC_ENAB|Rx8,
 	5,	TxCRC_ENAB|RTS|TxENAB|Tx8|DTR,
 	9,	0,		/* Disable interrupts */
+	6,	0xFF,
 	7,	FLAG,
-	10,	ABUNDER|MARKIDLE|NRZ|CRCPS,
+	10,	ABUNDER|NRZ|CRCPS,	/* MARKIDLE?? */
 	11,	TCTRxCP,
 	14,	DISDPLL,
 	15,	DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE,
@@ -389,6 +391,8 @@
 	if(chan->rxdma_on)
 	{
 		/* Special condition check only */
+		u8 r7=read_zsreg(chan, R7);
+		u8 r6=read_zsreg(chan, R6);
 		u8 status=read_zsreg(chan, R1);
 		if(status&END_FR)
 		{
@@ -418,6 +422,7 @@
 
 static void z8530_dma_status(struct z8530_channel *chan)
 {
+	unsigned long flags;
 	u8 status=read_zsreg(chan, R0);
 	u8 altered=chan->status^status;
 	
@@ -427,10 +432,12 @@
 	{
 		if(status&TxEOM)
 		{
+			flags=claim_dma_lock();
 			/* Transmit underrun */
 			disable_dma(chan->txdma);
 			clear_dma_ff(chan->txdma);	
 			chan->txdma_on=0;
+			release_dma_lock(flags);
 			z8530_tx_done(chan);
 		}
 	}
@@ -461,6 +468,15 @@
 
 EXPORT_SYMBOL(z8530_dma_sync);
 
+struct z8530_irqhandler z8530_txdma_sync=
+{
+	z8530_rx,
+	z8530_dma_tx,
+	z8530_dma_status
+};
+
+EXPORT_SYMBOL(z8530_txdma_sync);
+
 /*
  *	Interrupt vectors for a Z8530 that is in 'parked' mode.
  *	For machines with PCI Z85x30 cards, or level triggered interrupts
@@ -566,7 +582,7 @@
 				irqs->status(&dev->chanB);
 		}
 	}
-	if(work==200)
+	if(work==5000)
 		printk(KERN_ERR "%s: interrupt jammed - abort(0x%X)!\n", dev->name, intr);
 	/* Ok all done */
 	locker=0;
@@ -619,6 +635,8 @@
 
 int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c)
 {
+	unsigned long flags;
+	
 	c->sync = 1;
 	c->mtu = dev->mtu;
 	c->count = 0;
@@ -665,6 +683,7 @@
 		return -ENOBUFS;
 	}
 	c->tx_dma_used=0;
+	c->dma_tx = 1;
 	c->dma_num=0;
 	c->dma_ready=1;
 	
@@ -672,13 +691,23 @@
 	 *	Enable DMA control mode
 	 */
 	 
-	c->regs[R1]|= WT_RDY_RT|WT_FN_RDYFN;
+	/*
+	 *	TX DMA via DIR/REQ
+	 */
+	 
+	c->regs[R14]|= DTRREQ;
+	write_zsreg(c, R14, c->regs[R14]);     
+
+	/*
+	 *	RX DMA via W/Req
+	 */	 
+
+	c->regs[R1]|= WT_FN_RDYFN;
+	c->regs[R1]|= WT_RDY_RT;
 	c->regs[R1]|= INT_ERR_Rx;
 	write_zsreg(c, R1, c->regs[R1]);
 	c->regs[R1]|= WT_RDY_ENAB;
 	write_zsreg(c, R1, c->regs[R1]);            
-	c->regs[R14]|= DTRREQ;
-	write_zsreg(c, R14, c->regs[R14]);     
 	
 	/*
 	 *	DMA interrupts
@@ -688,9 +717,11 @@
 	 *	Set up the DMA configuration
 	 */	
 	 
+	flags=claim_dma_lock();
+	 
 	disable_dma(c->rxdma);
 	clear_dma_ff(c->rxdma);
-	set_dma_mode(c->rxdma, DMA_MODE_READ);
+	set_dma_mode(c->rxdma, DMA_MODE_READ|0x10);
 	set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[0]));
 	set_dma_count(c->rxdma, c->mtu);
 	enable_dma(c->rxdma);
@@ -700,6 +731,8 @@
 	set_dma_mode(c->txdma, DMA_MODE_WRITE);
 	disable_dma(c->txdma);
 	
+	release_dma_lock(flags);
+	
 	/*
 	 *	Select the DMA interrupt handlers
 	 */
@@ -719,6 +752,8 @@
 int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c)
 {
 	u8 chk;
+	unsigned long flags;
+	
 	c->irqs = &z8530_nop;
 	c->max = 0;
 	c->sync = 0;
@@ -726,12 +761,17 @@
 	/*
 	 *	Disable the PC DMA channels
 	 */
-	 
+	
+	flags=claim_dma_lock(); 
 	disable_dma(c->rxdma);
 	clear_dma_ff(c->rxdma);
+	
 	c->rxdma_on = 0;
+	
 	disable_dma(c->txdma);
 	clear_dma_ff(c->txdma);
+	release_dma_lock(flags);
+	
 	c->txdma_on = 0;
 	c->tx_dma_used = 0;
 
@@ -775,6 +815,137 @@
 
 EXPORT_SYMBOL(z8530_sync_dma_close);
 
+int z8530_sync_txdma_open(struct device *dev, struct z8530_channel *c)
+{
+	printk("Opening sync interface for TX-DMA\n");
+	c->sync = 1;
+	c->mtu = dev->mtu;
+	c->count = 0;
+	c->skb = NULL;
+	c->skb2 = NULL;
+	
+	/*
+	 *	Load the PIO receive ring
+	 */
+
+	z8530_rx_done(c);
+	z8530_rx_done(c);
+
+ 	/*
+	 *	Load the DMA interfaces up
+	 */
+
+	c->rxdma_on = 0;
+	c->txdma_on = 0;
+	
+	c->tx_dma_buf[0]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA);
+	if(c->tx_dma_buf[0]==NULL)
+	{
+		kfree(c->rx_buf[0]);
+		kfree(c->rx_buf[1]);
+		c->rx_buf[0]=NULL;
+		return -ENOBUFS;
+	}
+	c->tx_dma_buf[1]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA);
+	if(c->tx_dma_buf[1]==NULL)
+	{
+		kfree(c->tx_dma_buf[0]);
+		kfree(c->rx_buf[0]);
+		kfree(c->rx_buf[1]);
+		c->rx_buf[0]=NULL;
+		c->rx_buf[1]=NULL;
+		c->tx_dma_buf[0]=NULL;
+		return -ENOBUFS;
+	}
+	c->tx_dma_used=0;
+	c->dma_num=0;
+	c->dma_ready=1;
+	c->dma_tx = 1;
+
+ 	/*
+	 *	Enable DMA control mode
+	 */
+
+ 	/*
+	 *	TX DMA via DIR/REQ
+ 	 */
+	c->regs[R14]|= DTRREQ;
+	write_zsreg(c, R14, c->regs[R14]);     
+	
+	/*
+	 *	Set up the DMA configuration
+	 */	
+	 
+	disable_dma(c->txdma);
+	clear_dma_ff(c->txdma);
+	set_dma_mode(c->txdma, DMA_MODE_WRITE);
+	disable_dma(c->txdma);
+	
+	/*
+	 *	Select the DMA interrupt handlers
+	 */
+
+	c->rxdma_on = 0;
+	c->txdma_on = 1;
+	c->tx_dma_used = 1;
+	 
+	c->irqs = &z8530_txdma_sync;
+	printk("Loading RX\n");
+	z8530_rtsdtr(c,1);
+	printk("Rx interrupts ON\n");	
+	write_zsreg(c, R3, c->regs[R3]|RxENABLE);
+	return 0;
+}
+
+EXPORT_SYMBOL(z8530_sync_txdma_open);
+	
+int z8530_sync_txdma_close(struct device *dev, struct z8530_channel *c)
+{
+	u8 chk;
+	c->irqs = &z8530_nop;
+	c->max = 0;
+	c->sync = 0;
+	
+	/*
+	 *	Disable the PC DMA channels
+	 */
+	 
+	disable_dma(c->txdma);
+	clear_dma_ff(c->txdma);
+	c->txdma_on = 0;
+	c->tx_dma_used = 0;
+
+	/*
+	 *	Disable DMA control mode
+	 */
+	 
+	c->regs[R1]&= ~WT_RDY_ENAB;
+	write_zsreg(c, R1, c->regs[R1]);            
+	c->regs[R1]&= ~(WT_RDY_RT|WT_FN_RDYFN|INT_ERR_Rx);
+	c->regs[R1]|= INT_ALL_Rx;
+	write_zsreg(c, R1, c->regs[R1]);
+	c->regs[R14]&= ~DTRREQ;
+	write_zsreg(c, R14, c->regs[R14]);   
+	
+	if(c->tx_dma_buf[0])
+	{
+		kfree(c->tx_dma_buf[0]);
+		c->tx_dma_buf[0]=NULL;
+	}
+	if(c->tx_dma_buf[1])
+	{
+		kfree(c->tx_dma_buf[1]);
+		c->tx_dma_buf[1]=NULL;
+	}
+	chk=read_zsreg(c,R0);
+	write_zsreg(c, R3, c->regs[R3]);
+	z8530_rtsdtr(c,0);
+	return 0;
+}
+
+
+EXPORT_SYMBOL(z8530_sync_txdma_close);
+
 /*
  *	Describe a Z8530 in a standard format. We must pass the I/O as
  *	the port offset isnt predictable. The main reason for this function
@@ -929,7 +1100,12 @@
 	if(c->tx_skb==NULL)
 	{
 		/* Idle on */
-		disable_dma(c->txdma);
+		if(c->txdma)
+		{
+			flags=claim_dma_lock();
+			disable_dma(c->txdma);
+			release_dma_lock(flags);
+		}
 		c->txcount=0;
 	}
 	else
@@ -938,19 +1114,22 @@
 		c->txcount=c->tx_skb->len;
 		
 		
-		if(c->tx_dma_used)
+		if(c->dma_tx)
 		{
 			/*
-			 *	FIXME. DMA is broken for the non 85230,
+			 *	FIXME. DMA is broken for the original 8530,
 			 *	on the older parts we need to set a flag and
 			 *	wait for a further TX interrupt to fire this
 			 *	stage off	
 			 */
+			 
+			flags=claim_dma_lock();
 			disable_dma(c->txdma);
 			clear_dma_ff(c->txdma);
 			set_dma_addr(c->txdma, virt_to_bus(c->tx_ptr));
 			set_dma_count(c->txdma, c->txcount);
 			enable_dma(c->txdma);
+			release_dma_lock(flags);
 			write_zsreg(c, R5, c->regs[R5]|TxENAB);
 		}
 		else
@@ -1020,16 +1199,21 @@
 		 *	Save the ready state and the buffer currently
 		 *	being used as the DMA target
 		 */
+
 		int ready=c->dma_ready;
-		char *rxb=c->rx_buf[c->dma_num];
+		unsigned char *rxb=c->rx_buf[c->dma_num];
+		unsigned long flags;
 		
 		/*
 		 *	Complete this DMA. Neccessary to find the length
 		 */		
+		 
+		flags=claim_dma_lock();
+		
 		disable_dma(c->rxdma);
 		clear_dma_ff(c->rxdma);
 		c->rxdma_on=0;
-		ct=c->mtu-get_dma_residue(c->rxdma)-4;
+		ct=c->mtu-get_dma_residue(c->rxdma);
 		if(ct<0)
 			ct=2;	/* Shit happens.. */
 		c->dma_ready=0;
@@ -1042,16 +1226,21 @@
 		if(ready)
 		{
 			c->dma_num^=1;
-			set_dma_mode(c->rxdma, DMA_MODE_READ);
+			set_dma_mode(c->rxdma, DMA_MODE_READ|0x10);
 			set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[c->dma_num]));
 			set_dma_count(c->rxdma, c->mtu);
 			c->rxdma_on = 1;
 			enable_dma(c->rxdma);
+			/* Stop any frames that we missed the head of 
+			   from passing */
+			write_zsreg(c, R0, RES_Rx_CRC);
 		}
 		else
 			/* Can't occur as we dont reenable the DMA irq until
 			   after the flip is done */
 			printk("DMA flip overrun!\n");
+			
+		release_dma_lock(flags);
 		
 		/*
 		 *	Shove the old buffer into an sk_buff. We can't DMA
@@ -1068,7 +1257,6 @@
 		{
 			skb_put(skb, ct);
 			memcpy(skb->data, rxb, ct);
-			skb_pull(skb,2);
 		}
 		c->dma_ready=1;
 	}
@@ -1127,6 +1315,21 @@
 		printk("Lost a frame\n");
 }
 
+/*
+ *	Cannot DMA over a 64K boundary on a PC
+ */
+ 
+extern inline int spans_boundary(struct sk_buff *skb)
+{
+	unsigned long a=(unsigned long)skb->data;
+	a^=(a+skb->len);
+	if(a&0x00010000)	/* If the 64K bit is different.. */
+	{
+		printk("spanner\n");
+		return 1;
+	}
+	return 0;
+}
 
 /*
  *	Queue a packet for transmission. Because we have rather
@@ -1151,7 +1354,7 @@
 	 *	limit, then copy to the flip buffer
 	 */
 	 
-	if(c->dma_tx && (unsigned long)(virt_to_bus(skb->data+skb->len))>=16*1024*1024)
+	if(c->dma_tx && ((unsigned long)(virt_to_bus(skb->data+skb->len))>=16*1024*1024 || spans_boundary(skb)))
 	{
 		/* 
 		 *	Send the flip buffer, and flip the flippy bit.
diff -u --recursive --new-file v2.1.125/linux/drivers/net/z85230.h linux/drivers/net/z85230.h
--- v2.1.125/linux/drivers/net/z85230.h	Wed Sep  9 14:51:08 1998
+++ linux/drivers/net/z85230.h	Sat Oct 17 15:33:45 1998
@@ -272,8 +272,8 @@
 	u8		status;		/* Current DCD */
 	u8		sync;		/* Set if in sync mode */
 
-	u8		regs[16];	/* Register map for the chip */
-	u8		pendregs[16];	/* Pending register values */
+	u8		regs[32];	/* Register map for the chip */
+	u8		pendregs[32];	/* Pending register values */
 	
 	struct sk_buff 	*tx_skb;	/* Buffer being transmitted */
 	struct sk_buff  *tx_next_skb;	/* Next transmit buffer */
@@ -401,6 +401,8 @@
 extern int z8530_sync_close(struct device *, struct z8530_channel *);
 extern int z8530_sync_dma_open(struct device *, struct z8530_channel *);
 extern int z8530_sync_dma_close(struct device *, struct z8530_channel *);
+extern int z8530_sync_txdma_open(struct device *, struct z8530_channel *);
+extern int z8530_sync_txdma_close(struct device *, struct z8530_channel *);
 extern int z8530_channel_load(struct z8530_channel *, u8 *);
 extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb);
 extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c);
diff -u --recursive --new-file v2.1.125/linux/drivers/net/znet.c linux/drivers/net/znet.c
--- v2.1.125/linux/drivers/net/znet.c	Thu Feb 12 20:56:09 1998
+++ linux/drivers/net/znet.c	Tue Oct 20 13:17:41 1998
@@ -591,6 +591,7 @@
 /* The inverse routine to znet_open(). */
 static int znet_close(struct device *dev)
 {
+	unsigned long flags;
 	int ioaddr = dev->base_addr;
 
 	dev->tbusy = 1;
@@ -598,8 +599,10 @@
 
 	outb(CMD0_RESET, ioaddr);			/* CMD0_RESET */
 
+	flags=claim_dma_lock();
 	disable_dma(zn.rx_dma);
 	disable_dma(zn.tx_dma);
+	release_dma_lock(flags);
 
 	free_irq(dev->irq, dev);
 
@@ -662,16 +665,21 @@
 
 void show_dma(void)
 {
+	unsigned long flags;
 	short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
 	unsigned addr = inb(dma_port);
 	addr |= inb(dma_port) << 8;
+
+	flags=claim_dma_lock();
 	printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma));
+	release_dma_lock(flags);
 }
 
 /* Initialize the hardware.  We have to do this when the board is open()ed
    or when we come out of suspend mode. */
 static void hardware_init(struct device *dev)
 {
+	unsigned long flags;
 	short ioaddr = dev->base_addr;
 
 	zn.rx_cur = zn.rx_start;
@@ -680,22 +688,22 @@
 	/* Reset the chip, and start it up. */
 	outb(CMD0_RESET, ioaddr);
 
-	cli(); {							/* Protect against a DMA flip-flop */
-		disable_dma(zn.rx_dma); 		/* reset by an interrupting task. */
-		clear_dma_ff(zn.rx_dma);
-		set_dma_mode(zn.rx_dma, DMA_RX_MODE);
-		set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
-		set_dma_count(zn.rx_dma, RX_BUF_SIZE);
-		enable_dma(zn.rx_dma);
-		/* Now set up the Tx channel. */
-		disable_dma(zn.tx_dma);
-		clear_dma_ff(zn.tx_dma);
-		set_dma_mode(zn.tx_dma, DMA_TX_MODE);
-		set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
-		set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
-		enable_dma(zn.tx_dma);
-	} sti();
-
+	flags=claim_dma_lock();
+	disable_dma(zn.rx_dma); 		/* reset by an interrupting task. */
+	clear_dma_ff(zn.rx_dma);
+	set_dma_mode(zn.rx_dma, DMA_RX_MODE);
+	set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
+	set_dma_count(zn.rx_dma, RX_BUF_SIZE);
+	enable_dma(zn.rx_dma);
+	/* Now set up the Tx channel. */
+	disable_dma(zn.tx_dma);
+	clear_dma_ff(zn.tx_dma);
+	set_dma_mode(zn.tx_dma, DMA_TX_MODE);
+	set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
+	set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
+	enable_dma(zn.tx_dma);
+	release_dma_lock(flags);
+	
 	if (znet_debug > 1)
 	  printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name,
 			 zn.tx_start);
diff -u --recursive --new-file v2.1.125/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- v2.1.125/linux/drivers/pci/oldproc.c	Fri Oct  9 13:27:10 1998
+++ linux/drivers/pci/oldproc.c	Sun Oct 11 15:46:03 1998
@@ -1,5 +1,5 @@
 /*
- *	$Id: oldproc.c,v 1.20 1998/08/23 12:12:01 mj Exp $
+ *	$Id: oldproc.c,v 1.24 1998/10/11 15:13:04 mj Exp $
  *
  *	Backward-compatible procfs interface for PCI.
  *
@@ -200,6 +200,7 @@
 	DEVICE( PROMISE,	PROMISE_5300,	"DC5030"),
 	DEVICE( N9,		N9_I128,	"Imagine 128"),
 	DEVICE( N9,		N9_I128_2,	"Imagine 128v2"),
+	DEVICE( N9,		N9_I128_T2R,	"Revolution 3D"),
 	DEVICE( UMC,		UMC_UM8673F,	"UM8673F"),
 	DEVICE( UMC,		UMC_UM8891A,	"UM8891A"),
 	DEVICE( UMC,		UMC_UM8886BF,	"UM8886BF"),
@@ -528,10 +529,10 @@
 	DEVICE( ADAPTEC,	ADAPTEC_7883,	"AIC-7883U"),
 	DEVICE( ADAPTEC,	ADAPTEC_7884,	"AIC-7884U"),
 	DEVICE( ADAPTEC,	ADAPTEC_1030,	"ABA-1030 DVB receiver"),
-  DEVICE( ADAPTEC2, ADAPTEC2_2940U2, "AHA-2940U2"),
-  DEVICE( ADAPTEC2, ADAPTEC2_7890, "AIC-7890/1"),
-  DEVICE( ADAPTEC2, ADAPTEC2_3940U2, "AHA-3940U2"),
-  DEVICE( ADAPTEC2, ADAPTEC2_7896, "AIC-7896/7"),
+	DEVICE( ADAPTEC2,	ADAPTEC2_2940U2,"AHA-2940U2"),
+	DEVICE( ADAPTEC2,	ADAPTEC2_7890,	"AIC-7890/1"),
+	DEVICE( ADAPTEC2,	ADAPTEC2_3940U2,"AHA-3940U2"),
+	DEVICE( ADAPTEC2,	ADAPTEC2_7896,	"AIC-7896/7"),
   	DEVICE( ATRONICS,	ATRONICS_2015,	"IDE-2015PL"),
 	DEVICE( TIGERJET,	TIGERJET_300,	"Tiger300 ISDN"),
 	DEVICE( ARK,		ARK_STING,	"Stingray"),
diff -u --recursive --new-file v2.1.125/linux/drivers/pnp/parport_probe.c linux/drivers/pnp/parport_probe.c
--- v2.1.125/linux/drivers/pnp/parport_probe.c	Sat Sep  5 16:46:40 1998
+++ linux/drivers/pnp/parport_probe.c	Fri Oct  9 12:20:27 1998
@@ -91,7 +91,7 @@
 
 int parport_probe(struct parport *port, char *buffer, int len)
 {
-	struct pardevice *dev = parport_register_device(port, "IEEE 1284 probe", NULL, NULL, NULL, PARPORT_DEV_TRAN, &dev);
+	struct pardevice *dev = parport_register_device(port, "IEEE 1284 probe", NULL, NULL, NULL, 0, &dev);
 
 	int result = 0;
 
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.1.125/linux/drivers/scsi/Config.in	Thu Sep 17 17:53:36 1998
+++ linux/drivers/scsi/Config.in	Fri Oct  9 12:20:27 1998
@@ -53,7 +53,7 @@
 if [ "$CONFIG_PARPORT" != "n" ]; then
   dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT
   if [ "$CONFIG_SCSI_PPA" != "n" ]; then
-    int  '  Pedantic EPP-checking'   CONFIG_SCSI_PPA_HAVE_PEDANTIC 2 0 3
+    bool  '  Pedantic EPP-checking'   CONFIG_SCSI_PPA_HAVE_PEDANTIC
   fi
   dep_tristate 'IOMEGA ZIP Plus drive SCSI support' CONFIG_SCSI_IMM $CONFIG_SCSI $CONFIG_PARPORT
 fi
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c
--- v2.1.125/linux/drivers/scsi/NCR53c406a.c	Thu May 14 19:47:40 1998
+++ linux/drivers/scsi/NCR53c406a.c	Fri Oct  9 11:56:59 1998
@@ -317,15 +317,14 @@
     if ((count & 1) || (((unsigned) ptr) & 1))
         panic ("NCR53c406a: attempted unaligned DMA transfer\n"); 
     
-    save_flags(flags);
-    cli();
+    flags=claim_dma_lock();
     disable_dma(dma_chan);
     clear_dma_ff(dma_chan);
     set_dma_addr(dma_chan, (long) ptr);
     set_dma_count(dma_chan, count);
     set_dma_mode(dma_chan, mode);
     enable_dma(dma_chan);
-    restore_flags(flags);
+    release_dma_lock(flags);    
     
     return count;
 }
@@ -343,12 +342,12 @@
 static __inline__ int 
 NCR53c406a_dma_residual (void) {
     register int tmp;
-    unsigned long flags = 0;
-    save_flags(flags);
-    cli();
+    unsigned long flags;
+
+    flags=claim_dma_lock();
     clear_dma_ff(dma_chan);
     tmp = get_dma_residue(dma_chan);
-    restore_flags(flags);
+    release_dma_lock(flags);
     
     return tmp;
 }
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/README.aic7xxx linux/drivers/scsi/README.aic7xxx
--- v2.1.125/linux/drivers/scsi/README.aic7xxx	Fri Oct  9 13:27:10 1998
+++ linux/drivers/scsi/README.aic7xxx	Fri Oct  9 11:56:59 1998
@@ -412,7 +412,7 @@
     the system. Each file presents the current configuration and transfer
     statistics (enabled with #define in aic7xxx.c) for each controller.
 
-    Thanks to Michael Neuffer for for his upper-level SCSI help, and
+    Thanks to Michael Neuffer for his upper-level SCSI help, and
     Matthew Jacob for statistics support.
 
   Debugging the driver
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.1.125/linux/drivers/scsi/aha152x.c	Wed Sep  9 14:51:08 1998
+++ linux/drivers/scsi/aha152x.c	Fri Oct  9 11:38:15 1998
@@ -444,6 +444,7 @@
 
 /* set by aha152x_setup according to the command line */
 static int  setup_count=0;
+static int  registered_count=0;
 static struct aha152x_setup {
   int io_port;
   int irq;
@@ -951,6 +952,7 @@
 
     shpnt = aha152x_host[setup[i].irq-IRQ_MIN] =
       scsi_register(tpnt, sizeof(struct aha152x_hostdata));
+    registered_count++;
 
     shpnt->io_port                     = setup[i].io_port;
     shpnt->n_io_port                   = IO_RANGE;
@@ -1013,7 +1015,7 @@
 
     SETBITS(DMACNTRL0, INTEN);
 
-    ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", NULL);
+    ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", shpnt);
     if(ok<0) {
       if(ok == -EINVAL)
         printk("aha152x%d: bad IRQ %d.\n", i, shpnt->irq);
@@ -1024,6 +1026,8 @@
       printk("aha152x: driver needs an IRQ.\n");
 
       scsi_unregister(shpnt);
+      registered_count--;
+      release_region(shpnt->io_port, IO_RANGE);
       shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0;
       continue;
     }
@@ -1037,7 +1041,7 @@
     while(!HOSTDATA(shpnt)->swint && jiffies<the_time)
       barrier();
 
-    free_irq(shpnt->irq,0);
+    free_irq(shpnt->irq,shpnt);
 
     if(!HOSTDATA(shpnt)->swint) {
       if(TESTHI(DMASTAT, INTSTAT)) {
@@ -1049,6 +1053,8 @@
       printk("aha152x: IRQ %d possibly wrong.  Please verify.\n", shpnt->irq);
 
       scsi_unregister(shpnt);
+      registered_count--;
+      release_region(shpnt->io_port, IO_RANGE);
       shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0;
       continue;
     }
@@ -1061,12 +1067,23 @@
     SETPORT(SSTAT0, 0x7f);
     SETPORT(SSTAT1, 0xef);
 
-    if(request_irq(shpnt->irq,aha152x_intr,SA_INTERRUPT,"aha152x",NULL)<0) {
+    if(request_irq(shpnt->irq,aha152x_intr,SA_INTERRUPT,"aha152x",shpnt)<0) {
       printk("aha152x: failed to reassign interrupt.\n");
     }
   }
   
-  return (setup_count>0);
+  return (registered_count>0);
+}
+
+
+int aha152x_release(struct Scsi_Host *shpnt)
+{
+  if (shpnt->irq)
+    free_irq(shpnt->irq, shpnt);
+  if (shpnt->io_port)
+    release_region(shpnt->io_port, IO_RANGE);
+
+  return 0;
 }
 
 /* 
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h
--- v2.1.125/linux/drivers/scsi/aha152x.h	Fri Jul 31 17:08:24 1998
+++ linux/drivers/scsi/aha152x.h	Fri Oct 23 10:16:48 1998
@@ -15,6 +15,7 @@
 int aha152x_command(Scsi_Cmnd *);
 int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int aha152x_abort(Scsi_Cmnd *);
+int aha152x_release(struct Scsi_Host *shpnt);
 int aha152x_reset(Scsi_Cmnd *, unsigned int);
 int aha152x_biosparam(Disk *, kdev_t, int*);
 int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
@@ -36,6 +37,7 @@
                   queuecommand:       aha152x_queue,	  \
                   abort:              aha152x_abort,	  \
                   reset:              aha152x_reset,	  \
+                  release:            aha152x_release,	  \
                   slave_attach:       0,		  \
                   bios_param:         aha152x_biosparam,  \
                   can_queue:          1,		  \
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aic7xxx/bsd_q.h linux/drivers/scsi/aic7xxx/bsd_q.h
--- v2.1.125/linux/drivers/scsi/aic7xxx/bsd_q.h	Fri Oct  9 13:27:10 1998
+++ linux/drivers/scsi/aic7xxx/bsd_q.h	Wed Dec 31 16:00:00 1969
@@ -1,507 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)queue.h	8.5 (Berkeley) 8/20/94
- * $Id: queue.h,v 1.21 1998/05/12 03:55:25 gibbs Exp $
- */
-
-#ifndef _SYS_QUEUE_H_
-#define	_SYS_QUEUE_H_
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * slingly-linked tail queues, lists, tail queues, and circular queues.
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction.  Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A singly-linked tail queue is headed by a pair of pointers, one to the
- * head of the list and the other to the tail of the list. The elements are
- * singly linked for minimum space and pointer manipulation overhead at the
- * expense of O(n) removal for arbitrary elements. New elements can be added
- * to the list after an existing element, at the head of the list, or at the
- * end of the list. Elements being removed from the head of the tail queue
- * should use the explicit macro for this purpose for optimum efficiency.
- * A singly-linked tail queue may only be traversed in the forward direction.
- * Singly-linked tail queues are ideal for applications with large datasets
- * and few or no removals or for implementing a FIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may only be traversed in the forward direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- *
- *
- *			SLIST	LIST	STAILQ	TAILQ	CIRCLEQ
- * _HEAD		+	+	+	+	+
- * _ENTRY		+	+	+	+	+
- * _INIT		+	+	+	+	+
- * _EMPTY		+	+	+	+	+
- * _FIRST		+	+	-	+	+
- * _NEXT		+	+	-	+	+
- * _PREV		-	-	-	+	+
- * _LAST		-	-	-	+	+
- * _FOREACH		+	+	-	+	-
- * _INSERT_HEAD		+	+	+	+	+
- * _INSERT_BEFORE	-	+	-	+	+
- * _INSERT_AFTER	+	+	+	+	+
- * _INSERT_TAIL		-	-	+	+	+
- * _REMOVE_HEAD		+	-	+	-	-
- * _REMOVE		+	+	+	+	+
- *
- */
-
-/*
- * Singly-linked List definitions.
- */
-#define SLIST_HEAD(name, type)						\
-struct name {								\
-	struct type *slh_first;	/* first element */			\
-}
- 
-#define SLIST_ENTRY(type)						\
-struct {								\
-	struct type *sle_next;	/* next element */			\
-}
- 
-/*
- * Singly-linked List functions.
- */
-#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
-
-#define	SLIST_FIRST(head)	((head)->slh_first)
-
-#define SLIST_FOREACH(var, head, field)					\
-	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-#define SLIST_INIT(head) {						\
-	(head)->slh_first = NULL;					\
-}
-
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do  {			\
-	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
-	(slistelm)->field.sle_next = (elm);				\
-} while (0)
-
-#define SLIST_INSERT_HEAD(head, elm, field) do {			\
-	(elm)->field.sle_next = (head)->slh_first;			\
-	(head)->slh_first = (elm);					\
-} while (0)
-
-#define SLIST_NEXT(elm, field)	((elm)->field.sle_next)
-
-#define SLIST_REMOVE_HEAD(head, field) do {				\
-	(head)->slh_first = (head)->slh_first->field.sle_next;		\
-} while (0)
-
-#define SLIST_REMOVE(head, elm, type, field) do {			\
-	if ((head)->slh_first == (elm)) {				\
-		SLIST_REMOVE_HEAD((head), field);			\
-	}								\
-	else {								\
-		struct type *curelm = (head)->slh_first;		\
-		while( curelm->field.sle_next != (elm) )		\
-			curelm = curelm->field.sle_next;		\
-		curelm->field.sle_next =				\
-		    curelm->field.sle_next->field.sle_next;		\
-	}								\
-} while (0)
-
-/*
- * Singly-linked Tail queue definitions.
- */
-#define STAILQ_HEAD(name, type)						\
-struct name {								\
-	struct type *stqh_first;/* first element */			\
-	struct type **stqh_last;/* addr of last next element */		\
-}
-
-#define STAILQ_ENTRY(type)						\
-struct {								\
-	struct type *stqe_next;	/* next element */			\
-}
-
-/*
- * Singly-linked Tail queue functions.
- */
-#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
-
-#define	STAILQ_INIT(head) do {						\
-	(head)->stqh_first = NULL;					\
-	(head)->stqh_last = &(head)->stqh_first;			\
-} while (0)
-
-#define STAILQ_FIRST(head)	((head)->stqh_first)
-#define STAILQ_LAST(head)	(*(head)->stqh_last)
-
-#define STAILQ_INSERT_HEAD(head, elm, field) do {			\
-	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
-		(head)->stqh_last = &(elm)->field.stqe_next;		\
-	(head)->stqh_first = (elm);					\
-} while (0)
-
-#define STAILQ_INSERT_TAIL(head, elm, field) do {			\
-	(elm)->field.stqe_next = NULL;					\
-	*(head)->stqh_last = (elm);					\
-	(head)->stqh_last = &(elm)->field.stqe_next;			\
-} while (0)
-
-#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
-	if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
-		(head)->stqh_last = &(elm)->field.stqe_next;		\
-	(tqelm)->field.stqe_next = (elm);				\
-} while (0)
-
-#define STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
-
-#define STAILQ_REMOVE_HEAD(head, field) do {				\
-	if (((head)->stqh_first =					\
-	     (head)->stqh_first->field.stqe_next) == NULL)		\
-		(head)->stqh_last = &(head)->stqh_first;		\
-} while (0)
-
-#define STAILQ_REMOVE(head, elm, type, field) do {			\
-	if ((head)->stqh_first == (elm)) {				\
-		STAILQ_REMOVE_HEAD(head, field);			\
-	}								\
-	else {								\
-		struct type *curelm = (head)->stqh_first;		\
-		while( curelm->field.stqe_next != (elm) )		\
-			curelm = curelm->field.stqe_next;		\
-		if((curelm->field.stqe_next =				\
-		    curelm->field.stqe_next->field.stqe_next) == NULL)	\
-			(head)->stqh_last = &(curelm)->field.stqe_next;	\
-	}								\
-} while (0)
-
-/*
- * List definitions.
- */
-
-#define LIST_ENTRY(type)						\
-struct {								\
-	struct type *le_next;	/* next element */			\
-	struct type **le_prev;	/* address of previous next element */	\
-}
-
-/*
- * List functions.
- */
-
-#define	LIST_EMPTY(head) ((head)->lh_first == NULL)
-
-#define LIST_FIRST(head)	((head)->lh_first)
-
-#define LIST_FOREACH(var, head, field)					\
-	for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
-
-#define	LIST_INIT(head) do {						\
-	(head)->lh_first = NULL;					\
-} while (0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
-	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
-		(listelm)->field.le_next->field.le_prev =		\
-		    &(elm)->field.le_next;				\
-	(listelm)->field.le_next = (elm);				\
-	(elm)->field.le_prev = &(listelm)->field.le_next;		\
-} while (0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do {			\
-	(elm)->field.le_prev = (listelm)->field.le_prev;		\
-	(elm)->field.le_next = (listelm);				\
-	*(listelm)->field.le_prev = (elm);				\
-	(listelm)->field.le_prev = &(elm)->field.le_next;		\
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do {				\
-	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
-		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
-	(head)->lh_first = (elm);					\
-	(elm)->field.le_prev = &(head)->lh_first;			\
-} while (0)
-
-#define LIST_NEXT(elm, field)	((elm)->field.le_next)
-
-#define LIST_REMOVE(elm, field) do {					\
-	if ((elm)->field.le_next != NULL)				\
-		(elm)->field.le_next->field.le_prev = 			\
-		    (elm)->field.le_prev;				\
-	*(elm)->field.le_prev = (elm)->field.le_next;			\
-} while (0)
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type)						\
-struct name {								\
-	struct type *tqh_first;	/* first element */			\
-	struct type **tqh_last;	/* addr of last next element */		\
-}
-
-#define TAILQ_HEAD_INITIALIZER(head)					\
-	{ NULL, &(head).tqh_first }
-
-#define TAILQ_ENTRY(type)						\
-struct {								\
-	struct type *tqe_next;	/* next element */			\
-	struct type **tqe_prev;	/* address of previous next element */	\
-}
-
-/*
- * Tail queue functions.
- */
-#define	TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
-
-#define TAILQ_FOREACH(var, head, field)					\
-	for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
-
-#define	TAILQ_FIRST(head) ((head)->tqh_first)
-
-#define	TAILQ_LAST(head, headname) \
-	(*(((struct headname *)((head)->tqh_last))->tqh_last))
-
-#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-
-#define TAILQ_PREV(elm, headname, field) \
-	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-#define	TAILQ_INIT(head) do {						\
-	(head)->tqh_first = NULL;					\
-	(head)->tqh_last = &(head)->tqh_first;				\
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
-	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
-		(head)->tqh_first->field.tqe_prev =			\
-		    &(elm)->field.tqe_next;				\
-	else								\
-		(head)->tqh_last = &(elm)->field.tqe_next;		\
-	(head)->tqh_first = (elm);					\
-	(elm)->field.tqe_prev = &(head)->tqh_first;			\
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
-	(elm)->field.tqe_next = NULL;					\
-	(elm)->field.tqe_prev = (head)->tqh_last;			\
-	*(head)->tqh_last = (elm);					\
-	(head)->tqh_last = &(elm)->field.tqe_next;			\
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-		(elm)->field.tqe_next->field.tqe_prev = 		\
-		    &(elm)->field.tqe_next;				\
-	else								\
-		(head)->tqh_last = &(elm)->field.tqe_next;		\
-	(listelm)->field.tqe_next = (elm);				\
-	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
-} while (0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
-	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
-	(elm)->field.tqe_next = (listelm);				\
-	*(listelm)->field.tqe_prev = (elm);				\
-	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
-} while (0)
-
-#define TAILQ_REMOVE(head, elm, field) do {				\
-	if (((elm)->field.tqe_next) != NULL)				\
-		(elm)->field.tqe_next->field.tqe_prev = 		\
-		    (elm)->field.tqe_prev;				\
-	else								\
-		(head)->tqh_last = (elm)->field.tqe_prev;		\
-	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
-} while (0)
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type)					\
-struct name {								\
-	struct type *cqh_first;		/* first element */		\
-	struct type *cqh_last;		/* last element */		\
-}
-
-#define CIRCLEQ_ENTRY(type)						\
-struct {								\
-	struct type *cqe_next;		/* next element */		\
-	struct type *cqe_prev;		/* previous element */		\
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
-
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-
-#define CIRCLEQ_FOREACH(var, head, field)				\
-	for((var) = (head)->cqh_first;					\
-	    (var) != (void *)(head);					\
-	    (var) = (var)->field.cqe_next)
-
-#define	CIRCLEQ_INIT(head) do {						\
-	(head)->cqh_first = (void *)(head);				\
-	(head)->cqh_last = (void *)(head);				\
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
-	(elm)->field.cqe_prev = (listelm);				\
-	if ((listelm)->field.cqe_next == (void *)(head))		\
-		(head)->cqh_last = (elm);				\
-	else								\
-		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
-	(listelm)->field.cqe_next = (elm);				\
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
-	(elm)->field.cqe_next = (listelm);				\
-	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
-	if ((listelm)->field.cqe_prev == (void *)(head))		\
-		(head)->cqh_first = (elm);				\
-	else								\
-		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
-	(listelm)->field.cqe_prev = (elm);				\
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
-	(elm)->field.cqe_next = (head)->cqh_first;			\
-	(elm)->field.cqe_prev = (void *)(head);				\
-	if ((head)->cqh_last == (void *)(head))				\
-		(head)->cqh_last = (elm);				\
-	else								\
-		(head)->cqh_first->field.cqe_prev = (elm);		\
-	(head)->cqh_first = (elm);					\
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
-	(elm)->field.cqe_next = (void *)(head);				\
-	(elm)->field.cqe_prev = (head)->cqh_last;			\
-	if ((head)->cqh_first == (void *)(head))			\
-		(head)->cqh_first = (elm);				\
-	else								\
-		(head)->cqh_last->field.cqe_next = (elm);		\
-	(head)->cqh_last = (elm);					\
-} while (0)
-
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-
-#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
-
-#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
-
-#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
-	if ((elm)->field.cqe_next == (void *)(head))			\
-		(head)->cqh_last = (elm)->field.cqe_prev;		\
-	else								\
-		(elm)->field.cqe_next->field.cqe_prev =			\
-		    (elm)->field.cqe_prev;				\
-	if ((elm)->field.cqe_prev == (void *)(head))			\
-		(head)->cqh_first = (elm)->field.cqe_next;		\
-	else								\
-		(elm)->field.cqe_prev->field.cqe_next =			\
-		    (elm)->field.cqe_next;				\
-} while (0)
-
-#ifdef KERNEL
-
-/*
- * XXX insque() and remque() are an old way of handling certain queues.
- * They bogusly assumes that all queue heads look alike.
- */
-
-struct quehead {
-	struct quehead *qh_link;
-	struct quehead *qh_rlink;
-};
-
-#ifdef	__GNUC__
-
-static __inline void
-insque(void *a, void *b)
-{
-	struct quehead *element = a, *head = b;
-
-	element->qh_link = head->qh_link;
-	element->qh_rlink = head;
-	head->qh_link = element;
-	element->qh_link->qh_rlink = element;
-}
-
-static __inline void
-remque(void *a)
-{
-	struct quehead *element = a;
-
-	element->qh_link->qh_rlink = element->qh_rlink;
-	element->qh_rlink->qh_link = element->qh_link;
-	element->qh_rlink = 0;
-}
-
-#else /* !__GNUC__ */
-
-void	insque __P((void *a, void *b));
-void	remque __P((void *a));
-
-#endif /* __GNUC__ */
-
-#endif /* KERNEL */
-
-#endif /* !_SYS_QUEUE_H_ */
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aic7xxx/sequencer.h linux/drivers/scsi/aic7xxx/sequencer.h
--- v2.1.125/linux/drivers/scsi/aic7xxx/sequencer.h	Fri Oct  9 13:27:10 1998
+++ linux/drivers/scsi/aic7xxx/sequencer.h	Fri Oct  9 11:37:17 1998
@@ -73,7 +73,9 @@
 	union	ins_formats format;
 	unsigned int	srcline;
 	struct symbol *patch_label;
-	STAILQ_ENTRY(instruction) links;
+  struct {
+    struct instruction *stqe_next;
+  } links;
 };
 
 #define	AIC_OP_OR	0x0
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v2.1.125/linux/drivers/scsi/aic7xxx.c	Fri Oct  9 13:27:10 1998
+++ linux/drivers/scsi/aic7xxx.c	Sat Oct 10 09:30:16 1998
@@ -328,7 +328,6 @@
 #include "hosts.h"
 #include "aic7xxx.h"
 
-#include "aic7xxx/bsd_q.h"
 #include "aic7xxx/sequencer.h"
 #include "aic7xxx/scsi_message.h"
 #include "aic7xxx_reg.h"
@@ -350,7 +349,7 @@
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.1.0"
+#define AIC7XXX_C_VERSION  "5.1.2"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
@@ -6281,8 +6280,10 @@
       (((aic_inb(p, SEQADDR1) << 8) & 0x100) | aic_inb(p, SEQADDR0)));
     if (aic7xxx_panic_on_abort)
       aic7xxx_panic_abort(p, NULL);
+#ifdef CONFIG_PCI
     if (errno & PCIERRSTAT)
       aic7xxx_pci_intr(p);
+#endif
     if (errno & (SQPARERR | ILLOPCODE | ILLSADDR))
     {
       sti();
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v2.1.125/linux/drivers/scsi/eata.c	Tue Jul 28 14:21:08 1998
+++ linux/drivers/scsi/eata.c	Fri Oct  9 11:56:59 1998
@@ -1034,12 +1034,17 @@
    if (HD(j)->subversion == ESA)
       sh[j]->unchecked_isa_dma = FALSE;
    else {
+      unsigned long flags;
       sh[j]->wish_block = TRUE;
       sh[j]->unchecked_isa_dma = TRUE;
+      
+      flags=claim_dma_lock();
       disable_dma(dma_channel);
       clear_dma_ff(dma_channel);
       set_dma_mode(dma_channel, DMA_MODE_CASCADE);
       enable_dma(dma_channel);
+      release_dma_lock(flags);
+      
       }
 
    strcpy(BN(j), name);
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v2.1.125/linux/drivers/scsi/fdomain.c	Sun Jul 26 11:57:16 1998
+++ linux/drivers/scsi/fdomain.c	Wed Oct 14 11:43:14 1998
@@ -107,6 +107,7 @@
  2.0.12      5.44         8 Aug 1996  Use ID 7 for all PCI cards
  2.1.1       5.45         2 Oct 1996  Update ROM accesses for 2.1.x
  2.1.97      5.46	 23 Apr 1998  Rewritten PCI detection routines [mj]
+ 2.1.11x     5.47	  9 Aug 1998  Touched for 8 SCSI disk majors support
 
  
 
@@ -1891,7 +1892,11 @@
       0x0a bytes long.  Heads are one less than we need to report.
     */
 
-   drive = MINOR(dev) / 16;
+   if (MAJOR(dev) != SCSI_DISK0_MAJOR) {
+      printk("fdomain_16x0_biosparam: too many disks");
+      return 0;
+   }
+   drive = MINOR(dev) >> 4;
 
    if (bios_major == 2) {
       switch (Quantum) {
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/imm.c linux/drivers/scsi/imm.c
--- v2.1.125/linux/drivers/scsi/imm.c	Mon Sep 28 10:51:34 1998
+++ linux/drivers/scsi/imm.c	Fri Oct  9 12:20:27 1998
@@ -172,14 +172,29 @@
 
         imm_hosts[i].dev =
             parport_register_device(pb, "imm", NULL, imm_wakeup,
-                         NULL, PARPORT_DEV_TRAN, (void *) &imm_hosts[i]);
+                         NULL, 0, (void *) &imm_hosts[i]);
+
+	if (!imm_hosts[i].dev)
+		continue;
 
         /* Claim the bus so it remembers what we do to the control
          * registers. [ CTR and ECP ]
          */
-        if (imm_pb_claim(i))
-            while (imm_hosts[i].p_busy)
-                schedule();     /* We are safe to schedule here */
+	if (imm_pb_claim(i))
+	{
+	    unsigned long now = jiffies;
+	    while (imm_hosts[i].p_busy)
+	    {
+		schedule();	/* We are safe to schedule here */
+		if (jiffies > now + 3*HZ)
+		{
+		    printk(KERN_ERR "imm%d: failed to claim parport because a "
+			   "pardevice is owning the port for too longtime!\n",
+			   i);
+		    return 0;
+		}
+	    }
+	}
 
         ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base;
         w_ctr(ppb, 0x0c);
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
--- v2.1.125/linux/drivers/scsi/ppa.c	Mon Sep 28 10:51:34 1998
+++ linux/drivers/scsi/ppa.c	Fri Oct  9 12:20:27 1998
@@ -133,14 +133,29 @@
 
 	ppa_hosts[i].dev =
 	    parport_register_device(pb, "ppa", NULL, ppa_wakeup,
-			 NULL, PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]);
+			 NULL, 0, (void *) &ppa_hosts[i]);
+
+	if (!ppa_hosts[i].dev)
+		continue;
 
 	/* Claim the bus so it remembers what we do to the control
 	 * registers. [ CTR and ECP ]
 	 */
 	if (ppa_pb_claim(i))
+	{
+	    unsigned long now = jiffies;
 	    while (ppa_hosts[i].p_busy)
+	    {
 		schedule();	/* We are safe to schedule here */
+		if (jiffies > now + 3*HZ)
+		{
+		    printk(KERN_ERR "ppa%d: failed to claim parport because a "
+			   "pardevice is owning the port for too longtime!\n",
+			   i);
+		    return 0;
+		}
+	    }
+	}
 
 	ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base;
 	w_ctr(ppb, 0x0c);
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.1.125/linux/drivers/scsi/scsi.c	Fri Oct  9 13:27:11 1998
+++ linux/drivers/scsi/scsi.c	Wed Oct 14 11:43:13 1998
@@ -1734,8 +1734,7 @@
         host_active = NULL;
         
         /* For block devices "wake_up" is done in end_scsi_request */
-        if (MAJOR(SCpnt->request.rq_dev) != SCSI_DISK_MAJOR &&
-            MAJOR(SCpnt->request.rq_dev) != SCSI_CDROM_MAJOR) {
+        if (!SCSI_BLK_MAJOR(SCpnt->request.rq_dev)) {
             struct Scsi_Host * next;
             
             for (next = host->block; next != host; next = next->block)
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v2.1.125/linux/drivers/scsi/scsi.h	Thu Sep 17 17:53:36 1998
+++ linux/drivers/scsi/scsi.h	Fri Oct 23 10:15:54 1998
@@ -690,16 +690,22 @@
  * that an interrupt may start another request, so we run this with interrupts
  * turned off 
  */
-#define INIT_SCSI_REQUEST       \
-    if (!CURRENT) {             \
-	CLEAR_INTR;             \
-	return;                 \
-    }                           \
-    if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)           \
-	panic(DEVICE_NAME ": request list destroyed");\
-    if (CURRENT->bh) {                                \
-	if (!buffer_locked(CURRENT->bh))              \
-	    panic(DEVICE_NAME ": block not locked");  \
+#if MAJOR_NR == SCSI_DISK0_MAJOR
+#define CHECK_INITREQ_SD_MAJOR(major) SCSI_DISK_MAJOR(major)
+#else
+#define CHECK_INITREQ_SD_MAJOR(major) ((major) == MAJOR_NR)
+#endif
+
+#define INIT_SCSI_REQUEST       			\
+    if (!CURRENT) {             			\
+	CLEAR_INTR;             			\
+	return;                 			\
+    }                           			\
+    if (!CHECK_INITREQ_SD_MAJOR(MAJOR(CURRENT->rq_dev)))\
+	panic(DEVICE_NAME ": request list destroyed");	\
+    if (CURRENT->bh) {                                	\
+	if (!buffer_locked(CURRENT->bh))              	\
+	    panic(DEVICE_NAME ": block not locked");  	\
     }
 #endif
 
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- v2.1.125/linux/drivers/scsi/scsi_debug.c	Wed Sep  9 14:51:09 1998
+++ linux/drivers/scsi/scsi_debug.c	Wed Oct 14 11:43:13 1998
@@ -42,8 +42,8 @@
 
 /* A few options that we want selected */
 
-#define NR_HOSTS_PRESENT 1
-#define NR_FAKE_DISKS   3
+#define NR_HOSTS_PRESENT 20
+#define NR_FAKE_DISKS   6
 #define N_HEAD          32
 #define N_SECTOR        64
 #define DISK_READONLY(TGT)      (1)
@@ -55,6 +55,8 @@
 
 /* Skip some consistency checking.  Good for benchmarking */
 #define SPEEDY
+/* Read return zeros. Undefine for benchmarking */
+#define CLEAR
 
 /* Number of real scsi disks that will be detected ahead of time */
 static int NR_REAL=-1;
@@ -299,11 +301,8 @@
 #if defined(SCSI_SETUP_LATENCY) || defined(SCSI_DATARATE)
     {
 	int delay = SCSI_SETUP_LATENCY;
-	double usec;
 	
-	usec = 0.0;
-	usec = (SCpnt->request.nr_sectors << 9) * 1.0e6 / SCSI_DATARATE;
-	delay += usec;
+	delay += SCpnt->request.nr_sectors * SCSI_DATARATE;
 	if(delay) usleep(delay);
     };
 #endif
@@ -323,29 +322,31 @@
 	do{
 	    VERIFY1_DEBUG(READ);
 	    /* For the speedy test, we do not even want to fill the buffer with anything */
-#ifndef SPEEDY
+#ifdef CLEAR
 	    memset(buff, 0, bufflen);
 #endif
 	    /* If this is block 0, then we want to read the partition table for this
 	     * device.  Let's make one up */
-	    if(block == 0 && target == 0) {
+	    if(block == 0) {
+	    	int i;
                 memset(buff, 0, bufflen);
 		*((unsigned short *) (buff+510)) = 0xAA55;
 		p = (struct partition* ) (buff + 0x1be);
-		npart = 0;
-		while(starts[npart+1]){
-		    p->start_sect = starts[npart];
-		    p->nr_sects = starts[npart+1] - starts [npart];
+		i = 0;
+		while(starts[i+1]){
+		    p->start_sect = starts[i];
+		    p->nr_sects = starts[i+1] - starts [i];
 		    p->sys_ind = 0x81;  /* Linux partition */
-                    p->head       = (npart == 0 ? 1 : 0);
+                    p->head       = (i == 0 ? 1 : 0);
                     p->sector     = 1;
-                    p->cyl        = starts[npart] / N_HEAD / N_SECTOR;
+                    p->cyl        = starts[i] / N_HEAD / N_SECTOR;
                     p->end_head   = N_HEAD - 1;
                     p->end_sector = N_SECTOR;
-                    p->end_cyl    = starts[npart + 1] / N_HEAD / N_SECTOR;
+                    p->end_cyl    = starts[i + 1] / N_HEAD / N_SECTOR;
 		    p++;
-		    npart++;
+		    i++;
 		};
+		if (!npart) npart = i;
 		scsi_debug_errsts = 0;
 		break;
 	    };
@@ -376,7 +377,7 @@
 	    } /* End phony disk change code */
 #endif
 	    
-#ifndef SPEEDY
+#ifdef CLEAR
 	    memcpy(buff, &target, sizeof(target));
 	    memcpy(buff+sizeof(target), cmd, 24);
 	    memcpy(buff+60, &block, sizeof(block));
@@ -384,7 +385,7 @@
 #endif
 	    nbytes -= bufflen;
 	    if(SCpnt->use_sg){
-#ifndef SPEEDY
+#ifdef CLEAR
 		memcpy(buff+128, bh, sizeof(struct buffer_head));
 #endif
 		block += bufflen >> 9;
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi_obsolete.c linux/drivers/scsi/scsi_obsolete.c
--- v2.1.125/linux/drivers/scsi/scsi_obsolete.c	Fri Oct  9 13:27:11 1998
+++ linux/drivers/scsi/scsi_obsolete.c	Wed Oct 14 11:43:13 1998
@@ -658,8 +658,7 @@
 	    host_active = NULL;
 
 	    /* For block devices "wake_up" is done in end_scsi_request */
-	    if (MAJOR(SCpnt->request.rq_dev) != SCSI_DISK_MAJOR &&
-		MAJOR(SCpnt->request.rq_dev) != SCSI_CDROM_MAJOR) {
+	    if (!SCSI_BLK_MAJOR(SCpnt->request.rq_dev)) {
 		struct Scsi_Host * next;
 
 		for (next = host->block; next != host; next = next->block)
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.1.125/linux/drivers/scsi/sd.c	Mon Oct  5 13:13:40 1998
+++ linux/drivers/scsi/sd.c	Wed Oct 14 11:43:13 1998
@@ -14,8 +14,11 @@
  *
  *       Modified by Eric Youngdale eric@aib.com to support loadable
  *       low-level scsi drivers.
+ *
+ *       Modified by Jirka Hanika geo@ff.cuni.cz to support more
+ *       scsi disks using eight major numbers.
  */
-
+ 
 #include <linux/module.h>
 #ifdef MODULE
 /*
@@ -41,7 +44,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#define MAJOR_NR SCSI_DISK_MAJOR
+#define MAJOR_NR SCSI_DISK0_MAJOR
 #include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
@@ -54,6 +57,15 @@
 /*
  *  static const char RCSid[] = "$Header:";
  */
+ 
+#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
+ 
+#define SCSI_DISKS_PER_MAJOR	16
+#define SD_MAJOR_NUMBER(i)	SD_MAJOR((i) >> 8)
+#define SD_MINOR_NUMBER(i)	((i) & 255)
+#define MKDEV_SD_PARTITION(i)	MKDEV(SD_MAJOR_NUMBER(i), (i) & 255)
+#define MKDEV_SD(index)		MKDEV_SD_PARTITION((index) << 4)
+#define N_USED_SD_MAJORS	((sd_template.dev_max + SCSI_DISKS_PER_MAJOR - 1) / SCSI_DISKS_PER_MAJOR)
 
 #define MAX_RETRIES 5
 
@@ -91,12 +103,9 @@
 
 static void sd_devname(unsigned int disknum, char * buffer)
 {
-    if( disknum <= 26 )
-    {
+    if( disknum < 26 )
         sprintf(buffer, "sd%c", 'a' + disknum);
-    }
-    else
-    {
+    else {
         unsigned int min1;
         unsigned int min2;
         /*
@@ -105,13 +114,13 @@
          */
         min1 = disknum / 26;
         min2 = disknum % 26;
-        sprintf(buffer, "sd%c%c", 'a' + min1, 'a' + min2);
+        sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
     }
 }
 
 struct Scsi_Device_Template sd_template =
 { NULL, "disk", "sd", NULL, TYPE_DISK,
-      SCSI_DISK_MAJOR, 0, 0, 0, 1,
+      SCSI_DISK0_MAJOR, 0, 0, 0, 1,
       sd_detect, sd_init,
       sd_finish, sd_attach, sd_detach
 };
@@ -175,7 +184,7 @@
      * See if we are requesting a non-existent partition.  Do this
      * after checking for disk change.
      */
-    if(sd_sizes[MINOR(inode->i_rdev)] == 0)
+    if(sd_sizes[SD_PARTITION(inode->i_rdev)] == 0)
 	return -ENXIO;
 
     if(rscsi_disks[target].device->removable)
@@ -230,8 +239,13 @@
     fop_revalidate_scsidisk      /* revalidate */
 };
 
+/*
+ *	If we need more than one SCSI disk major (i.e. more than
+ *	16 SCSI disks), we'll have to kmalloc() more gendisks later.
+ */
+
 static struct gendisk sd_gendisk = {
-    MAJOR_NR,                    /* Major number */
+    SCSI_DISK0_MAJOR,            /* Major number */
     "sd",                        /* Major name */
     4,                           /* Bits to shift to get real from partition */
     1 << 4,                      /* Number of partitions per real */
@@ -242,7 +256,12 @@
     0,                           /* number */
     NULL,                        /* internal */
     NULL                         /* next */
-};
+}; 
+
+static struct gendisk *sd_gendisks = &sd_gendisk;
+
+#define SD_GENDISK(i)    sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR]
+#define LAST_SD_GENDISK  sd_gendisks[N_USED_SD_MAJORS - 1]
 
 static void sd_geninit (struct gendisk *ignored)
 {
@@ -251,10 +270,6 @@
     for (i = 0; i < sd_template.dev_max; ++i)
 	if(rscsi_disks[i].device)
 	    sd[i << 4].nr_sects = rscsi_disks[i].capacity;
-#if 0
-    /* No longer needed - we keep track of this as we attach/detach */
-    sd_gendisk.nr_real = sd_template.dev_max;
-#endif
 }
 
 /*
@@ -271,7 +286,7 @@
     int good_sectors = (result == 0 ? this_count : 0);
     int block_sectors = 1;
 
-    sd_devname(MINOR(SCpnt->request.rq_dev) >> 4, nbuff);
+    sd_devname(DEVICE_NR(SCpnt->request.rq_dev), nbuff);
 
     SCSI_LOG_HLCOMPLETE(1,printk("%s : rw_intr(%d, %x [%x %x])\n", nbuff,
 	   SCpnt->host->host_no, 
@@ -309,7 +324,7 @@
 	  }
 	else if (sector_size == 256)
 	  error_sector >>= 1;
-	error_sector -= sd[MINOR(SCpnt->request.rq_dev)].start_sect;
+	error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect;
 	error_sector &= ~ (block_sectors - 1);
 	good_sectors = error_sector - SCpnt->request.sector;
 	if (good_sectors < 0 || good_sectors >= this_count)
@@ -524,7 +539,7 @@
 	}
 
 	INIT_SCSI_REQUEST;
-        SDev = rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device;
+        SDev = rscsi_disks[CURRENT_DEV].device;
 
         /*
          * If the host for this device is in error recovery mode, don't
@@ -578,7 +593,7 @@
 
 	if (flag++ == 0)
 	    SCpnt = scsi_allocate_device(&CURRENT,
-			   rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device, 0);
+			   rscsi_disks[CURRENT_DEV].device, 0);
 	else SCpnt = NULL;
 
 	/*
@@ -643,7 +658,7 @@
 	return;
     }
 
-    devm =  MINOR(SCpnt->request.rq_dev);
+    devm =  SD_PARTITION(SCpnt->request.rq_dev);
     dev = DEVICE_NR(SCpnt->request.rq_dev);
 
     block = SCpnt->request.sector;
@@ -1329,7 +1344,7 @@
 		printk ("scsi : deleting disk entry.\n");
 		rscsi_disks[i].device = NULL;
 		sd_template.nr_dev--;
-		sd_gendisk.nr_real--;
+		SD_GENDISK(i).nr_real--;
 
                 /* Wake up a process waiting for device */
                 wake_up(&SCpnt->device->device_wait);
@@ -1463,67 +1478,99 @@
 
     if (sd_template.dev_noticed == 0) return 0;
 
+    if (!rscsi_disks)
+        sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
+
+    /* 128 disks is our current limit (8 majors, 16 disks per major) */
+    if(sd_template.dev_max > 128)
+   	sd_template.dev_max = 128;
+
     if(!sd_registered) {
-	  if (register_blkdev(MAJOR_NR,"sd",&sd_fops)) {
-	      printk("Unable to get major %d for SCSI disk\n",MAJOR_NR);
-	      return 1;
-	  }
-	  sd_registered++;
-      }
+	for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) {
+	    if (register_blkdev(SD_MAJOR(i),"sd",&sd_fops)) {
+		printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i));
+		return 1;
+	    }
+	}
+	sd_registered++;
+    }
 
     /* We do not support attaching loadable devices yet. */
     if(rscsi_disks) return 0;
 
-    sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
-
     rscsi_disks = (Scsi_Disk *)
 	scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
     memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));
-
-    sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
-					sizeof(int), GFP_ATOMIC);
+    
+  /* for every (necessary) major: */
+    sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
     memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));
 
-    sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
-					     sizeof(int), GFP_ATOMIC);
-
-    sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
-					    sizeof(int), GFP_ATOMIC);
+    sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
+    sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
 
-     for(i=0;i<(sd_template.dev_max << 4);i++)
-       {
-         sd_blocksizes[i] = 1024;
-         sd_hardsizes[i] = 512;
-       }
+    for(i=0; i < sd_template.dev_max << 4; i++) {
+	sd_blocksizes[i] = 1024;
+	sd_hardsizes[i] = 512;
+    }
  
-    blksize_size[MAJOR_NR] = sd_blocksizes;
-    hardsect_size[MAJOR_NR] = sd_hardsizes;
+    for (i=0; i < N_USED_SD_MAJORS; i++) {
+	blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4);
+	hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4);
+    }
     sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *
 					       sizeof(struct hd_struct),
 					       GFP_ATOMIC);
 
-
-    sd_gendisk.max_nr = sd_template.dev_max;
-    sd_gendisk.part = sd;
-    sd_gendisk.sizes = sd_sizes;
-    sd_gendisk.real_devices = (void *) rscsi_disks;
+    if (N_USED_SD_MAJORS > 1)
+    	sd_gendisks = (struct gendisk *)
+    	    kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);
+    for (i=0; i < N_USED_SD_MAJORS; i++) {
+	sd_gendisks[i].major = SD_MAJOR(i);
+	sd_gendisks[i].major_name = "sd";
+	sd_gendisks[i].minor_shift = 4;
+	sd_gendisks[i].max_p = 1 << 4;
+	sd_gendisks[i].max_nr = SCSI_DISKS_PER_MAJOR;
+	sd_gendisks[i].init = sd_geninit;
+	sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4);
+	sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4);
+	sd_gendisks[i].nr_real = 0;
+	sd_gendisks[i].next = sd_gendisks + i + 1;
+	sd_gendisks[i].real_devices =
+		 (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR);
+    }
+    LAST_SD_GENDISK.max_nr =
+    	sd_template.dev_max % SCSI_DISKS_PER_MAJOR;
+    LAST_SD_GENDISK.next = NULL;
     return 0;
 }
 
+/*
+ * sd_get_queue() returns the queue which corresponds to a given device.
+ */
+static struct request **sd_get_queue (kdev_t dev)
+{
+	return &blk_dev[MAJOR_NR].current_request;
+}
+
 static void sd_finish()
 {
     struct gendisk *gendisk;
     int i;
 
-    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+    for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) {
+        /* FIXME: After 2.2 we should implement multiple sd queues */
+        blk_dev[SD_MAJOR(i)].request_fn = DEVICE_REQUEST;
+        if (i) blk_dev[SD_MAJOR(i)].queue = sd_get_queue;
+    }
 
     for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next)
-      if (gendisk == &sd_gendisk)
+      if (gendisk == sd_gendisks)
 	break;
     if (gendisk == NULL)
       {
-	sd_gendisk.next = gendisk_head;
-	gendisk_head = &sd_gendisk;
+	LAST_SD_GENDISK.next = gendisk_head;
+	gendisk_head = sd_gendisks;
       }
 
     for (i = 0; i < sd_template.dev_max; ++i)
@@ -1534,7 +1581,7 @@
 		&& !rscsi_disks[i].has_part_table) {
 		sd_sizes[i << 4] = rscsi_disks[i].capacity;
 		/* revalidate does sd_init_onedisk via MAYBE_REINIT*/
-		revalidate_scsidisk(MKDEV(MAJOR_NR, i << 4), 0);
+		revalidate_scsidisk(MKDEV_SD(i), 0);
 	    }
 	    else
 	    	i=sd_init_onedisk(i);
@@ -1542,13 +1589,17 @@
 	}
 
     /* If our host adapter is capable of scatter-gather, then we increase
-     * the read-ahead to 16 blocks (32 sectors).  If not, we use
-     * a two block (4 sector) read ahead.
+     * the read-ahead to 60 blocks (120 sectors).  If not, we use
+     * a two block (4 sector) read ahead. We can only respect this with the
+     * granularity of every 16 disks (one device major).
      */
-    if(rscsi_disks[0].device && rscsi_disks[0].device->host->sg_tablesize)
-	read_ahead[MAJOR_NR] = 120;  /* 120 sector read-ahead */
-    else
-	read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
+    for (i=0; i < N_USED_SD_MAJORS; i++) {
+        read_ahead[SD_MAJOR(i)] =
+            (rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device
+          && rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device->host->sg_tablesize)
+            ? 120  /* 120 sector read-ahead */
+            : 4;   /* 4 sector read-ahead */
+    }
 
     return;
 }
@@ -1586,7 +1637,7 @@
     rscsi_disks[i].device = SDp;
     rscsi_disks[i].has_part_table = 0;
     sd_template.nr_dev++;
-    sd_gendisk.nr_real++;
+    SD_GENDISK(i).nr_real++;
     return 0;
 }
 
@@ -1594,7 +1645,6 @@
 #define USAGE rscsi_disks[target].device->access_count
 #define CAPACITY rscsi_disks[target].capacity
 #define MAYBE_REINIT  sd_init_onedisk(target)
-#define GENDISK_STRUCT sd_gendisk
 
 /* This routine is called to flush all partitions and partition tables
  * for a changed scsi disk, and then re-read the new partition table.
@@ -1603,15 +1653,13 @@
  * usage == 1 (we need an open channel to use an ioctl :-), so this
  * is our limit.
  */
-int revalidate_scsidisk(kdev_t dev, int maxusage){
+int revalidate_scsidisk(kdev_t dev, int maxusage) {
     int target;
-    struct gendisk * gdev;
     int max_p;
     int start;
     int i;
 
     target =  DEVICE_NR(dev);
-    gdev = &GENDISK_STRUCT;
 
     if (DEVICE_BUSY || USAGE > maxusage) {
 	printk("Device busy for revalidation (usage=%d)\n", USAGE);
@@ -1619,37 +1667,38 @@
     }
     DEVICE_BUSY = 1;
 
-    max_p = gdev->max_p;
-    start = target << gdev->minor_shift;
+    max_p = sd_gendisks->max_p;
+    start = target << sd_gendisks->minor_shift;
 
     for (i=max_p - 1; i >=0 ; i--) {
-	int minor = start+i;
-	kdev_t devi = MKDEV(MAJOR_NR, minor);
+	int index = start+i;
+	kdev_t devi = MKDEV_SD_PARTITION(index);
         struct super_block *sb = get_super(devi);
 	sync_dev(devi);
 	if (sb) invalidate_inodes(sb);
 	invalidate_buffers(devi);
-	gdev->part[minor].start_sect = 0;
-	gdev->part[minor].nr_sects = 0;
+	sd_gendisks->part[index].start_sect = 0;
+	sd_gendisks->part[index].nr_sects = 0;
         /*
          * Reset the blocksize for everything so that we can read
          * the partition table.  Technically we will determine the
          * correct block size when we revalidate, but we do this just
          * to make sure that everything remains consistent.
          */
-        blksize_size[MAJOR_NR][minor] = 1024;
+        sd_blocksizes[index] = 1024;
         if( rscsi_disks[target].sector_size == 2048 )
-          blksize_size[MAJOR_NR][minor] = 2048;
+          sd_blocksizes[index] = 2048;
         else
-          blksize_size[MAJOR_NR][minor] = 1024;
+          sd_blocksizes[index] = 1024;
     }
 
 #ifdef MAYBE_REINIT
     MAYBE_REINIT;
 #endif
 
-    gdev->part[start].nr_sects = CAPACITY;
-    resetup_one_dev(gdev, target);
+    sd_gendisks->part[start].nr_sects = CAPACITY;
+    resetup_one_dev(&SD_GENDISK(target),
+		    target % SCSI_DISKS_PER_MAJOR);
 
     DEVICE_BUSY = 0;
     return 0;
@@ -1676,15 +1725,15 @@
 	    start = i << sd_gendisk.minor_shift;
 
 	    for (i=max_p - 1; i >=0 ; i--) {
-		int minor = start+i;
-		kdev_t devi = MKDEV(MAJOR_NR, minor);
+		int index = start+i;
+		kdev_t devi = MKDEV_SD_PARTITION(index);
                 struct super_block *sb = get_super(devi);
 		sync_dev(devi);
 		if (sb) invalidate_inodes(sb);
 		invalidate_buffers(devi);
-		sd_gendisk.part[minor].start_sect = 0;
-		sd_gendisk.part[minor].nr_sects = 0;
-		sd_sizes[minor] = 0;
+		sd_gendisks->part[index].start_sect = 0;
+		sd_gendisks->part[index].nr_sects = 0;
+		sd_sizes[index] = 0;
 	    }
 
 	    dpnt->has_part_table = 0;
@@ -1693,7 +1742,7 @@
 	    SDp->attached--;
 	    sd_template.dev_noticed--;
 	    sd_template.nr_dev--;
-	    sd_gendisk.nr_real--;
+	    SD_GENDISK(start).nr_real--;
 	    return;
 	}
     return;
@@ -1710,48 +1759,48 @@
 {
     struct gendisk * prev_sdgd;
     struct gendisk * sdgd;
+    int i;
+    int removed = 0;
 
     scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
-    unregister_blkdev(SCSI_DISK_MAJOR, "sd");
+
+    for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) 
+    unregister_blkdev(SD_MAJOR(i),"sd");
+    
     sd_registered--;
     if( rscsi_disks != NULL )
     {
-	scsi_init_free((char *) rscsi_disks,
-		       (sd_template.dev_noticed + SD_EXTRA_DEVS)
-		       * sizeof(Scsi_Disk));
-
+	scsi_init_free((char *) rscsi_disks, 
+			sd_template.dev_max * sizeof(Scsi_Disk));
 	scsi_init_free((char *) sd_sizes, sd_template.dev_max * sizeof(int));
 	scsi_init_free((char *) sd_blocksizes, sd_template.dev_max * sizeof(int));
 	scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int));
 	scsi_init_free((char *) sd,
 		       (sd_template.dev_max << 4) * sizeof(struct hd_struct));
 	/*
-	 * Now remove sd_gendisk from the linked list
+	 * Now remove sd_gendisks from the linked list
 	 */
-	sdgd = gendisk_head;
-	prev_sdgd = NULL;
-	while(sdgd != &sd_gendisk)
-	{
-	    prev_sdgd = sdgd;
-	    sdgd = sdgd->next;
-	}
 
-	if(sdgd != &sd_gendisk)
-	    printk("sd_gendisk not in disk chain.\n");
-	else {
-	    if(prev_sdgd != NULL)
-		prev_sdgd->next = sdgd->next;
-	    else
-		gendisk_head = sdgd->next;
-	}
+	for (sdgd = gendisk_head; sdgd; sdgd = sdgd->next)
+	{
+	    if (sdgd->next >= sd_gendisks && sdgd->next <= LAST_SD_GENDISK)
+	    	    removed++, sdgd->next = sdgd->next->next;
+	    else sdgd = sdgd->next;
+	}
+	if (removed != N_USED_SCSI_DISKS)
+	    printk("%s %d sd_gendisks in disk chain",
+	    	removed > N_USED_SCSI_DISKS ? "total" : "just", removed);
+	
     }
 
-    blksize_size[MAJOR_NR] = NULL;
-    blk_dev[MAJOR_NR].request_fn = NULL;
-    blk_size[MAJOR_NR] = NULL;
-    hardsect_size[MAJOR_NR] = NULL;
-    read_ahead[MAJOR_NR] = 0;
+    for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) {
+        blk_dev[SD_MAJOR(i)].request_fn = NULL;
+        blk_size[SD_MAJOR(i)] = NULL;
+        hardsect_size[SD_MAJOR(i)] = NULL;
+        read_ahead[SD_MAJOR(i)] = 0;
+    }
     sd_template.dev_max = 0;
+    if (sd_gendisks != &sd_gendisk) kfree(sd_gendisks);
 }
 #endif /* MODULE */
 
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/sd.h linux/drivers/scsi/sd.h
--- v2.1.125/linux/drivers/scsi/sd.h	Fri Jul 31 17:07:58 1998
+++ linux/drivers/scsi/sd.h	Fri Oct 23 10:16:03 1998
@@ -42,6 +42,11 @@
 
 extern int revalidate_scsidisk(kdev_t dev, int maxusage);
 
+#define N_SD_MAJORS	8
+
+#define SD_MAJOR_MASK	(N_SD_MAJORS - 1)
+#define SD_PARTITION(i)		(((MAJOR(i) & SD_MAJOR_MASK) << 8) | (MINOR(i) & 255))
+
 #endif
 
 /*
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c
--- v2.1.125/linux/drivers/scsi/sd_ioctl.c	Thu May  7 22:51:51 1998
+++ linux/drivers/scsi/sd_ioctl.c	Wed Oct 14 11:43:14 1998
@@ -13,6 +13,7 @@
 
 #include <asm/uaccess.h>
 
+#define MAJOR_NR	SCSI_DISK0_MAJOR
 #include <linux/blk.h>
 #include "scsi.h"
 #include <scsi/scsi_ioctl.h>
@@ -29,7 +30,7 @@
     int diskinfo[4];
     struct hd_geometry *loc = (struct hd_geometry *) arg;
     
-    SDev = rscsi_disks[MINOR(dev) >> 4].device;
+    SDev = rscsi_disks[DEVICE_NR(dev)].device;
     /*
      * If we are in the middle of error recovery, don't let anyone
      * else try and use this device.  Also, if error recovery fails, it
@@ -47,34 +48,34 @@
 	error = verify_area(VERIFY_WRITE, loc, sizeof(*loc));
 	if (error)
 	    return error;
-	host = rscsi_disks[MINOR(dev) >> 4].device->host;
+	host = rscsi_disks[DEVICE_NR(dev)].device->host;
 
 /* default to most commonly used values */
 
         diskinfo[0] = 0x40;
         diskinfo[1] = 0x20;
-        diskinfo[2] = rscsi_disks[MINOR(dev) >> 4].capacity >> 11;
+        diskinfo[2] = rscsi_disks[DEVICE_NR(dev)].capacity >> 11;
 
 /* override with calculated, extended default, or driver values */
 
 	if(host->hostt->bios_param != NULL)
-	    host->hostt->bios_param(&rscsi_disks[MINOR(dev) >> 4],
+	    host->hostt->bios_param(&rscsi_disks[DEVICE_NR(dev)],
 				    dev,
 				    &diskinfo[0]);
-        else scsicam_bios_param(&rscsi_disks[MINOR(dev) >> 4],
+        else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)],
 				dev, &diskinfo[0]);
 
 	put_user(diskinfo[0], &loc->heads);
 	put_user(diskinfo[1], &loc->sectors);
 	put_user(diskinfo[2], &loc->cylinders);
-	put_user(sd[MINOR(inode->i_rdev)].start_sect, &loc->start);
+	put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start);
 	return 0;
     case BLKGETSIZE:   /* Return device size */
 	if (!arg)  return -EINVAL;
 	error = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
 	if (error)
 	    return error;
-	put_user(sd[MINOR(inode->i_rdev)].nr_sects,
+	put_user(sd[SD_PARTITION(inode->i_rdev)].nr_sects,
 		 (long *) arg);
 	return 0;
 
@@ -110,7 +111,7 @@
     RO_IOCTLS(dev, arg);
 
     default:
-	return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device , cmd, (void *) arg);
+	return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg);
     }
 }
 
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v2.1.125/linux/drivers/scsi/u14-34f.c	Tue Jul 28 14:21:08 1998
+++ linux/drivers/scsi/u14-34f.c	Fri Oct  9 11:56:59 1998
@@ -844,12 +844,17 @@
       bus_type = "VESA";
       }
    else {
+      unsigned long flags;
       sh[j]->wish_block = TRUE;
       sh[j]->unchecked_isa_dma = TRUE;
+      
+      flags=claim_dma_lock();
       disable_dma(dma_channel);
       clear_dma_ff(dma_channel);
       set_dma_mode(dma_channel, DMA_MODE_CASCADE);
       enable_dma(dma_channel);
+      release_dma_lock(flags);
+      
       sh[j]->dma_channel = dma_channel;
       sprintf(BN(j), "U14F%d", j);
       bus_type = "ISA";
diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c
--- v2.1.125/linux/drivers/scsi/wd7000.c	Wed Sep  9 14:51:09 1998
+++ linux/drivers/scsi/wd7000.c	Fri Oct  9 11:56:59 1998
@@ -772,10 +772,15 @@
 
 static inline void wd7000_enable_dma (Adapter *host)
 {
+    unsigned long flags;
     host->control |= DMA_EN;
     outb (host->control, host->iobase + ASC_CONTROL);
+    
+    flags = claim_dma_lock();
     set_dma_mode (host->dma, DMA_MODE_CASCADE);
     enable_dma (host->dma);
+    release_dma_lock(flags);
+    
 }
 
 
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.1.125/linux/drivers/sound/Config.in	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/Config.in	Sat Oct 17 15:33:45 1998
@@ -11,6 +11,9 @@
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
   dep_tristate 'Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND
+  if [ "$CONFIG_SOUND_ES1370" = "y" ]; then
+     bool 'Joystick support at boot time' CONFIG_SOUND_ES1370_JOYPORT_BOOT
+  fi  
   dep_tristate 'Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND
   dep_tristate 'S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND
 fi
@@ -20,11 +23,11 @@
    if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then
      comment 'Compiled-in MSND Classic support requires firmware during compilation.'
      define_bool CONFIG_MSNDCLAS_HAVE_BOOT y
-     string '  Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin"
-     string '  Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin"
    else
      define_bool CONFIG_MSNDCLAS_HAVE_BOOT n
    fi
+   string '  Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin"
+   string '  Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin"
 fi
 if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then
    int 'MSND Classic IRQ 5,7,9,10,11,12' CONFIG_MSNDCLAS_IRQ 5
@@ -36,29 +39,29 @@
 if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDPIN" = "m" ]; then
    if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then
      comment 'Compiled-in MSND Pinnacle support requires firmware during compilation.'
-     string '  Full pathname of PNDSPINI.BIN firmware file' CONFIG_MSNDPIN_INIT_FILE "/etc/sound/pndspini.bin"
-     string '  Full pathname of PNDSPERM.BIN firmware file' CONFIG_MSNDPIN_PERM_FILE "/etc/sound/pndsperm.bin"
      define_bool CONFIG_MSNDPIN_HAVE_BOOT y
    else
      define_bool CONFIG_MSNDPIN_HAVE_BOOT n
    fi
+   string '  Full pathname of PNDSPINI.BIN firmware file' CONFIG_MSNDPIN_INIT_FILE "/etc/sound/pndspini.bin"
+   string '  Full pathname of PNDSPERM.BIN firmware file' CONFIG_MSNDPIN_PERM_FILE "/etc/sound/pndsperm.bin"
 fi
 if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then
    int 'MSND Pinnacle IRQ 5,7,9,10,11,12' CONFIG_MSNDPIN_IRQ 5
    hex 'MSND Pinnacle memory B0000,C8000,D0000,D8000,E0000,E8000' CONFIG_MSNDPIN_MEM D0000
    hex 'MSND Pinnacle I/O 210,220,230,240,250,260,290,3E0' CONFIG_MSNDPIN_IO 290
    bool 'MSND Pinnacle has S/PDIF I/O' CONFIG_MSNDPIN_DIGITAL
-   bool 'MSND Pinnacle Non-PnP Mode' CONFIG_MSNDPIN_NONPNP
+   bool 'MSND Pinnacle non-PnP Mode' CONFIG_MSNDPIN_NONPNP
    if [ "$CONFIG_MSNDPIN_NONPNP" = "y" ]; then
      comment 'MSND Pinnacle DSP section will be configured to above parameters.'
-     hex 'MSDN Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250
+     hex 'MSND Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250
      comment 'Pinnacle-specific Device Configuration (0 disables)'
      hex 'MSND Pinnacle MPU I/O (e.g. 330)' CONFIG_MSNDPIN_MPU_IO 0
      int 'MSND Pinnacle MPU IRQ (e.g. 9)' CONFIG_MSNDPIN_MPU_IRQ 0
      hex 'MSND Pinnacle IDE I/O 0 (e.g. 170)' CONFIG_MSNDPIN_IDE_IO0 0
      hex 'MSND Pinnacle IDE I/O 1 (e.g. 376)' CONFIG_MSNDPIN_IDE_IO1 0
      int 'MSND Pinnacle IDE IRQ (e.g. 15)' CONFIG_MSNDPIN_IDE_IRQ 0
-     hex 'MSDN Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0
+     hex 'MSND Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0
    fi
 fi
 if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then
@@ -190,6 +193,16 @@
       int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3
       hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330
       int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9
+  fi
+
+  dep_tristate 'Support for Yamaha OPL3-SA[2,3,x] based (PnP) cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS
+  if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then
+      hex 'OPL3SA2 audio I/O base 530, 604, E80 or F40' CONFIG_OPL3SA2_BASE 530
+      int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 11
+      int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0
+      int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1
+      hex 'OPL3SA2 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_OPL3SA2_MPU_BASE 330
+      int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9
   fi
 
   dep_tristate 'Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v2.1.125/linux/drivers/sound/Makefile	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/Makefile	Fri Oct  9 11:56:59 1998
@@ -72,6 +72,7 @@
 obj-$(CONFIG_SOUND_MSNDPIN)	+= msnd.o msnd_pinnacle.o
 obj-$(CONFIG_SOUND_MSS)		+= ad1848.o
 obj-$(CONFIG_SOUND_OPL3SA1)	+= opl3sa.o ad1848.o uart401.o
+obj-$(CONFIG_SOUND_OPL3SA2)	+= opl3sa2.o ad1848.o uart401.o mpu401.o
 obj-$(CONFIG_SOUND_PAS)		+= pas2.o sb.o uart401.o
 obj-$(CONFIG_SOUND_PSS)		+= pss.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_SB)		+= sb.o uart401.o
@@ -219,7 +220,7 @@
 
 ifeq ($(CONFIG_MAUI_HAVE_BOOT),y)
     maui_boot.h: $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE)) bin2hex
-	bin2hex -i maui_os < $(CONFIG_MAUI_BOOT_FILE) > $@
+	./bin2hex -i maui_os < $(CONFIG_MAUI_BOOT_FILE) > $@
 else
     maui_boot.h:
 	(							\
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/Readme linux/drivers/sound/Readme
--- v2.1.125/linux/drivers/sound/Readme	Thu Jul 16 18:09:26 1998
+++ linux/drivers/sound/Readme	Fri Oct  9 11:56:59 1998
@@ -168,7 +168,7 @@
 	with impossible parameters. Check that the application is
 	for sound driver version 2.X or later.
 
-In general the printout of of /dev/sndstat should tell what is the problem.
+In general the printout of /dev/sndstat should tell what is the problem.
 It's possible that there are bugs in the sound driver but 99% of the problems
 reported to me are caused by somehow incorrect setup during "make config".
 
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.1.125/linux/drivers/sound/ad1848.c	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/ad1848.c	Fri Oct  9 11:56:59 1998
@@ -206,7 +206,7 @@
 		return;
 
 	timeout = 80000;
-	while (timeout > 0 && ad_read(devc, 11) & 0x20)
+	while (timeout > 0 && (ad_read(devc, 11) & 0x20))
 		timeout--;
 	if (ad_read(devc, 11) & 0x20)
 		if (devc->model != MD_1845)
@@ -916,7 +916,7 @@
 		cnt >>= 1;
 	cnt--;
 
-	if (devc->audio_mode & PCM_ENABLE_OUTPUT && audio_devs[dev]->flags & DMA_AUTOMODE &&
+	if ((devc->audio_mode & PCM_ENABLE_OUTPUT) && (audio_devs[dev]->flags & DMA_AUTOMODE) &&
 	    intrflag &&
 	    cnt == devc->xfer_count)
 	{
@@ -958,7 +958,7 @@
 		cnt >>= 1;
 	cnt--;
 
-	if (devc->audio_mode & PCM_ENABLE_INPUT && audio_devs[dev]->flags & DMA_AUTOMODE &&
+	if ((devc->audio_mode & PCM_ENABLE_INPUT) && (audio_devs[dev]->flags & DMA_AUTOMODE) &&
 		intrflag &&
 		cnt == devc->xfer_count)
 	{
@@ -1182,10 +1182,10 @@
 
 	unsigned char   bits = ad_read(devc, 9);
 
-	if (bits & 0x01 && portc->open_mode & OPEN_WRITE)
+	if (bits & 0x01 && (portc->open_mode & OPEN_WRITE))
 		ad1848_halt_output(dev);
 
-	if (bits & 0x02 && portc->open_mode & OPEN_READ)
+	if (bits & 0x02 && (portc->open_mode & OPEN_READ))
 		ad1848_halt_input(dev);
 	devc->audio_mode = 0;
 }
@@ -1308,7 +1308,7 @@
 		0x00, 0x0c, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00,
 
 	/* Positions 16 to 31 just for CS4231/2 and ad1845 */
-		0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+		0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x1f, 0x40,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 	};
 
@@ -1997,16 +1997,16 @@
 			ad_write(devc, 24, ad_read(devc, 24) & ~alt_stat);	/* Selective ack */
 		}
 
-		if (devc->open_mode & OPEN_READ && devc->audio_mode & PCM_ENABLE_INPUT && alt_stat & 0x20)
+		if ((devc->open_mode & OPEN_READ) && (devc->audio_mode & PCM_ENABLE_INPUT) && (alt_stat & 0x20))
 		{
 			DMAbuf_inputintr(devc->record_dev);
 		}
-		if (devc->open_mode & OPEN_WRITE && devc->audio_mode & PCM_ENABLE_OUTPUT &&
-		      alt_stat & 0x10)
+		if ((devc->open_mode & OPEN_WRITE) && (devc->audio_mode & PCM_ENABLE_OUTPUT) &&
+		      (alt_stat & 0x10))
 		{
 			DMAbuf_outputintr(devc->playback_dev, 1);
 		}
-		if (devc->model != MD_1848 && alt_stat & 0x40)	/* Timer interrupt */
+		if (devc->model != MD_1848 && (alt_stat & 0x40))	/* Timer interrupt */
 		{
 			devc->timer_ticks++;
 #if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/ad1848_mixer.h linux/drivers/sound/ad1848_mixer.h
--- v2.1.125/linux/drivers/sound/ad1848_mixer.h	Thu Jul 16 18:09:26 1998
+++ linux/drivers/sound/ad1848_mixer.h	Fri Oct  9 11:56:59 1998
@@ -17,7 +17,7 @@
  * The AD1848 codec has generic input lines called Line, Aux1 and Aux2.
  * Sound card manufacturers have connected actual inputs (CD, synth, line,
  * etc) to these inputs in different order. Therefore it's difficult
- * to assign mixer channels to to these inputs correctly. The following
+ * to assign mixer channels to these inputs correctly. The following
  * contains two alternative mappings. The first one is for GUS MAX and
  * the second is just a generic one (line1, line2 and line3).
  * (Actually this is not a mapping but rather some kind of interleaving
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
--- v2.1.125/linux/drivers/sound/audio.c	Sat Sep  5 16:46:41 1998
+++ linux/drivers/sound/audio.c	Sat Oct 17 15:33:46 1998
@@ -18,6 +18,8 @@
  *                   lifetime as the rest in there and dynamic allocation saves
  *                   12k or so
  * Thomas Sailer   : use more logical O_NONBLOCK semantics
+ * Daniel Rodriksson: reworked the use of the device specific copy_user
+ *                    still generic
  */
 
 #include <linux/config.h>
@@ -155,10 +157,21 @@
 
 	dev = dev >> 4;
 
+	/*
+	 * We do this in DMAbuf_release(). Why are we doing it
+	 * here? Why don't we test the file mode before setting
+	 * both flags? DMAbuf_release() does.
+	 * ...pester...pester...pester...
+	 */
 	audio_devs[dev]->dmap_out->closing = 1;
 	audio_devs[dev]->dmap_in->closing = 1;
 
-	sync_output(dev);
+	/*
+	 * We need to make sure we allocated the dmap_out buffer
+	 * before we go mucking around with it in sync_output().
+	 */
+	if (mode & OPEN_WRITE)
+		sync_output(dev);
 
 	if (audio_devs[dev]->coproc)
 		audio_devs[dev]->coproc->close(audio_devs[dev]->coproc->devc, COPR_PCM);
@@ -178,7 +191,7 @@
 
 int audio_write(int dev, struct file *file, const char *buf, int count)
 {
-	int c, p, l, buf_size;
+	int c, p, l, buf_size, used, returned;
 	int err;
 	char *dma_buf;
 
@@ -215,6 +228,8 @@
 		if (l > buf_size)
 			l = buf_size;
 
+        returned = l;
+        used = l;
 		if (!audio_devs[dev]->d->copy_user)
 		{
 			if ((dma_buf + l) >
@@ -231,7 +246,13 @@
 			if(copy_from_user(dma_buf, &(buf)[p], l))
 				return -EFAULT;
 		} 
-		else audio_devs[dev]->d->copy_user(dev, dma_buf, 0, buf, p, l);
+		else audio_devs[dev]->d->copy_user ( dev,
+                                             dma_buf, 0,
+                                             buf, p,
+                                             c, buf_size,
+                                             &used, &returned,
+                                             l);
+        l = returned;
 
 		if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
 		{
@@ -241,8 +262,8 @@
 			sti();
 			translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
 		}
-		c -= l;
-		p += l;
+		c -= used;
+		p += used;
 		DMAbuf_move_wrpointer(dev, l);
 
 	}
@@ -279,7 +300,7 @@
 			 *	Nonblocking mode handling. Return current # of bytes
 			 */
 
-			if (file->f_flags & O_NONBLOCK && buf_no == -EAGAIN)
+			if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN)
 				return p;
 
 			if (p > 0) 		/* Avoid throwing away data */
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v2.1.125/linux/drivers/sound/dev_table.h	Sat Sep  5 16:46:41 1998
+++ linux/drivers/sound/dev_table.h	Sat Oct 17 15:33:46 1998
@@ -31,6 +31,8 @@
 #define SNDCARD_SOFTOSS			36
 #define SNDCARD_VMIDI			37
 #define SNDCARD_WAVEFRONT               41
+#define SNDCARD_OPL3SA2                 42
+#define SNDCARD_OPL3SA2_MPU             43
 
 void attach_opl3sa_wss (struct address_info *hw_config);
 int probe_opl3sa_wss (struct address_info *hw_config);
@@ -186,8 +188,12 @@
 	int (*prepare_for_output) (int dev, int bufsize, int nbufs);
 	void (*halt_io) (int dev);
 	int (*local_qlen)(int dev);
-        void (*copy_user)(int dev, char *localbuf, int localoffs,
-                               const char *userbuf, int useroffs, int len);
+    void (*copy_user)(int dev,
+                      char *localbuf, int localoffs,
+                      const char *userbuf, int useroffs,
+                      int max_in, int max_out,
+                      int *used, int *returned,
+                      int len);
 	void (*halt_input) (int dev);
 	void (*halt_output) (int dev);
 	void (*trigger) (int dev, int bits);
@@ -412,6 +418,11 @@
 	{"CS4232MPU", 0, SNDCARD_CS4232_MPU,	"CS4232 MIDI",		attach_cs4232_mpu, probe_cs4232_mpu, unload_cs4232_mpu},
 #endif
 
+#ifdef CONFIG_SOUND_OPL3SA2
+	{"OPL3SA2", 0, SNDCARD_OPL3SA2,	"OPL3SA2",		attach_opl3sa2, probe_opl3sa2, unload_opl3sa2},
+	{"OPL3SA2MPU", 0, SNDCARD_OPL3SA2_MPU,	"OPL3SA2 MIDI",		attach_opl3sa2_mpu, probe_opl3sa2_mpu, unload_opl3sa2_mpu},
+#endif
+
 #ifdef CONFIG_SGALAXY
 	{"SGALAXY", 0, SNDCARD_SGALAXY,	"Sound Galaxy WSS",		attach_sgalaxy, probe_sgalaxy, unload_sgalaxy},
 #endif
@@ -558,6 +569,16 @@
 	{SNDCARD_CS4232_MPU, {CONFIG_CS4232_MPU_BASE, CONFIG_CS4232_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
 #endif
 	{SNDCARD_CS4232, {CONFIG_CS4232_BASE, CONFIG_CS4232_IRQ, CONFIG_CS4232_DMA, CONFIG_CS4232_DMA2}, SND_DEFAULT_ENABLE},
+#endif
+
+#ifdef CONFIG_SOUND_OPL3SA2
+#ifndef CONFIG_OPL3SA2_DMA2
+#define CONFIG_OPL3SA2_DMA2 CONFIG_OPL3SA2_DMA
+#endif
+#ifdef CONFIG_OPL3SA2_MPU_BASE
+	{SNDCARD_OPL3SA2_MPU, {CONFIG_OPL3SA2_MPU_BASE, CONFIG_OPL3SA2_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+#endif
+	{SNDCARD_OPL3SA2, {CONFIG_OPL3SA2_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
 #endif
 
 #ifdef CONFIG_SGALAXY
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c
--- v2.1.125/linux/drivers/sound/dmabuf.c	Sat Sep  5 16:46:41 1998
+++ linux/drivers/sound/dmabuf.c	Fri Oct  9 11:56:59 1998
@@ -138,15 +138,15 @@
 	int chan = dmap->dma;
 
 	/* printk( "Start DMA%d %d, %d\n",  chan,  (int)(physaddr-dmap->raw_buf_phys),  count); */
-	save_flags(flags);
-	cli();
+
+	flags = claim_dma_lock();
 	disable_dma(chan);
 	clear_dma_ff(chan);
 	set_dma_mode(chan, dma_mode);
 	set_dma_addr(chan, physaddr);
 	set_dma_count(chan, count);
 	enable_dma(chan);
-	restore_flags(flags);
+	release_dma_lock(flags);
 
 	return 0;
 }
@@ -201,11 +201,17 @@
 
 static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap)
 {
+	unsigned long flags;
+	
 	sound_close_dma(dmap->dma);
 	if (dmap->flags & DMA_BUSY)
 		dmap->dma_mode = DMODE_NONE;
 	dmap->flags &= ~DMA_BUSY;
+	
+	flags=claim_dma_lock();
 	disable_dma(dmap->dma);
+	release_dma_lock(flags);
+	
 	sound_free_dmap(dmap);
 }
 
@@ -279,7 +285,7 @@
 	}
 	adev->enable_bits = mode;
 
-	if (mode == OPEN_READ || (mode != OPEN_WRITE && adev->flags & DMA_DUPLEX)) {
+	if (mode == OPEN_READ || (mode != OPEN_WRITE && (adev->flags & DMA_DUPLEX))) {
 		if ((retval = open_dmap(adev, mode, dmap_in)) < 0) {
 			adev->d->close(dev);
 			if (mode & OPEN_WRITE)
@@ -311,7 +317,7 @@
 static void dma_reset_output(int dev)
 {
 	struct audio_operations *adev = audio_devs[dev];
-	unsigned long flags;
+	unsigned long flags,f ;
 	struct dma_buffparms *dmap = adev->dmap_out;
 
 	if (!(dmap->flags & DMA_STARTED))	/* DMA is not active */
@@ -341,8 +347,12 @@
 	else
 		adev->d->halt_output(dev);
 	adev->dmap_out->flags &= ~DMA_STARTED;
+	
+	f=claim_dma_lock();
 	clear_dma_ff(dmap->dma);
 	disable_dma(dmap->dma);
+	release_dma_lock(f);
+	
 	restore_flags(flags);
 	dmap->byte_counter = 0;
 	reorganize_buffers(dev, adev->dmap_out, 0);
@@ -377,7 +387,7 @@
 		return;		/* Don't start DMA yet */
 	dmap->dma_mode = DMODE_OUTPUT;
 
-	if (!(dmap->flags & DMA_ACTIVE) || !(adev->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA) {
+	if (!(dmap->flags & DMA_ACTIVE) || !(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) {
 		if (!(dmap->flags & DMA_STARTED)) {
 			reorganize_buffers(dev, dmap, 0);
 			if (adev->d->prepare_for_output(dev, dmap->fragment_size, dmap->nbufs))
@@ -404,7 +414,7 @@
 	int n = 0;
 	struct dma_buffparms *dmap;
 
-	if (!adev->go && (!adev->enable_bits & PCM_ENABLE_OUTPUT))
+	if (!adev->go && !(adev->enable_bits & PCM_ENABLE_OUTPUT))
 		return 0;
 
 	if (adev->dmap_out->dma_mode == DMODE_OUTPUT) {
@@ -476,7 +486,7 @@
 
 	if (adev->open_mode == OPEN_READ ||
 	    (adev->open_mode != OPEN_WRITE &&
-	     adev->flags & DMA_DUPLEX))
+	     (adev->flags & DMA_DUPLEX)))
 		close_dmap(adev, adev->dmap_in);
 	adev->open_mode = 0;
 	restore_flags(flags);
@@ -606,6 +616,7 @@
 
 	int pos;
 	unsigned long flags;
+	unsigned long f;
 
 	save_flags(flags);
 	cli();
@@ -613,9 +624,12 @@
 		pos = 0;
 	else {
 		int chan = dmap->dma;
+		
+		f=claim_dma_lock();
 		clear_dma_ff(chan);
 		disable_dma(dmap->dma);
 		pos = get_dma_residue(chan);
+		
 		pos = dmap->bytes_in_use - pos;
 
 		if (!(dmap->mapping_flags & DMA_MAP_MAPPED)) {
@@ -634,6 +648,7 @@
 		if (pos >= dmap->bytes_in_use)
 			pos = 0;
 		enable_dma(dmap->dma);
+		release_dma_lock(f);
 	}
 	restore_flags(flags);
 	/* printk( "%04x ",  pos); */
@@ -961,10 +976,16 @@
 	}
 	if (!(adev->flags & DMA_AUTOMODE))
 		dmap->flags &= ~DMA_ACTIVE;
-	while (dmap->qlen <= 0) {
+		
+	/*
+	 *	This is  dmap->qlen <= 0 except when closing when
+	 *	dmap->qlen < 0
+	 */
+	 
+	while (dmap->qlen <= -dmap->closing) {
 		dmap->underrun_count++;
 		dmap->qlen++;
-		if (dmap->flags & DMA_DIRTY && dmap->applic_profile != APF_CPUINTENS) {
+		if ((dmap->flags & DMA_DIRTY) && dmap->applic_profile != APF_CPUINTENS) {
 			dmap->flags &= ~DMA_DIRTY;
 			memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,
 			       adev->dmap_out->buffsize);
@@ -988,10 +1009,15 @@
 	cli();
 	if (!(dmap->flags & DMA_NODMA)) {
 		int chan = dmap->dma, pos, n;
+		unsigned long f;
+		
+		f=claim_dma_lock();
 		clear_dma_ff(chan);
 		disable_dma(dmap->dma);
 		pos = dmap->bytes_in_use - get_dma_residue(chan);
 		enable_dma(dmap->dma);
+		release_dma_lock(f);
+		
 		pos = pos / dmap->fragment_size;	/* Actual qhead */
 		if (pos < 0 || pos >= dmap->nbufs)
 			pos = 0;
@@ -1056,7 +1082,7 @@
 			}
 		}
 	}
-	if (!(adev->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA) {
+	if (!(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) {
 		local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);
 		adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size, dmap->fragment_size, 1);
 		if (adev->d->trigger)
@@ -1078,10 +1104,14 @@
 
 	if (!(dmap->flags & DMA_NODMA)) {
 		int chan = dmap->dma, pos, n;
+		unsigned long f;
+		
+		f=claim_dma_lock();
 		clear_dma_ff(chan);
 		disable_dma(dmap->dma);
 		pos = dmap->bytes_in_use - get_dma_residue(chan);
 		enable_dma(dmap->dma);
+		release_dma_lock(f);
 
 		pos = pos / dmap->fragment_size;	/* Actual qhead */
 		if (pos < 0 || pos >= dmap->nbufs)
@@ -1112,11 +1142,10 @@
 	if (adev->dmap_out->dma >= 0) {
 		unsigned long flags;
 
-		save_flags(flags);
-		cli();
+		flags=claim_dma_lock();
 		clear_dma_ff(adev->dmap_out->dma);
 		disable_dma(adev->dmap_out->dma);
-		restore_flags(flags);
+		release_dma_lock(flags);
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- v2.1.125/linux/drivers/sound/es1370.c	Sat Sep  5 16:46:41 1998
+++ linux/drivers/sound/es1370.c	Sat Oct 17 15:33:46 1998
@@ -24,9 +24,10 @@
  *
  * Module command line parameters:
  *   joystick if 1 enables the joystick interface on the card; but it still
- *            needs a separate joystick driver (presumably PC standard, although
- *            the chip doc doesn't say anything and it looks slightly fishy from
- *            the PCI standpoint...)
+ *            needs a driver for joysticks connected to a standard IBM-PC
+ *	      joyport. It is tested with the joy-analog driver. This 
+ *	      module must be loaded before the joystick driver. Kmod will
+ *	      not ensure that.
  *   lineout  if 1 the LINE jack is used as an output instead of an input.
  *            LINE then contains the unmixed dsp output. This can be used
  *            to make the card a four channel one: use dsp to output two
@@ -76,6 +77,8 @@
  *    22.08.98   0.12  Mixer registers actually have 5 instead of 4 bits
  *                     pointed out by Itai Nahshon
  *    31.08.98   0.13  Fix realplayer problems - dac.count issues
+ *    08.10.98   0.14  Joystick support fixed
+ *		       -- Oliver Neukum <c188@org.chemie.uni-muenchen.de>
  *
  * some important things missing in Ensoniq documentation:
  *
@@ -2242,8 +2245,11 @@
 
 /* maximum number of devices */
 #define NR_DEVICE 5
-
+#ifdef CONFIG_SOUND_ES1370_JOYPORT_BOOT
+static int joystick[NR_DEVICE] = { 1, 0, };
+#else
 static int joystick[NR_DEVICE] = { 0, };
+#endif
 static int lineout[NR_DEVICE] = { 0, };
 static int micz[NR_DEVICE] = { 0, };
 
@@ -2337,8 +2343,6 @@
 			goto err_dev3;
 		if ((s->dev_midi = register_sound_midi(&es1370_midi_fops)) < 0)
 			goto err_dev4;
-		if (s->ctrl & CTRL_JYSTK_EN)
-			request_region(0x200, JOY_EXTENT, "es1370");
 		/* initialize the chips */
 		outl(s->ctrl, s->io+ES1370_REG_CONTROL);
 		outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
--- v2.1.125/linux/drivers/sound/gus_wave.c	Thu Aug 20 17:05:16 1998
+++ linux/drivers/sound/gus_wave.c	Sat Oct 17 15:33:46 1998
@@ -863,7 +863,7 @@
 
 	int bank, chunk, addr, total = 0;
 	int bank_sizes[4];
-	int i, j, bits = -1, nbanks = 0;
+	int i, j, bits = -1, testbits = -1, nbanks = 0;
 
 	/*
 	 * This routine determines what kind of RAM is installed in each of the four
@@ -974,28 +974,26 @@
 		}
 	}
 	/*
-	 * The last resort is to search for a combination where the last bank is
-	 * smaller than the actual SIMM. This leaves some memory in the last bank
-	 * unused but doesn't leave holes in the DRAM address space.
-	 */
-	if (bits == -1)		/* No luck yet */
-	{
-		for (i = 0; bits == -1 && i < 13; i++)
-		{
-			bits = i;
-
-			for (j = 0; bits != -1 && j < nbanks - 1; j++)
-				if (mem_decode[i][j] != bank_sizes[j])
-					bits = -1;	/* No hit */
-		}
-		if (bits != -1)
-		{
+ 	 * The last resort is to search for a combination where the banks are
+ 	 * smaller than the actual SIMMs. This leaves some memory in the banks
+ 	 * unused but doesn't leave holes in the DRAM address space.
+ 	 */
+ 	if (bits == -1)		/* No luck yet */
+ 	{
+ 		for (i = 0; i < 13; i++)
+ 		{
+ 			testbits = i;
+ 			for (j = 0; testbits != -1 && j < nbanks - 1; j++)
+ 				if (mem_decode[i][j] > bank_sizes[j]) {
+ 					testbits = -1;
+ 				}
+ 			if(testbits > bits) bits = testbits;
+ 		}
+ 		if (bits != -1)
+ 		{
 			printk(KERN_INFO "Interwave: Can't use all installed RAM.\n");
 			printk(KERN_INFO "Interwave: Try reordering SIMMS.\n");
 		}
-	}
-	if (bits == -1)
-	{
 		printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n");
 		printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
 		bits = 0;
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/legacy.h linux/drivers/sound/legacy.h
--- v2.1.125/linux/drivers/sound/legacy.h	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/legacy.h	Fri Oct  9 11:56:59 1998
@@ -27,6 +27,7 @@
 #define CONFIG_MPU401
 #define CONFIG_MSS
 #define CONFIG_OPL3SA1
+#define CONFIG_OPL3SA2
 #define CONFIG_PAS
 #define CONFIG_PSS
 #define CONFIG_SB
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/msnd.h linux/drivers/sound/msnd.h
--- v2.1.125/linux/drivers/sound/msnd.h	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/msnd.h	Sat Oct 17 15:33:46 1998
@@ -24,13 +24,13 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: msnd.h,v 1.31 1998/09/10 14:02:58 andrewtv Exp $
+ * $Id: msnd.h,v 1.32 1998/10/09 19:54:39 andrewtv Exp $
  *
  ********************************************************************/
 #ifndef __MSND_H
 #define __MSND_H
 
-#define VERSION			"0.8.2"
+#define VERSION			"0.8.2.1"
 
 #define DEFSAMPLERATE		DSP_DEFAULT_SPEED
 #define DEFSAMPLESIZE		AFMT_U8
@@ -230,6 +230,7 @@
 #define F_READBLOCK			8
 #define F_EXT_MIDI_INUSE		9
 #define F_INT_MIDI_INUSE		10
+#define F_DISABLE_WRITE_NDELAY		11
 	struct wait_queue *writeblock, *readblock;
 	struct wait_queue *writeflush;
 #ifndef LINUX20
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- v2.1.125/linux/drivers/sound/msnd_pinnacle.c	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/msnd_pinnacle.c	Sat Oct 17 15:33:46 1998
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: msnd_pinnacle.c,v 1.63 1998/09/10 18:37:19 andrewtv Exp $
+ * $Id: msnd_pinnacle.c,v 1.66 1998/10/09 19:54:39 andrewtv Exp $
  *
  ********************************************************************/
 
@@ -66,6 +66,10 @@
 #  define LOGNAME			"msnd_pinnacle"
 #endif
 
+#ifndef CONFIG_MSND_WRITE_NDELAY
+#  define CONFIG_MSND_WRITE_NDELAY	0
+#endif
+
 #define get_play_delay_jiffies(size)	((size) * HZ *			\
 					 dev.play_sample_size / 8 /	\
 					 dev.play_sample_rate /		\
@@ -281,7 +285,8 @@
 		return 0;
 
 	case SNDCTL_DSP_NONBLOCK:
-		if (file->f_mode & FMODE_WRITE)
+		if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags) &&
+		    file->f_mode & FMODE_WRITE)
 			dev.play_ndelay = 1;
 		if (file->f_mode & FMODE_READ)
 			dev.rec_ndelay = 1;
@@ -742,11 +747,14 @@
 			dev.nresets = 0;
 			if (file->f_mode & FMODE_WRITE) {
 				set_default_play_audio_parameters();
-				dev.play_ndelay = (file->f_mode & O_NDELAY) ? 1 : 0;
+				if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags))
+					dev.play_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
+				else
+					dev.play_ndelay = 0;
 			}
 			if (file->f_mode & FMODE_READ) {
 				set_default_rec_audio_parameters();
-				dev.rec_ndelay = (file->f_mode & O_NDELAY) ? 1 : 0;
+				dev.rec_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
 			}
 		}
 	}
@@ -820,7 +828,7 @@
 	if ((n = msnd_fifo_write(
 		&dev.DARF,
 		(char *)(dev.base + bank * DAR_BUFF_SIZE),
-		size, 0)) < 0) {
+		size, 0)) <= 0) {
 		outb(HPBLKSEL_0, dev.io + HP_BLKS);
 		return n;
 	}
@@ -1099,7 +1107,9 @@
 	dev_ioctl,	/* ioctl */
 	NULL,		/* mmap */
 	dev_open,	/* open */
+#ifndef LINUX20
 	NULL,		/* flush */
+#endif
 	dev_release,	/* release */
 	NULL,		/* fsync */
 	NULL,		/* fasync */
@@ -1631,6 +1641,7 @@
 MODULE_PARM				(io, "i");
 MODULE_PARM				(irq, "i");
 MODULE_PARM				(mem, "i");
+MODULE_PARM				(write_ndelay, "i");
 MODULE_PARM				(major, "i");
 MODULE_PARM				(fifosize, "i");
 MODULE_PARM				(calibrate_signal, "i");
@@ -1649,6 +1660,7 @@
 static int io __initdata =		-1;
 static int irq __initdata =		-1;
 static int mem __initdata =		-1;
+static int write_ndelay __initdata =	-1;
 
 #ifndef MSND_CLASSIC
 /* Pinnacle/Fiji non-PnP Config Port */
@@ -1676,6 +1688,8 @@
 
 #else /* not a module */
 
+static int write_ndelay __initdata =	-1;
+
 #ifdef MSND_CLASSIC
 static int io __initdata =		CONFIG_MSNDCLAS_IO;
 static int irq __initdata =		CONFIG_MSNDCLAS_IRQ;
@@ -1888,6 +1902,12 @@
 	dev.recsrc = 0;
 	dev.inc_ref = mod_inc_ref;
 	dev.dec_ref = mod_dec_ref;
+	if (write_ndelay == -1)
+		write_ndelay = CONFIG_MSND_WRITE_NDELAY;
+	if (write_ndelay)
+		clear_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
+	else
+		set_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
 
 #ifndef MSND_CLASSIC
 	if (digital) {
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.1.125/linux/drivers/sound/opl3sa2.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/opl3sa2.c	Fri Oct  9 11:56:59 1998
@@ -0,0 +1,241 @@
+/*
+ * sound/opl3sa2.c
+ *
+ * A low level driver for Yamaha OPL3-SA[2,3,x] based cards.
+ *
+ * Scott Murray, Jun 14, 1998
+ *
+ */
+
+/* Based on the CS4232 driver:
+ *
+ * Copyright (C) by Hannu Savolainen 1993-1997
+ *
+ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include "sound_config.h"
+#include "soundmodule.h"
+
+#ifdef CONFIG_OPL3SA2
+
+int probe_opl3sa2_mpu(struct address_info *hw_config)
+{
+#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
+	return probe_mpu401(hw_config);
+#else
+	return 0;
+#endif
+}
+
+
+void attach_opl3sa2_mpu(struct address_info *hw_config)
+{
+#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
+	attach_mpu401(hw_config);
+#endif
+}
+
+
+void unload_opl3sa2_mpu(struct address_info *hw_config)
+{
+#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
+	unload_mpu401(hw_config);
+#endif
+}
+
+
+int probe_opl3sa2_mss(struct address_info *hw_config)
+{
+	return probe_ms_sound(hw_config);
+}
+
+
+void attach_opl3sa2_mss(struct address_info *hw_config)
+{
+   	printk(KERN_INFO "opl3sa2.c: trying to init WSS\n");   
+   
+	attach_ms_sound(hw_config);
+
+   	/* request_region(hw_config->io_base, 4, "Yamaha 7xx WSS Config"); */
+   
+	if (hw_config->slots[0] != -1 &&
+	    audio_devs[hw_config->slots[0]]->mixer_dev != -1)
+	{
+  		AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
+  		AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
+	        /* GSM! test the following: */
+                AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
+	}
+}
+
+
+void unload_opl3sa2_mss(struct address_info *hw_config)
+{
+        int mixer;
+
+        /* Find mixer */
+	mixer = audio_devs[hw_config->slots[0]]->mixer_dev;
+
+        /* Unload MSS audio codec */
+	unload_ms_sound(hw_config);
+
+	sound_unload_audiodev(hw_config->slots[0]);
+
+        /* Unload mixer if there */
+	if(mixer >= 0)
+	{
+		sound_unload_mixerdev(mixer);
+	}
+
+        /* Release MSS config ports */
+	release_region(hw_config->io_base, 4);
+}
+
+
+int probe_opl3sa2(struct address_info *hw_config)
+{
+	/*
+	 * Verify that the I/O port range is free.
+	 */
+
+	printk(KERN_INFO "opl3sa2.c: Control using I/O port 0x%03x\n", hw_config->io_base);
+
+	if (check_region(hw_config->io_base, 2))
+	{
+	    printk(KERN_ERR "opl3sa2.c: Control I/O port 0x%03x not free\n", hw_config->io_base);
+	    return 0;
+	}
+
+	/* GSM!: Add some kind of other test here... */
+
+	return 1;
+}
+
+
+void attach_opl3sa2(struct address_info *hw_config)
+{
+   	printk(KERN_INFO "opl3sa2.c: trying to init!\n");   
+   
+   	request_region(hw_config->io_base, 2, "Yamaha 7xx Control");
+
+	/* GSM! Mixer stuff should go here... */
+}   
+
+
+void unload_opl3sa2(struct address_info *hw_config)
+{
+        /* Release control ports */
+	release_region(hw_config->io_base, 2);
+
+	/* GSM! Mixer stuff should go here... */
+}
+
+
+#ifdef MODULE
+
+int io      = -1;
+int mss_io  = -1;
+int mpu_io  = -1;
+int irq     = -1;
+int dma     = -1;
+int dma2    = -1;
+
+MODULE_PARM(io,"i");
+MODULE_PARM(mss_io,"i");
+MODULE_PARM(mpu_io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(dma2,"i");
+
+EXPORT_NO_SYMBOLS;
+
+struct address_info cfg;
+struct address_info mss_cfg;
+struct address_info mpu_cfg;
+
+/*
+ *	Install a OPL3SA2 based card. Need to have ad1848 and mpu401
+ *	loaded ready.
+ */
+int init_module(void)
+{
+        int i;
+
+	if (io == -1 || irq == -1 || dma == -1 || dma2 == -1 || mss_io == -1)
+	{
+		printk(KERN_ERR "opl3sa2: io, mss_io, irq, dma, and dma2 must be set.\n");
+		return -EINVAL;
+	}
+   
+        /* Our own config: */
+        cfg.io_base = io;
+	cfg.irq     = irq;
+	cfg.dma     = dma;
+	cfg.dma2    = dma2;
+
+        /* The MSS config: */
+	mss_cfg.io_base      = mss_io;
+	mss_cfg.irq          = irq;
+	mss_cfg.dma          = dma;
+	mss_cfg.dma2         = dma2;
+	mss_cfg.card_subtype = 1;      /* No IRQ or DMA setup */
+
+	/* Call me paranoid: */
+	for(i = 0; i < 6; i++)
+	{
+	    cfg.slots[i] = mss_cfg.slots[i] = mpu_cfg.slots[i] = -1;
+	}
+
+	if (probe_opl3sa2(&cfg) == 0)
+	{
+	    return -ENODEV;
+	}
+	attach_opl3sa2(&cfg);
+
+	if (probe_opl3sa2_mss(&mss_cfg) == 0)
+	{
+	    return -ENODEV;
+	}
+	attach_opl3sa2_mss(&mss_cfg);
+
+#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
+	if(mpu_io != -1)
+	{
+            /* MPU config: */
+	    mpu_cfg.io_base       = mpu_io;
+	    mpu_cfg.irq           = irq;
+	    mpu_cfg.dma           = dma;
+	    mpu_cfg.always_detect = 1;  /* It's there, so use shared IRQs */
+
+	    if (probe_opl3sa2_mpu(&mpu_cfg))
+	    {
+	        attach_opl3sa2_mpu(&mpu_cfg);
+	    }
+	}
+#endif
+	SOUND_LOCK;
+	return 0;
+}
+
+
+void cleanup_module(void)
+{
+#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
+        if(mpu_cfg.slots[1] != -1)
+	{
+            unload_opl3sa2_mpu(&mpu_cfg);
+	}
+#endif
+	unload_opl3sa2_mss(&mss_cfg);
+	unload_opl3sa2(&cfg);
+	SOUND_LOCK_END;
+}
+
+#endif
+#endif
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb.h linux/drivers/sound/sb.h
--- v2.1.125/linux/drivers/sound/sb.h	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/sb.h	Sat Oct 17 15:33:46 1998
@@ -87,15 +87,20 @@
 
 	/* State variables */
  	   int opened;
+    /* new audio fields for full duplex support */
+       int fullduplex;
+       int duplex;
 	   int speed, bits, channels;
 	   volatile int irq_ok;
 	   volatile int intr_active, irq_mode;
+    /* duplicate audio fields for full duplex support */
+	   volatile int intr_active_2, irq_mode_2;
 
 	/* Mixer fields */
 	   int *levels;
 	   mixer_tab *iomap;
-	   int mixer_caps, recmask, supported_devices;
-	   int supported_rec_devices;
+	   int mixer_caps, recmask, outmask, supported_devices;
+	   int supported_rec_devices, supported_out_devices;
 	   int my_mixerdev;
 	   int sbmixnum;
 
@@ -105,6 +110,13 @@
 	   int      trg_bytes;
 	   int      trg_intrflag;
 	   int      trg_restart;
+    /* duplicate audio fields for full duplex support */
+	   unsigned long trg_buf_2;
+	   int      trigger_bits_2;
+	   int      trg_bytes_2;
+	   int      trg_intrflag_2;
+	   int      trg_restart_2;
+
 	   unsigned char tconst;
 	   int my_dev;
 	
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_audio.c linux/drivers/sound/sb_audio.c
--- v2.1.125/linux/drivers/sound/sb_audio.c	Thu Jul 16 18:09:27 1998
+++ linux/drivers/sound/sb_audio.c	Sat Oct 17 15:33:46 1998
@@ -15,6 +15,10 @@
  *
  * Status
  *	Mostly working. Weird uart bug causing irq storms
+ *
+ * Daniel J. Rodriksson: Changes to make sb16 work full duplex.
+ *                       Maybe other 16 bit cards in this code could behave
+ *                       the same.
  */
 
 #include <linux/config.h>
@@ -47,7 +51,7 @@
 		  restore_flags(flags);
 		  return -EBUSY;
 	}
-	if (devc->dma16 != -1 && devc->dma16 != devc->dma8)
+    if (devc->dma16 != -1 && devc->dma16 != devc->dma8 && !devc->duplex)
 	{
 		if (sound_open_dma(devc->dma16, "Sound Blaster 16 bit"))
 		{
@@ -59,6 +63,10 @@
 	restore_flags(flags);
 
 	devc->irq_mode = IMODE_NONE;
+    devc->irq_mode_2 = IMODE_NONE;
+    devc->intr_active_2 = 0;
+    devc->fullduplex = devc->duplex &&
+        ((mode & OPEN_READ) && (mode & OPEN_WRITE));
 	sb_dsp_reset(devc);
 
 	/* The ALS007 seems to require that the DSP be removed from the output */
@@ -84,9 +92,11 @@
 {
 	sb_devc *devc = audio_devs[dev]->devc;
 
-	audio_devs[dev]->dmap_in->dma = audio_devs[dev]->dmap_out->dma = devc->dma8;
+    audio_devs[dev]->dmap_out->dma = devc->dma8;
+    audio_devs[dev]->dmap_in->dma = ( devc->duplex ) ?
+        devc->dma16 : devc->dma8;
 
-	if (devc->dma16 != -1 && devc->dma16 != devc->dma8)
+    if (devc->dma16 != -1 && devc->dma16 != devc->dma8 && !devc->duplex)
 		sound_close_dma(devc->dma16);
 
 	/* For ALS007, turn DSP output back on if closing the device for read */
@@ -104,20 +114,34 @@
 {
 	sb_devc *devc = audio_devs[dev]->devc;
 
-	devc->trg_buf = buf;
-	devc->trg_bytes = nr_bytes;
-	devc->trg_intrflag = intrflag;
-	devc->irq_mode = IMODE_OUTPUT;
+    if( !devc->fullduplex || devc->bits == AFMT_S16_LE) {
+        devc->trg_buf = buf;
+        devc->trg_bytes = nr_bytes;
+        devc->trg_intrflag = intrflag;
+        devc->irq_mode = IMODE_OUTPUT;
+    } else {
+        devc->trg_buf_2 = buf;
+        devc->trg_bytes_2 = nr_bytes;
+        devc->trg_intrflag_2 = intrflag;
+        devc->irq_mode_2 = IMODE_OUTPUT;
+    }
 }
 
 static void sb_set_input_parms(int dev, unsigned long buf, int count, int intrflag)
 {
 	sb_devc *devc = audio_devs[dev]->devc;
 
-	devc->trg_buf = buf;
-	devc->trg_bytes = count;
-	devc->trg_intrflag = intrflag;
-	devc->irq_mode = IMODE_INPUT;
+    if( !devc->fullduplex || devc->bits != AFMT_S16_LE) {
+        devc->trg_buf = buf;
+        devc->trg_bytes = count;
+        devc->trg_intrflag = intrflag;
+        devc->irq_mode = IMODE_INPUT;
+    } else {
+        devc->trg_buf_2 = buf;
+        devc->trg_bytes_2 = count;
+        devc->trg_intrflag_2 = intrflag;
+        devc->irq_mode_2 = IMODE_INPUT;
+    }
 }
 
 /*
@@ -830,9 +854,17 @@
 {
 	sb_devc *devc = audio_devs[dev]->devc;
 
-	audio_devs[dev]->dmap_out->dma =
-	    audio_devs[dev]->dmap_in->dma =
-	    devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8;
+    if( !devc->fullduplex) {
+        audio_devs[dev]->dmap_out->dma =
+            audio_devs[dev]->dmap_in->dma =
+            devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8;
+    } else if( devc->bits == AFMT_S16_LE) {
+        audio_devs[dev]->dmap_out->dma = devc->dma8;
+        audio_devs[dev]->dmap_in->dma = devc->dma16;
+    } else {
+        audio_devs[dev]->dmap_out->dma = devc->dma16;
+        audio_devs[dev]->dmap_in->dma = devc->dma8;
+    }
 
 	devc->trigger_bits = 0;
 	return 0;
@@ -842,8 +874,17 @@
 {
 	sb_devc *devc = audio_devs[dev]->devc;
 
-	audio_devs[dev]->dmap_out->dma = audio_devs[dev]->dmap_in->dma =
-			devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8;
+    if( !devc->fullduplex) {
+        audio_devs[dev]->dmap_out->dma =
+            audio_devs[dev]->dmap_in->dma =
+            devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8;
+    } else if( devc->bits == AFMT_S16_LE) {
+        audio_devs[dev]->dmap_out->dma = devc->dma8;
+        audio_devs[dev]->dmap_in->dma = devc->dma16;
+    } else {
+        audio_devs[dev]->dmap_out->dma = devc->dma16;
+        audio_devs[dev]->dmap_in->dma = devc->dma8;
+    }
 
 	devc->trigger_bits = 0;
 	return 0;
@@ -854,9 +895,23 @@
 {
 	unsigned long   flags, cnt;
 	sb_devc        *devc = audio_devs[dev]->devc;
+    unsigned long   bits;
 
-	devc->irq_mode = IMODE_OUTPUT;
-	devc->intr_active = 1;
+    if( !devc->fullduplex || devc->bits == AFMT_S16_LE) {
+        devc->irq_mode = IMODE_OUTPUT;
+        devc->intr_active = 1;
+    } else {
+        devc->irq_mode_2 = IMODE_OUTPUT;
+        devc->intr_active_2 = 1;
+    }
+
+    /* save value */
+    save_flags (flags);
+    cli ();
+    bits = devc->bits;
+    if( devc->fullduplex)
+        devc->bits = (devc->bits == AFMT_S16_LE) ? AFMT_U8 : AFMT_S16_LE;
+    restore_flags (flags);
 
 	cnt = count;
 	if (devc->bits == AFMT_S16_LE)
@@ -878,6 +933,8 @@
 	sb_dsp_command(devc, (unsigned char) (cnt & 0xff));
 	sb_dsp_command(devc, (unsigned char) (cnt >> 8));
 
+    /* restore real value after all programming */
+    devc->bits = bits;
 	restore_flags(flags);
 }
 
@@ -886,8 +943,13 @@
 	unsigned long   flags, cnt;
 	sb_devc        *devc = audio_devs[dev]->devc;
 
-	devc->irq_mode = IMODE_INPUT;
-	devc->intr_active = 1;
+    if( !devc->fullduplex || devc->bits != AFMT_S16_LE) {
+        devc->irq_mode = IMODE_INPUT;
+        devc->intr_active = 1;
+    } else {
+        devc->irq_mode_2 = IMODE_INPUT;
+        devc->intr_active_2 = 1;
+    }
 
 	cnt = count;
 	if (devc->bits == AFMT_S16_LE)
@@ -916,29 +978,125 @@
 {
 	sb_devc *devc = audio_devs[dev]->devc;
 
+    int bits_2 = bits & devc->irq_mode_2;
 	bits &= devc->irq_mode;
 
 	if (!bits)
 		sb_dsp_command(devc, 0xd0);	/* Halt DMA */
 	else
 	{
-		switch (devc->irq_mode)
-		{
-			case IMODE_INPUT:
-				sb16_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
-					devc->trg_intrflag);
-				break;
-
-			case IMODE_OUTPUT:
-				sb16_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
-					devc->trg_intrflag);
-				break;
-		}
-	}
-
-	devc->trigger_bits = bits;
+        if( bits) {
+            switch (devc->irq_mode)
+            {
+       			case IMODE_INPUT:
+                    sb16_audio_start_input(dev, devc->trg_buf,
+                                           devc->trg_bytes,
+                                           devc->trg_intrflag);
+                    break;
+
+			    case IMODE_OUTPUT:
+                    sb16_audio_output_block(dev, devc->trg_buf,
+                                            devc->trg_bytes,
+                                            devc->trg_intrflag);
+                    break;
+            }
+        }
+        if( bits_2) {
+            switch (devc->irq_mode_2)
+            {
+                case IMODE_INPUT:
+                    sb16_audio_start_input (dev, devc->trg_buf_2,
+                                            devc->trg_bytes_2,
+                                            devc->trg_intrflag_2);
+                    break;
+                case IMODE_OUTPUT:
+                    sb16_audio_output_block (dev, devc->trg_buf_2,
+                                             devc->trg_bytes_2,
+                                             devc->trg_intrflag_2);
+                    break;
+            }
+        }
+	}
+
+	devc->trigger_bits = bits | bits_2;
+}
+
+static unsigned char lbuf8[2048];
+static signed short *lbuf16 = (signed short *)lbuf8;
+#define LBUFCOPYSIZE 1024
+static void
+sb16_copy_from_user( int dev,
+                     char *localbuf, int localoffs,
+                     const char *userbuf, int useroffs,
+                     int max_in, int max_out,
+                     int *used, int *returned,
+                     int len)
+{
+  sb_devc        *devc = audio_devs[dev]->devc;
+  int i, c, p, locallen;
+  unsigned char *buf8;
+  signed short *buf16;
+
+  /* if not duplex no conversion */
+  if( !devc->fullduplex) {
+    copy_from_user( localbuf + localoffs, userbuf + useroffs, len);
+    *used = len;
+    *returned = len;
+  } else if( devc->bits == AFMT_S16_LE) {
+    /* 16 -> 8 */
+    /* max_in >> 1, max number of samples in ( 16 bits ) */
+    /* max_out, max number of samples out ( 8 bits ) */
+    /* len, number of samples that will be taken ( 16 bits )*/
+    /* c, count of samples remaining in buffer ( 16 bits )*/
+    /* p, count of samples already processed ( 16 bits )*/
+    len = ( (max_in >> 1) > max_out) ? max_out : (max_in >> 1);
+    c = len;
+    p = 0;
+    buf8 = (unsigned char *)(localbuf + localoffs);
+    while( c) {
+      locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
+      /* << 1 in order to get 16 bit samples */
+      copy_from_user( lbuf16,
+                 userbuf+useroffs + (p << 1),
+                 locallen << 1);
+      for( i = 0; i < locallen; i++) {
+        buf8[p+i] = ~((lbuf16[i] >> 8) & 0xff) ^ 0x80;
+      }
+      c -= locallen; p += locallen;
+    }
+    /* used = ( samples * 16 bits size ) */
+    *used = len << 1;
+    /* returned = ( samples * 8 bits size ) */
+    *returned = len;
+  } else {
+    /* 8 -> 16 */
+    /* max_in, max number of samples in ( 8 bits ) */
+    /* max_out >> 1, max number of samples out ( 16 bits ) */
+    /* len, number of samples that will be taken ( 8 bits )*/
+    /* c, count of samples remaining in buffer ( 8 bits )*/
+    /* p, count of samples already processed ( 8 bits )*/
+    len = max_in > (max_out >> 1) ? (max_out >> 1) : max_in;
+    c = len;
+    p = 0;
+    buf16 = (signed short *)(localbuf + localoffs);
+    while( c) {
+      locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
+      copy_from_user( lbuf8,
+                 userbuf+useroffs + p,
+                 locallen);
+      for( i = 0; i < locallen; i++) {
+        buf16[p+i] = (~lbuf8[i] ^ 0x80) << 8;
+      }
+      c -= locallen; p += locallen;
+    }
+    /* used = ( samples * 8 bits size ) */
+    *used = len;
+    /* returned = ( samples * 16 bits size ) */
+    *returned = len << 1;
+  }
 }
 
+
 static struct audio_driver sb1_audio_driver =	/* SB1.x */
 {
 	sb_audio_open,
@@ -1050,7 +1208,7 @@
 	sb16_audio_prepare_for_output,
 	sb1_audio_halt_xfer,
 	NULL,			/* local_qlen */
-	NULL,			/* copy_from_user */
+	sb16_copy_from_user,			/* copy_from_user */
 	NULL,
 	NULL,
 	sb16_audio_trigger,
@@ -1086,6 +1244,7 @@
 
 	struct audio_driver *driver = &sb1_audio_driver;
 
+    devc->duplex = 0;
 	switch (devc->model)
 	{
 		case MDL_SB1:	/* SB1.0 or SB 1.5 */
@@ -1124,6 +1283,10 @@
 			DDB(printk("Will use SB16 driver\n"));
 			audio_flags = DMA_AUTOMODE;
 			format_mask |= AFMT_S16_LE;
+            if( devc->dma8 != devc->dma16 && devc->dma16 != -1) {
+                audio_flags |= DMA_DUPLEX;
+                devc->duplex = 1;
+            }
 			driver = &sb16_audio_driver;
 			break;
 
@@ -1136,7 +1299,9 @@
 	if ((devc->my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
 				name,driver, sizeof(struct audio_driver),
 				audio_flags, format_mask, devc,
-				devc->dma8, devc->dma8)) < 0)
+				devc->dma8,
+                (devc->dma8 != devc->dma16 && devc->dma16 != -1)
+                     ? devc->dma16 : devc->dma8)) < 0)
 	{
 		  printk(KERN_ERR "Sound Blaster:  unable to install audio.\n");
 		  return;
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- v2.1.125/linux/drivers/sound/sb_common.c	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/sb_common.c	Sat Oct 17 15:33:46 1998
@@ -10,7 +10,10 @@
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
  */
-
+/*
+ * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts
+ *                       for full duplex support ( only sb16 by now )
+ */
 #include <linux/config.h>
 #include <linux/delay.h>
 #include <asm/init.h>
@@ -140,7 +143,7 @@
 		if (!(src & 3))
 			return;	/* Not a DSP interrupt */
 	}
-	if (devc->intr_active)
+	if (devc->intr_active && (!devc->fullduplex || (src & 0x01)))
 	{
 		switch (devc->irq_mode)
 		{
@@ -165,7 +168,17 @@
 				/* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */
 				;
 		}
-	}
+    } else if (devc->intr_active_2 && (src & 0x02)) {
+        switch (devc->irq_mode_2)
+        {
+            case IMODE_OUTPUT:
+                DMAbuf_outputintr (devc->dev, 1);
+                break;
+            case IMODE_INPUT:
+                DMAbuf_inputintr (devc->dev);
+                break;
+        }
+    }
 	/*
 	 * Acknowledge interrupts 
 	 */
@@ -954,8 +967,7 @@
 		if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && devc->irq > 0)
 		{
 			free_irq(devc->irq, devc);
-			if (devc->my_mixerdev)
-				sound_unload_mixerdev(devc->my_mixerdev);
+			sound_unload_mixerdev(devc->my_mixerdev);
 			/* We don't have to do this bit any more the UART401 is its own
 				master  -- Krzysztof Halasa */
 			/* But we have to do it, if UART401 is not detected */
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c
--- v2.1.125/linux/drivers/sound/sb_mixer.c	Thu Sep 17 17:53:37 1998
+++ linux/drivers/sound/sb_mixer.c	Sat Oct 17 15:33:46 1998
@@ -294,6 +294,39 @@
 	return devc->recmask;
 }
 
+static int set_outmask(sb_devc * devc, int mask)
+{
+	int devmask, i;
+	unsigned char  regimage;
+
+	devmask = mask & devc->supported_out_devices;
+
+	switch (devc->model)
+	{
+		case MDL_SB16:
+			if (devc->submodel == SUBMDL_ALS007) 
+				break;
+			else
+			{
+				regimage = 0;
+				for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+				{
+					if ((1 << i) & devmask)
+					{
+						regimage |= (sb16_recmasks_L[i] | sb16_recmasks_R[i]);
+					}
+					sb_setmixer (devc, SB16_OMASK, regimage);
+				}
+			}
+			break;
+		default:
+			break;
+	}
+
+	devc->outmask = devmask;
+	return devc->outmask;
+}
+
 static int sb_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
 {
 	sb_devc *devc = mixer_devs[dev]->devc;
@@ -321,6 +354,10 @@
 					ret = set_recmask(devc, val);
 					break;
 
+				case SOUND_MIXER_OUTSRC:
+					ret = set_outmask(devc, val);
+					break;
+
 				default:
 					ret = sb_mixer_set(devc, cmd & 0xff, val);
 			}
@@ -331,6 +368,10 @@
 				ret = devc->recmask;
 				break;
 				  
+			case SOUND_MIXER_OUTSRC:
+				ret = devc->outmask;
+				break;
+				  
 			case SOUND_MIXER_DEVMASK:
 				ret = devc->supported_devices;
 				break;
@@ -348,6 +389,10 @@
 				ret = devc->supported_rec_devices;
 				break;
 				  
+			case SOUND_MIXER_OUTMASK:
+				ret = devc->supported_out_devices;
+				break;
+				  
 			case SOUND_MIXER_CAPS:
 				ret = devc->mixer_caps;
 				break;
@@ -435,6 +480,7 @@
 		case MDL_SB16:
 			devc->mixer_caps = 0;
 			devc->supported_rec_devices = SB16_RECORDING_DEVICES;
+			devc->supported_out_devices = SB16_OUTFILTER_DEVICES;
 			if (devc->submodel != SUBMDL_ALS007)
 			{
 				devc->supported_devices = SB16_MIXER_DEVICES;
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_mixer.h linux/drivers/sound/sb_mixer.h
--- v2.1.125/linux/drivers/sound/sb_mixer.h	Thu May 14 19:47:42 1998
+++ linux/drivers/sound/sb_mixer.h	Sat Oct 17 15:33:46 1998
@@ -41,6 +41,9 @@
 #define SB16_RECORDING_DEVICES		(SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \
 					 SOUND_MASK_CD)
 
+#define SB16_OUTFILTER_DEVICES		(SOUND_MASK_LINE | SOUND_MASK_MIC | \
+					 SOUND_MASK_CD)
+
 #define ES688_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
 #define ES688_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_LINE2|SOUND_MASK_SPEAKER)
 
@@ -99,6 +102,7 @@
 /*
  * Mixer registers of SB16
  */
+#define SB16_OMASK	0x3c
 #define SB16_IMASK_L	0x3d
 #define SB16_IMASK_R	0x3e
 
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sgalaxy.c linux/drivers/sound/sgalaxy.c
--- v2.1.125/linux/drivers/sound/sgalaxy.c	Tue Jun  9 11:57:30 1998
+++ linux/drivers/sound/sgalaxy.c	Sat Oct 17 15:33:46 1998
@@ -93,7 +93,7 @@
 	}
         
 	if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
-		return 1;	       /* The card is already active */
+		return probe_ms_sound(ai);  /* The card is already active, check irq etc... */
 
 	if ( check_region( ai->ai_sgbase, 0x10 ) )
 	{
diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sound_calls.h linux/drivers/sound/sound_calls.h
--- v2.1.125/linux/drivers/sound/sound_calls.h	Tue Jul 21 00:15:31 1998
+++ linux/drivers/sound/sound_calls.h	Fri Oct  9 11:56:59 1998
@@ -251,6 +251,8 @@
 void unload_trix_mpu(struct address_info *hw_info);
 void unload_cs4232(struct address_info *hw_info);
 void unload_cs4232_mpu(struct address_info *hw_info);
+void unload_opl3sa2(struct address_info *hw_info);
+void unload_opl3sa2_mpu(struct address_info *hw_info);
 
 /* From cs4232.c */
 
@@ -258,6 +260,12 @@
 void attach_cs4232 (struct address_info *hw_config);
 int probe_cs4232_mpu (struct address_info *hw_config);
 void attach_cs4232_mpu (struct address_info *hw_config);
+
+/* From opl3sa2.c */
+int probe_opl3sa2 (struct address_info *hw_config);
+void attach_opl3sa2 (struct address_info *hw_config);
+int probe_opl3sa2_mpu (struct address_info *hw_config);
+void attach_opl3sa2_mpu (struct address_info *hw_config);
 
 /*	From maui.c */
 void attach_maui(struct address_info * hw_config);
diff -u --recursive --new-file v2.1.125/linux/drivers/video/Config.in linux/drivers/video/Config.in
--- v2.1.125/linux/drivers/video/Config.in	Mon Oct  5 13:13:40 1998
+++ linux/drivers/video/Config.in	Thu Oct 15 15:24:18 1998
@@ -71,6 +71,14 @@
       bool '  Leo (ZX) support' CONFIG_FB_LEO
     fi
   fi
+  if [ "$ARCH" = "sparc" ]; then
+    if [ "$CONFIG_PCI" != "n" ]; then
+      bool 'PCI framebuffers' CONFIG_FB_PCI
+      if [ "$CONFIG_FB_PCI" != "n" ]; then
+        bool '  IGA 168x display support' CONFIG_FB_IGA
+      fi
+    fi
+  fi
   if [ "$ARCH" = "sparc64" ]; then
     if [ "$CONFIG_PCI" != "n" ]; then
       bool 'PCI framebuffers' CONFIG_FB_PCI
@@ -133,7 +141,8 @@
 	 "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
 	 "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
 	 "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \
-	 "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" ]; then
+	 "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
+         "$CONFIG_FB_IGA" = "y" ]; then
       define_bool CONFIG_FBCON_CFB8 y
     else
       if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
@@ -143,7 +152,8 @@
 	   "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
 	   "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
 	   "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \
-	   "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" ]; then
+	   "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
+           "$CONFIG_FB_IGA" = "y" ]; then
 	define_bool CONFIG_FBCON_CFB8 m
       fi
     fi
diff -u --recursive --new-file v2.1.125/linux/drivers/video/Makefile linux/drivers/video/Makefile
--- v2.1.125/linux/drivers/video/Makefile	Mon Oct  5 13:13:40 1998
+++ linux/drivers/video/Makefile	Thu Oct 15 15:24:18 1998
@@ -95,6 +95,10 @@
 L_OBJS += atyfb.o
 endif
 
+ifeq ($(CONFIG_FB_IGA),y)
+L_OBJS += igafb.o
+endif
+
 ifeq ($(CONFIG_FB_CONTROL),y)
 L_OBJS += controlfb.o
 endif
@@ -447,7 +451,7 @@
 
 include $(TOPDIR)/Rules.make
 
-promcon_tbl.c: prom.uni
+promcon_tbl.c: prom.uni ../char/conmakehash
 	../char/conmakehash prom.uni | \
 	sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
 	    -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > promcon_tbl.c
diff -u --recursive --new-file v2.1.125/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.1.125/linux/drivers/video/atyfb.c	Mon Oct  5 13:13:41 1998
+++ linux/drivers/video/atyfb.c	Thu Oct 15 15:24:18 1998
@@ -1,4 +1,4 @@
-/*  $Id: atyfb.c,v 1.77 1998/09/14 08:01:46 jj Exp $
+/*  $Id: atyfb.c,v 1.81 1998/10/14 16:45:38 ecd Exp $
  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
  *
  *	Copyright (C) 1997-1998  Geert Uytterhoeven
@@ -28,6 +28,8 @@
 
     - cursor support on all cards and all ramdacs.
     - cursor parameters controlable via ioctl()s.
+    - guess PLL and MCLK based on the original PLL register values initialized
+      by the BIOS or Open Firmware (if they are initialized).
 
 						(Anyone to help with this?)
 
@@ -60,7 +62,7 @@
 
 #include <asm/io.h>
 
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <video/macmodes.h>
@@ -83,7 +85,7 @@
 /*
  * Debug flags.
  */
-#undef PLL_DEBUG
+#undef DEBUG
 
 
 #define GUI_RESERVE	0x00001000
@@ -322,7 +324,7 @@
 			const struct fb_info_aty *info);
 static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info);
 static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
-#ifdef PLL_DEBUG
+#if defined(__sparc__) || defined(DEBUG)
 static u8 aty_ld_pll(int offset, const struct fb_info_aty *info);
 #endif
 static void aty_set_crtc(const struct fb_info_aty *info,
@@ -366,7 +368,7 @@
 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			 u_int transp, struct fb_info *fb);
 static void do_install_cmap(int con, struct fb_info *info);
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
 static int read_aty_sense(const struct fb_info_aty *info);
 #endif
 
@@ -401,7 +403,7 @@
 
 static const u32 ref_clk_per = 1000000000000ULL/14318180;
 
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
 #endif
@@ -445,6 +447,14 @@
     { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)" },
 };
 
+static const char *aty_gx_ram[8] __initdata = {
+    "DRAM", "VRAM", "VRAM", "DRAM", "GDRAM", "EVRAM", "EVRAM", "RESV"
+};
+
+static const char *aty_ct_ram[8] __initdata = {
+    "OFF", "DRAM", "EDO", "HPDRAM", "SDRAM", "SGRAM", "WRAM", "RESV"
+};
+
 
 static inline u32 aty_ld_le32(volatile unsigned int regindex,
 			      const struct fb_info_aty *info)
@@ -670,7 +680,7 @@
     aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
 }
 
-#ifdef PLL_DEBUG
+#if defined(__sparc__) || defined(DEBUG)
 static u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
 {
     u8 res;
@@ -685,7 +695,7 @@
 }
 #endif
 
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
 
     /*
      *  Apple monitor sense
@@ -725,7 +735,7 @@
     return sense;
 }
 
-#endif /* defined(CONFIG_PMAC) || defined(CONFIG_CHRP) */
+#endif /* defined(CONFIG_PPC) */
 
 /* ------------------------------------------------------------------------- */
 
@@ -2289,6 +2299,78 @@
 	}
 	return 0;
 }
+
+static struct {
+	u32	yoffset;
+	u8	r[2][256];
+	u8	g[2][256];
+	u8	b[2][256];
+} atyfb_save;
+
+static void atyfb_save_palette(struct fb_info *fb, int enter)
+{
+	struct fb_info_aty *info = (struct fb_info_aty *)fb;
+	int i, tmp, scale;
+
+	for (i = 0; i < 256; i++) {
+		tmp = aty_ld_8(DAC_CNTL, info) & 0xfc;
+		if ((Gx == GT_CHIP_ID) || (Gx == GU_CHIP_ID) ||
+		    (Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) ||
+		    (Gx == GD_CHIP_ID) || (Gx == GI_CHIP_ID) ||
+		    (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID))
+			tmp |= 0x2;
+		aty_st_8(DAC_CNTL, tmp, info);
+		aty_st_8(DAC_REGS + DAC_MASK, 0xff, info);
+		eieio();
+		scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
+			(info->current_par.crtc.bpp == 16)) ? 3 : 0;
+		info->aty_cmap_regs->rindex = i << scale;
+		eieio();
+		atyfb_save.r[enter][i] = info->aty_cmap_regs->lut;
+		eieio();
+		atyfb_save.g[enter][i] = info->aty_cmap_regs->lut;
+		eieio();
+		atyfb_save.b[enter][i] = info->aty_cmap_regs->lut;
+		eieio();
+		info->aty_cmap_regs->windex = i << scale;
+		eieio();
+		info->aty_cmap_regs->lut = atyfb_save.r[1-enter][i];
+		eieio();
+		info->aty_cmap_regs->lut = atyfb_save.g[1-enter][i];
+		eieio();
+		info->aty_cmap_regs->lut = atyfb_save.b[1-enter][i];
+		eieio();
+	}
+}
+
+static void atyfb_palette(int enter)
+{
+	struct fb_info_aty *info;
+	struct atyfb_par *par;
+	struct display *d;
+	int i;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		d = &fb_display[i];
+		if (d->fb_info &&
+		    d->fb_info->fbops == &atyfb_ops &&
+		    d->fb_info->display_fg &&
+		    d->fb_info->display_fg->vc_num == i) {
+			atyfb_save_palette(d->fb_info, enter);
+			info = (struct fb_info_aty *)d->fb_info;
+			par = &info->current_par;
+			if (enter) {
+				atyfb_save.yoffset = par->crtc.yoffset;
+				par->crtc.yoffset = 0;
+				set_off_pitch(par, info);
+			} else {
+				par->crtc.yoffset = atyfb_save.yoffset;
+				set_off_pitch(par, info);
+			}
+			break;
+		}
+	}
+}
 #endif /* __sparc__ */
 
     /*
@@ -2302,9 +2384,9 @@
     int j, k;
     struct fb_var_screeninfo var;
     struct display *disp;
-    const char *chipname = NULL;
+    const char *chipname = NULL, *ramname = NULL;
     int pll, mclk;
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
     int sense;
 #endif
 
@@ -2325,6 +2407,7 @@
     if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
 	info->bus_type = (aty_ld_le32(CONFIG_STAT0, info) >> 0) & 0x07;
 	info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) >> 3) & 0x07;
+	ramname = aty_gx_ram[info->ram_type];
 	/* FIXME: clockchip/RAMDAC probing? */
 #ifdef CONFIG_ATARI
 	info->dac_type = DAC_ATI68860_B;
@@ -2339,6 +2422,7 @@
     } else {
 	info->bus_type = PCI;
 	info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
+	ramname = aty_ct_ram[info->ram_type];
 	info->dac_type = DAC_INTERNAL;
 	info->clk_type = CLK_INTERNAL;
 	if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
@@ -2454,17 +2538,34 @@
 	  info->total_vram += 0x400000;
     }
 
-    printk("%d%c %d MHz PLL, %d Mhz MCLK\n", 
+    printk("%d%c %s, %d MHz PLL, %d Mhz MCLK\n", 
     	   info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20), 
-    	   info->total_vram == 0x80000 ? 'K' : 'M', pll, mclk);
-    
+    	   info->total_vram == 0x80000 ? 'K' : 'M', ramname, pll, mclk);
+
+#ifdef DEBUG
+    if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
+	int i;
+	printk("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
+	       "DSP_CONFIG DSP_ON_OFF\n"
+	       "%08x %08x %08x %08x     %08x      %08x   %08x\n"
+	       "PLL",
+	       aty_ld_le32(BUS_CNTL, info), aty_ld_le32(DAC_CNTL, info),
+	       aty_ld_le32(MEM_CNTL, info), aty_ld_le32(EXT_MEM_CNTL, info),
+	       aty_ld_le32(CRTC_GEN_CNTL, info), aty_ld_le32(DSP_CONFIG, info),
+	       aty_ld_le32(DSP_ON_OFF, info));
+	for (i = 0; i < 16; i++)
+	    printk(" %02x", aty_ld_pll(i, info));
+	printk("\n");
+    }
+#endif
+
     if (info->bus_type == ISA)
 	if ((info->total_vram == 0x400000) || (info->total_vram == 0x800000)) {
 	    /* protect GUI-regs if complete Aperture is VRAM */
 	    info->total_vram -= GUI_RESERVE;
 	}
 
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
     if (default_vmode == VMODE_NVRAM) {
 	default_vmode = nvram_read_byte(NV_VMODE);
 	if (default_vmode <= 0 || default_vmode > VMODE_MAX)
@@ -2487,9 +2588,9 @@
 	default_cmode = CMODE_8;
     if (mac_vmode_to_var(default_vmode, default_cmode, &var))
 	var = default_var;
-#else /* !CONFIG_PMAC && !CONFIG_CHRP */
+#else /* !CONFIG_PPC */
     var = default_var;
-#endif /* !CONFIG_PMAC && !CONFIG_CHRP */
+#endif /* !CONFIG_PPC */
     if (noaccel)
         var.accel_flags &= ~FB_ACCELF_TEXT;
     else
@@ -2520,6 +2621,9 @@
     info->fb_info.blank = &atyfbcon_blank;
     info->fb_info.flags = FBINFO_FLAG_DEFAULT;
 
+#ifdef __sparc__
+    atyfb_save_palette(&info->fb_info, 0);
+#endif
     for (j = 0; j < 16; j++) {
 	k = color_table[j];
 	info->palette[j].red = default_red[k];
@@ -2555,6 +2659,7 @@
     struct fb_info_aty *info;
     unsigned long addr;
 #ifdef __sparc__
+    extern void (*prom_palette) (int);
     extern int con_is_present(void);
     struct pcidev_cookie *pcp;
     char prop[128];
@@ -2703,6 +2808,9 @@
 		struct fb_var_screeninfo *var = &default_var;
 		u32 v_total, h_total;
 		struct crtc crtc;
+		u8 pll_regs[16];
+		u8 clock_cntl;
+		unsigned int N, P, Q, M, T;
 
 		crtc.vxres = prom_getintdefault(node, "width", 1024);
 		crtc.vyres = prom_getintdefault(node, "height", 768);
@@ -2715,15 +2823,59 @@
 		crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, info);
 		aty_crtc_to_var(&crtc, var);
 
-		/*
-		 * FIXME: Read the PLL to figure actual Refresh Rate.
-		 *        Default to 66Hz for now.
-		 */
 		h_total = var->xres + var->right_margin +
 			  var->hsync_len + var->left_margin;
 		v_total = var->yres + var->lower_margin +
 			  var->vsync_len + var->upper_margin;
-		default_var.pixclock = 1000000000000ULL/(66*h_total*v_total);
+
+		/*
+		 * Read the PLL to figure actual Refresh Rate.
+		 */
+    		clock_cntl = aty_ld_8(CLOCK_CNTL, info);
+		/* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
+		for (i = 0; i < 16; i++) {
+			pll_regs[i] = aty_ld_pll(i, info);
+			/* printk("atyfb: PLL %2d: %02x\n", i, pll_regs[i]); */
+		}
+		/*
+		 * PLL Reference Devider M:
+		 */
+		M = pll_regs[2];
+		/* printk("atyfb: M: %02x\n", M); */
+
+		/*
+		 * PLL Feedback Devider N (Dependant on CLOCK_CNTL):
+		 */
+		N = pll_regs[7 + (clock_cntl & 3)];
+		/* printk("atyfb: N: %02x\n", N); */
+
+		/*
+		 * PLL Post Devider P (Dependant on CLOCK_CNTL):
+		 */
+		P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
+		/* printk("atyfb: P: %2d\n", P); */
+
+		/*
+		 * PLL Devider Q:
+		 */
+		Q = N / P;
+		/* printk("atyfb: Q: %d\n", Q); */
+
+		/*
+		 * Target Frequency:
+		 *
+		 *      T * M
+		 * Q = -------
+		 *      2 * R
+		 *
+		 * where R is XTALIN (= 14318 kHz).
+		 */
+		T = 2 * Q * 14318 / M;
+		/* printk("atyfb: T: %d\n", T); */
+
+		default_var.pixclock =
+			((1000000000000ULL / v_total) * 1000) / (T * h_total);
+		/* printk("atyfb: pixclock: %d\n", default_var.pixclock); */
 	    }
 
 #else /* __sparc__ */
@@ -2764,6 +2916,9 @@
 	    }
 
 #ifdef __sparc__
+	    if (!prom_palette)
+		prom_palette = atyfb_palette;
+
 	    /*
 	     * Add /dev/fb mmap values.
 	     */
@@ -2920,7 +3075,7 @@
 	} else if (!strncmp(this_opt, "noaccel", 7)) {
 		noaccel = 1;
 	}
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
 	else if (!strncmp(this_opt, "vmode:", 6)) {
 	    unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
 	    if (vmode > 0 && vmode <= VMODE_MAX)
diff -u --recursive --new-file v2.1.125/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.1.125/linux/drivers/video/fbcon.c	Fri Oct  9 13:27:12 1998
+++ linux/drivers/video/fbcon.c	Thu Oct 15 15:24:18 1998
@@ -1338,11 +1338,6 @@
     if (resize) {
 	/* reset wrap/pan */
 	p->var.xoffset = p->var.yoffset = p->yscroll = 0;
-	if (!p->dispsw->set_font || 
-	    !p->dispsw->set_font(p, fontwidth(p), fontheight(p))) {
-	    /* Adjust the virtual screen-size to fontheight*rows */
-	    p->var.yres_virtual = (p->var.yres/h)*h;
-	}
 	p->vrows = p->var.yres_virtual/h;
 	updatescrollmode(p);
 	vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
diff -u --recursive --new-file v2.1.125/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.1.125/linux/drivers/video/fbmem.c	Mon Oct  5 13:13:41 1998
+++ linux/drivers/video/fbmem.c	Thu Oct 15 15:24:18 1998
@@ -66,6 +66,8 @@
 extern void offb_setup(char *options, int *ints);
 extern void atyfb_init(void);
 extern void atyfb_setup(char *options, int *ints);
+extern void igafb_init(void);
+extern void igafb_setup(char *options, int *ints);
 extern void imsttfb_init(void);
 extern void dnfb_init(void);
 extern void tgafb_init(void);
@@ -115,6 +117,9 @@
 #endif
 #ifdef CONFIG_FB_ATY
 	{ "atyfb", atyfb_init, atyfb_setup },
+#endif
+#ifdef CONFIG_FB_IGA
+        { "igafb", igafb_init, igafb_setup },
 #endif
 #ifdef CONFIG_FB_IMSTT
 	{ "imsttfb", imsttfb_init, NULL },
diff -u --recursive --new-file v2.1.125/linux/drivers/video/iga.h linux/drivers/video/iga.h
--- v2.1.125/linux/drivers/video/iga.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/iga.h	Thu Oct 15 15:24:18 1998
@@ -0,0 +1,27 @@
+/* $Id: iga.h,v 1.1 1998/10/07 11:36:07 jj Exp $
+ * iga1682.h: Sparc/PCI iga1682 driver constants etc.
+ *
+ * Copyleft 1998 V. Roganov and G. Raiko
+ */
+
+#ifndef _IGA1682_H
+#define _IGA1682_H 1
+
+struct iga1682_info
+{
+    unsigned int total_vram;
+};
+
+#define DAC_W_INDEX                     0x03C8
+#define DAC_DATA                        0x03C9
+#define IGA_EXT_CNTRL                   0x3CE
+#define   IGA_IDX_EXT_BUS_CNTL          0x30
+#define     MEM_SIZE_ALIAS              0x3
+#define     MEM_SIZE_1M                 0x0
+#define     MEM_SIZE_2M                 0x1
+#define     MEM_SIZE_4M                 0x2
+#define     MEM_SIZE_RESERVED           0x3
+#define   IGA_IDX_OVERSCAN_COLOR        0x58
+#define   IGA_IDX_EXT_MEM_2             0x72
+
+#endif /* !(_IGA1682_H) */
diff -u --recursive --new-file v2.1.125/linux/drivers/video/igafb.c linux/drivers/video/igafb.c
--- v2.1.125/linux/drivers/video/igafb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/igafb.c	Fri Oct 16 23:30:21 1998
@@ -0,0 +1,783 @@
+/*
+ *  linux/drivers/video/igafb.c -- Frame buffer device for IGA 1682
+ *
+ *      Copyright (C) 1998  Vladimir Roganov and Gleb Raiko
+ *
+ *  This driver is partly based on the Frame buffer device for ATI Mach64
+ *  and partially on VESA-related code.
+ *
+ *      Copyright (C) 1997-1998  Geert Uytterhoeven
+ *      Copyright (C) 1998  Bernd Harries
+ *      Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+/******************************************************************************
+
+  TODO:
+       Despite of IGA Card has advanced graphic acceleration, 
+       initial version is almost dummy and does not support it.
+       Support for video modes and acceleration must be added
+       together with accelerated X-Windows driver implementation.
+
+                                                (Anyone to help with this?)
+
+       Most important thing at this moment is that we have working
+       JavaEngine1  console & X  with new console interface.
+       
+******************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/selection.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/nvram.h>
+#include <linux/kd.h>
+#include <linux/vt_kern.h>
+
+#include <asm/io.h>
+
+#ifdef __sparc__
+#include <asm/pbm.h>
+#include <asm/pcic.h>
+#endif
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#include "iga.h"
+
+static char igafb_name[16] = "IGA 1682";
+static char fontname[40] __initdata = { 0 };
+
+struct pci_mmap_map {
+    unsigned long voff;
+    unsigned long poff;
+    unsigned long size;
+    unsigned long prot_flag;
+    unsigned long prot_mask;
+};
+
+struct fb_info_iga {
+    struct fb_info fb_info;
+    unsigned long frame_buffer_phys;
+    unsigned long frame_buffer;
+    unsigned long io_base_phys;
+    unsigned long io_base;
+    u32 total_vram;
+    struct pci_mmap_map *mmap_map;
+    struct { u_short blue, green, red, pad; } palette[256];
+    int video_cmap_len;
+    int currcon;
+    struct display disp;
+    struct display_switch dispsw; 
+    union {
+#ifdef FBCON_HAS_CFB16
+	    u16 cfb16[16];  
+#endif
+#ifdef FBCON_HAS_CFB24
+	    u32 cfb24[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+	    u32 cfb32[16];
+#endif
+    } fbcon_cmap;
+#ifdef __sparc__
+    u8 open;
+    u8 mmaped;
+    int vtconsole;
+    int consolecnt;
+#endif
+};
+
+struct fb_var_screeninfo default_var = {
+    /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+    640, 480, 640, 480, 0, 0, 8, 0,
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
+    0, FB_VMODE_NONINTERLACED
+};
+
+#ifdef __sparc__
+struct fb_var_screeninfo default_var_1024x768 __initdata = {
+    /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+    1024, 768, 1024, 768, 0, 0, 8, 0,
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0, 12699, 176, 16, 28, 1, 96, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+struct fb_var_screeninfo default_var_1152x900 __initdata = {
+    /* 1152x900, 76 Hz, Non-Interlaced (110.0 MHz dotclock) */
+    1152, 900, 1152, 900, 0, 0, 8, 0,
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0, 9091, 234, 24, 34, 3, 100, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+struct fb_var_screeninfo default_var_1280x1024 __initdata = {
+    /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
+    1280, 1024, 1280, 1024, 0, 0, 8, 0,
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0, 7408, 248, 16, 38, 1, 144, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+/*
+ *   Memory-mapped I/O functions for Sparc PCI
+ */ 
+static inline unsigned char pci_inb (struct fb_info_iga *info, 
+				     unsigned int reg) 
+{
+	return *(volatile unsigned char*)(info->io_base + reg);
+}
+static inline void pci_outb (struct fb_info_iga *info, unsigned char c,
+			     unsigned int reg) 
+{
+	*(volatile unsigned char*)(info->io_base + reg) = c;
+}
+static inline unsigned int iga_inb(struct fb_info_iga *info,
+				   unsigned int reg, unsigned int idx )
+{
+        pci_outb(info, idx, reg);
+        return pci_inb(info, reg + 1);
+}
+static inline void iga_outb(struct fb_info_iga *info, unsigned char val,
+			    unsigned int reg, unsigned int idx )
+{
+        pci_outb(info, idx, reg);
+        pci_outb(info, val, reg+1);
+}
+
+#endif /* __sparc__ */
+
+/*
+ *  Very important functionality for the JavaEngine1 computer:
+ *  make screen border black (usign special IGA registers) 
+ */
+static void iga_blank_border(struct fb_info_iga *info)
+{
+        int i;
+
+        for (i=0; i < 3; i++) 
+                iga_outb(info, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
+}
+
+
+/*
+ *  Frame buffer device API
+ */
+
+/*
+ * Open/Release the frame buffer device
+ */
+
+static int igafb_open(struct fb_info *info, int user)
+{
+        /*
+         * Nothing, only a usage count for the moment
+         */
+        MOD_INC_USE_COUNT;
+        return(0);
+}
+
+static int igafb_release(struct fb_info *info, int user)
+{
+        MOD_DEC_USE_COUNT;
+        return(0);
+}
+
+static int igafb_update_var(int con, struct fb_info *info)
+{
+        return 0;
+}
+
+static int igafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                         struct fb_info *info)
+{
+        struct fb_info_iga *fb = (struct fb_info_iga*)info;
+
+        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+        strcpy(fix->id, igafb_name);
+
+        fix->smem_start = (char *)fb->frame_buffer;
+        fix->smem_len = fb->total_vram;
+        fix->xpanstep = 0;
+        fix->ypanstep = 0;
+        fix->ywrapstep = 0;
+
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+	fix->line_length = default_var.xres * (default_var.bits_per_pixel/8);
+	fix->visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR
+		                                      : FB_VISUAL_DIRECTCOLOR;
+        return 0;
+}
+
+static int igafb_get_var(struct fb_var_screeninfo *var, int con,
+                         struct fb_info *info)
+{
+        if(con == -1)
+                memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
+        else
+                *var = fb_display[con].var;
+        return 0;
+}
+
+static int igafb_set_var(struct fb_var_screeninfo *var, int con,
+                         struct fb_info *info)
+{
+        memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
+        return 0;
+}
+
+#ifdef __sparc__
+static int igafb_mmap(struct fb_info *info, struct file *file,
+		      struct vm_area_struct *vma)
+{
+	struct fb_info_iga *fb = (struct fb_info_iga *)info;
+	unsigned int size, page, map_size = 0;
+	unsigned long map_offset = 0;
+	int i;
+
+	if (!fb->mmap_map)
+		return -ENXIO;
+
+	size = vma->vm_end - vma->vm_start;
+	if (vma->vm_offset & ~PAGE_MASK)
+		return -ENXIO;
+
+	/* To stop the swapper from even considering these pages. */
+	vma->vm_flags |= (VM_SHM | VM_LOCKED);
+
+	/* Each page, see which map applies */
+	for (page = 0; page < size; ) {
+		map_size = 0;
+		for (i = 0; fb->mmap_map[i].size; i++) {
+			unsigned long start = fb->mmap_map[i].voff;
+			unsigned long end = start + fb->mmap_map[i].size;
+			unsigned long offset = vma->vm_offset + page;
+
+			if (start > offset)
+				continue;
+			if (offset >= end)
+				continue;
+
+			map_size = fb->mmap_map[i].size - (offset - start);
+			map_offset = fb->mmap_map[i].poff + (offset - start);
+			break;
+		}
+		if (!map_size) {
+			page += PAGE_SIZE;
+			continue;
+		}
+		if (page + map_size > size)
+			map_size = size - page;
+
+		pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
+		pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
+
+		if (remap_page_range(vma->vm_start + page, map_offset,
+				     map_size, vma->vm_page_prot))
+			return -EAGAIN;
+
+		page += map_size;
+	}
+
+	if (!map_size)
+		return -EINVAL;
+
+	vma->vm_file = file;
+	file->f_count++;
+	vma->vm_flags |= VM_IO;
+
+	if (!fb->mmaped) {
+		int lastconsole = 0;
+
+		if (info->display_fg)
+			lastconsole = info->display_fg->vc_num;
+		fb->mmaped = 1;
+		if (fb->consolecnt && fb_display[lastconsole].fb_info ==info) {
+			fb->vtconsole = lastconsole;
+			vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
+		}
+	}
+	return 0;
+}
+#endif /* __sparc__ */
+
+
+static int iga_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+                          unsigned *blue, unsigned *transp,
+                          struct fb_info *fb_info)
+{
+        /*
+         *  Read a single color register and split it into colors/transparent.
+         *  Return != 0 for invalid regno.
+         */
+	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
+
+        if (regno >= info->video_cmap_len)
+                return 1;
+
+	*red    = info->palette[regno].red;
+	*green  = info->palette[regno].green;
+	*blue   = info->palette[regno].blue;
+	*transp = 0;
+	return 0;
+}
+
+static int iga_setcolreg(unsigned regno, unsigned red, unsigned green,
+                          unsigned blue, unsigned transp,
+                          struct fb_info *fb_info)
+{
+        /*
+         *  Set a single color register. The values supplied are
+         *  already rounded down to the hardware's capabilities
+         *  (according to the entries in the `var' structure). Return
+         *  != 0 for invalid regno.
+         */
+        
+	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
+
+        if (regno >= info->video_cmap_len)
+                return 1;
+
+        info->palette[regno].red   = red;
+        info->palette[regno].green = green;
+        info->palette[regno].blue  = blue;
+        
+	pci_outb(info, regno, DAC_W_INDEX);
+	pci_outb(info, red,   DAC_DATA);
+	pci_outb(info, green, DAC_DATA);
+	pci_outb(info, blue,  DAC_DATA);
+
+	if (regno << 16)
+		switch (default_var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			info->fbcon_cmap.cfb16[regno] = 
+				(regno << 10) | (regno << 5) | regno;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB24
+		case 24:
+			info->fbcon_cmap.cfb24[regno] = 
+				(regno << 16) | (regno << 8) | regno;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			i = (regno << 8) | regno;
+			info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+			break;
+#endif
+		}
+	return 0;
+}
+
+static void do_install_cmap(int con, struct fb_info *fb_info)
+{
+	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
+
+        if (con != info->currcon)
+                return;
+        if (fb_display[con].cmap.len)
+                fb_set_cmap(&fb_display[con].cmap, 1,
+                            iga_setcolreg, &info->fb_info);
+        else
+                fb_set_cmap(fb_default_cmap(info->video_cmap_len), 1, 
+			    iga_setcolreg, &info->fb_info);
+}
+
+static int igafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+                           struct fb_info *fb_info)
+{
+	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
+	
+        if (con == info->currcon) /* current console? */
+                return fb_get_cmap(cmap, kspc, iga_getcolreg, &info->fb_info);
+        else if (fb_display[con].cmap.len) /* non default colormap? */
+                fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+        else
+                fb_copy_cmap(fb_default_cmap(info->video_cmap_len),
+                     cmap, kspc ? 0 : 2);
+        return 0;
+}
+
+static int igafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+	                  struct fb_info *info)
+{
+        int err;
+	struct fb_info_iga *fb = (struct fb_info_iga*) info;
+
+        if (!fb_display[con].cmap.len) {        /* no colormap allocated? */
+                err = fb_alloc_cmap(&fb_display[con].cmap,
+				    fb->video_cmap_len,0);
+                if (err)
+                        return err;
+        }
+        if (con == fb->currcon)                     /* current console? */
+                return fb_set_cmap(cmap, kspc, iga_setcolreg, info);
+        else
+                fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+        return 0;
+}
+
+static int igafb_pan_display(struct fb_var_screeninfo *var, int con,
+                             struct fb_info *info)
+{
+        /* no panning */
+        return -EINVAL;
+}
+
+static int igafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		       u_long arg, int con, struct fb_info *info)
+{
+	return -EINVAL;
+}
+
+/*
+ * Framebuffer option structure
+ */
+static struct fb_ops igafb_ops = {
+    igafb_open, 
+    igafb_release, 
+    igafb_get_fix, 
+    igafb_get_var, 
+    igafb_set_var,
+    igafb_get_cmap, 
+    igafb_set_cmap, 
+    igafb_pan_display, 
+    igafb_ioctl,
+#ifdef __sparc__
+    igafb_mmap
+#else
+    NULL
+#endif
+};
+
+static void igafb_set_disp(int con, struct fb_info_iga *info)
+{
+        struct fb_fix_screeninfo fix;
+        struct display *display;
+        struct display_switch *sw;
+        
+        if (con >= 0)
+                display = &fb_display[con];
+        else 
+                display = &info->disp;        /* used during initialization */
+
+        igafb_get_fix(&fix, con, &info->fb_info);
+
+        memset(display, 0, sizeof(struct display));
+        display->screen_base = (char*)info->frame_buffer;
+        display->visual = fix.visual;
+        display->type = fix.type;
+        display->type_aux = fix.type_aux;
+        display->ypanstep = fix.ypanstep;
+        display->ywrapstep = fix.ywrapstep;
+        display->line_length = fix.line_length;
+        display->next_line = fix.line_length;
+        display->can_soft_blank = 0; 
+        display->inverse = 0;
+        igafb_get_var(&display->var, -1, &info->fb_info);
+
+        switch (default_var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+        case 8:
+                sw = &fbcon_cfb8;
+                break;
+#endif
+#ifdef FBCON_HAS_CFB16
+        case 15:
+        case 16:
+                sw = &fbcon_cfb16;
+		display->dispsw_data = fbcon_cmap.cfb16;
+                break;
+#endif
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		sw = &fbcon_cfb24;
+		display->dispsw_data = fbcon_cmap.cfb24;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+        case 32:
+                sw = &fbcon_cfb32;
+		display->dispsw_data = fbcon_cmap.cfb32;
+                break;
+#endif
+        default:
+                return;
+        }
+        memcpy(&info->dispsw, sw, sizeof(*sw));
+        display->dispsw = &info->dispsw;
+
+	display->scrollmode = SCROLL_YREDRAW;
+	info->dispsw.bmove = fbcon_redraw_bmove;
+}
+
+static int igafb_switch(int con, struct fb_info *fb_info)
+{
+	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
+	
+        /* Do we have to save the colormap? */
+        if (fb_display[info->currcon].cmap.len)
+                fb_get_cmap(&fb_display[info->currcon].cmap, 1,
+                            iga_getcolreg, fb_info);
+        
+        info->currcon = con;
+        /* Install new colormap */
+        do_install_cmap(con, fb_info);
+	igafb_update_var(con, fb_info);
+        return 1;
+}
+
+
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void igafb_blank(int blank, struct fb_info *info)
+{
+        /* Not supported */
+}
+
+
+__initfunc(static int iga_init(struct fb_info_iga *info))
+{
+        char vramsz = iga_inb(info, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL) 
+		                                         & MEM_SIZE_ALIAS;
+        switch (vramsz) {
+        case MEM_SIZE_1M:
+                info->total_vram = 0x100000;
+                break;
+        case MEM_SIZE_2M:
+                info->total_vram = 0x200000;
+                break;
+        case MEM_SIZE_4M:
+        case MEM_SIZE_RESERVED:
+                info->total_vram = 0x400000;
+                break;
+        }
+
+        if (default_var.bits_per_pixel > 8) {
+                info->video_cmap_len = 16;
+        } else {
+		int i, j;
+                for(i = 0; i < 16; i++) {
+                        j = color_table[i];
+                        info->palette[i].red   = default_red[j];
+                        info->palette[i].green = default_grn[j];
+                        info->palette[i].blue  = default_blu[j];
+                }
+                info->video_cmap_len = 256;
+        }
+
+	strcpy(info->fb_info.modename, igafb_name);
+	info->fb_info.node = -1;
+	info->fb_info.fbops = &igafb_ops;
+	info->fb_info.disp = &info->disp;
+	strcpy(info->fb_info.fontname, fontname);
+	info->fb_info.changevar = NULL;
+	info->fb_info.switch_con = &igafb_switch;
+	info->fb_info.updatevar = &igafb_update_var;
+	info->fb_info.blank = &igafb_blank;
+	info->fb_info.flags=FBINFO_FLAG_DEFAULT;
+
+	{
+		int j, k;
+		for (j = 0; j < 16; j++) {
+			k = color_table[j];
+			info->palette[j].red = default_red[k];
+			info->palette[j].green = default_grn[k];
+			info->palette[j].blue = default_blu[k];
+		}
+	}
+
+	igafb_set_disp(-1, info);
+
+	if (register_framebuffer(&info->fb_info) < 0)
+		return 0;
+
+	printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n",
+	       GET_FB_IDX(info->fb_info.node), igafb_name, 
+	       info->frame_buffer_phys, info->total_vram >> 20);
+
+	iga_blank_border(info); 
+	return 1;
+}	
+
+
+__initfunc(void igafb_init(void))
+{
+        struct pci_dev *pdev;
+        struct fb_info_iga *info;
+        unsigned long addr;
+        extern int con_is_present(void);
+
+        /* Do not attach when we have a serial console. */
+        if (!con_is_present())
+                return;
+
+        pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 
+                               PCI_DEVICE_ID_INTERG_1682, 0);
+        if(pdev == NULL)
+                return;
+
+        info = kmalloc(sizeof(struct fb_info_iga), GFP_ATOMIC);
+        if (!info) {
+                printk("igafb_init: can't alloc fb_info_iga\n");
+                return;
+        }
+        memset(info, 0, sizeof(struct fb_info_iga));
+
+	info->frame_buffer = pdev->base_address[0];
+	if (!info->frame_buffer)
+		return;
+
+        pcibios_read_config_dword(0, pdev->devfn,
+                                  PCI_BASE_ADDRESS_0, 
+                                  (unsigned int*)&addr);
+	if (!addr)
+		return;
+	info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
+
+#ifdef __sparc__
+	
+	info->io_base_phys = info->frame_buffer_phys;
+	
+	/* Obtain virtual address and correct physical by PCIC shift */
+	info->io_base = pcic_alloc_io(&info->io_base_phys);
+	if (!info->io_base) {
+		return;
+	}
+
+	/*
+	 * Figure mmap addresses from PCI config space.
+	 * We need two regions: for video memory and for I/O ports.
+	 * Later one can add region for video coprocessor registers.
+	 * However, mmap routine loops until size != 0, so we put
+	 * one additional region with size == 0. 
+	 */
+
+	info->mmap_map = kmalloc(4 * sizeof(*info->mmap_map), GFP_ATOMIC);
+	if (!info->mmap_map) {
+                printk("igafb_init: can't alloc mmap_map\n");
+                kfree(info);
+		return;
+	}
+
+	memset(info->mmap_map, 0, 4 * sizeof(*info->mmap_map));
+
+	/*
+	 * Set default vmode and cmode from PROM properties.
+	 */
+	{
+                struct pcidev_cookie *cookie = pdev->sysdata;
+                int node = cookie->prom_node;
+                int width = prom_getintdefault(node, "width", 1024);
+                int height = prom_getintdefault(node, "height", 768);
+                int depth = prom_getintdefault(node, "depth", 8);
+                switch (width) {
+                    case 1024:
+                        if (height == 768)
+                            default_var = default_var_1024x768;
+                        break;
+                    case 1152:
+                        if (height == 900)
+                            default_var = default_var_1152x900;
+                        break;
+                    case 1280:
+                        if (height == 1024)
+                            default_var = default_var_1280x1024;
+                        break;
+                    default:
+                        break;
+                }
+
+                switch (depth) {
+                    case 8:
+                        default_var.bits_per_pixel = 8;
+                        break;
+                    case 16:
+                        default_var.bits_per_pixel = 16;
+                        break;
+                    case 24:
+                        default_var.bits_per_pixel = 24;
+                        break;
+                    case 32:
+                        default_var.bits_per_pixel = 32;
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+#endif
+            if (!iga_init(info)) {
+		    if (info->mmap_map)
+			    kfree(info->mmap_map);
+		    kfree(info);
+            }
+
+#ifdef __sparc__
+	    /*
+	     * Add /dev/fb mmap values.
+	     */
+	    
+	    /* First region is for video memory */
+	    info->mmap_map[0].voff = 0x0;  
+	    info->mmap_map[0].poff = info->frame_buffer_phys & PAGE_MASK;
+	    info->mmap_map[0].size = info->total_vram   & PAGE_MASK;
+	    info->mmap_map[0].prot_mask = SRMMU_CACHE;
+	    info->mmap_map[0].prot_flag = SRMMU_WRITE;
+
+	    /* Second region is for I/O ports */
+	    info->mmap_map[1].voff = info->frame_buffer_phys & PAGE_MASK;
+	    info->mmap_map[1].poff = info->io_base_phys & PAGE_MASK;
+	    info->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
+	    info->mmap_map[1].prot_mask = SRMMU_CACHE;
+	    info->mmap_map[1].prot_flag = SRMMU_WRITE;
+#endif /* __sparc__ */
+}
+
+__initfunc(void igafb_setup(char *options, int *ints))
+{
+    char *this_opt;
+
+    if (!options || !*options)
+        return;
+
+    for (this_opt = strtok(options, ","); this_opt;
+         this_opt = strtok(NULL, ",")) {
+        if (!strncmp(this_opt, "font:", 5)) {
+                char *p;
+                int i;
+
+                p = this_opt + 5;
+                for (i = 0; i < sizeof(fontname) - 1; i++)
+                        if (!*p || *p == ' ' || *p == ',')
+                                break;
+                memcpy(fontname, this_opt + 5, i);
+                fontname[i] = 0;
+        }
+    }
+}
diff -u --recursive --new-file v2.1.125/linux/drivers/video/imsttfb.c linux/drivers/video/imsttfb.c
--- v2.1.125/linux/drivers/video/imsttfb.c	Mon Oct  5 13:13:42 1998
+++ linux/drivers/video/imsttfb.c	Thu Oct 15 15:24:18 1998
@@ -1,5 +1,5 @@
 /*
- *  drivers/video/imsttfb.c -- frame buffer device for IMS Twin Turbo
+ *  drivers/video/imsttfb.c -- frame buffer device for IMS TwinTurbo
  *
  *  This file is derived from the powermac console "imstt" driver:
  *  Copyright (C) 1997 Sigurdur Asgeirsson
@@ -27,13 +27,14 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
+#include <linux/console.h>
 #include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
 #include <linux/nvram.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
@@ -55,7 +56,7 @@
 	TVP = 0x01
 };
 
-/* TwinTurbo registers */
+/* TwinTurbo (Cosmo) registers */
 enum {
 	S1SA	=  0, /* 0x00 */
 	S2SA	=  1, /* 0x04 */
@@ -112,23 +113,70 @@
 #endif
 };
 
-/* IBM ramdac registers */
+/* IBM ramdac direct registers */
 enum {
 	PADDRW	= 0x00,
 	PDATA	= 0x04,
 	PPMASK	= 0x08,
-	PADDRR	= 0x0C,
+	PADDRR	= 0x0c,
 	PIDXLO	= 0x10,	
 	PIDXHI	= 0x14,	
 	PIDXDATA= 0x18,
-	PIDXCTL	= 0x1C,
+	PIDXCTL	= 0x1c
+};
 
-	PPIXREP	= 0x0A,
-	PM0	= 0x20,
-	PN0	= 0x21,
-	PP0	= 0x22,
-	PC0	= 0x23,
-	MCTL_3	= 0x72
+/* IBM ramdac indirect registers */
+enum {
+	CLKCTL		= 0x02,	/* (0x01) Miscellaneous Clock Control */
+	SYNCCTL		= 0x03,	/* (0x00) Sync Control */
+	HSYNCPOS	= 0x04,	/* (0x00) Horizontal Sync Position */
+	PWRMNGMT	= 0x05,	/* (0x00) Power Management  [multiples of 4 unblack screen] */
+	DACOP		= 0x06,	/* (0x02) DAC Operation  [0-3 coloured, 4-7 green, odd light, even dark] */
+	PALETCTL	= 0x07,	/* (0x00) Palette Control */
+	SYSCLKCTL	= 0x08,	/* (0x01) System Clock Control */
+	PIXFMT		= 0x0a,	/* () Pixel Format  [bpp >> 3 + 2] */
+	BPP8		= 0x0b,	/* () 8 Bits/Pixel Control */
+	BPP16		= 0x0c, /* () 16 Bits/Pixel Control  [15 or 1 for 555] */
+	BPP24		= 0x0d,	/* () 24 Bits/Pixel Control */
+	BPP32		= 0x0e,	/* () 32 Bits/Pixel Control */
+	PIXCTL1		= 0x10, /* (0x05) Pixel PLL Control 1  [5-7 ok] */
+	PIXCTL2		= 0x11,	/* (0x00) Pixel PLL Control 2  [multiples of 20 ok] */
+	SYSCLKN		= 0x15,	/* () System Clock N (System PLL Reference Divider) */
+	SYSCLKM		= 0x16,	/* () System Clock M (System PLL VCO Divider) */
+	SYSCLKP		= 0x17,	/* () System Clock P */
+	SYSCLKC		= 0x18,	/* () System Clock C */
+	/*
+	 * Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1)
+	 * c is charge pump bias which depends on the VCO frequency  
+	 */
+	PIXCLKM		= 0x20,	/* () Pixel Clock M */
+	PIXCLKN		= 0x21,	/* () Pixel Clock N */
+	PIXCLKP		= 0x22,	/* () Pixel Clock P */
+	PIXCLKC		= 0x23,	/* () Pixel Clock C */
+	CURSCTL		= 0x30,	/* (0x00) Cursor Control  [1=curs1, 2=curs2, 5=curs3] */
+	CURSXLO		= 0x31,	/* () Cursor X position, low 8 bits */
+	CURSXHI		= 0x32,	/* () Cursor X position, high 8 bits */
+	CURSYLO		= 0x33,	/* () Cursor Y position, low 8 bits */
+	CURSYHI		= 0x34,	/* () Cursor Y position, high 8 bits */
+	CURSHOTX	= 0x35,	/* () ???  [position relative to CURSX] */
+	CURSHOTY	= 0x36,	/* () ???  [position relative to CURSY] */
+	CURSACAEN	= 0x37,	/* () ???  [even=cursor on, odd=cursor off] */
+	CURS1R		= 0x40,	/* () Cursor 1 Red */
+	CURS1G		= 0x41,	/* () Cursor 1 Green */
+	CURS1B		= 0x42,	/* () Cursor 1 Blue */
+	CURS2R		= 0x43,	/* () Cursor 2 Red */
+	CURS2G		= 0x44,	/* () Cursor 2 Green */
+	CURS2B		= 0x45,	/* () Cursor 2 Blue */
+	CURS3R		= 0x46,	/* () Cursor 3 Red */
+	CURS3G		= 0x47,	/* () Cursor 3 Green */
+	CURS3B		= 0x48,	/* () Cursor 3 Blue */
+	BORDR		= 0x60,	/* () Border Color Red */
+	BORDG		= 0x61,	/* () Border Color Green */
+	BORDB		= 0x62,	/* () Border Color Blue */
+	MISCTL1		= 0x70,	/* (0x00) Miscellaneous Control 1 */
+	MISCTL2		= 0x71,	/* (0x00) Miscellaneous Control 2 */
+	MISCTL3		= 0x72,	/* (0x00) Miscellaneous Control 3 */
+	KEYCTL		= 0x78	/* (0x00) Key Control/DB Operation */
 };
 
 /* TI TVP 3030 RAMDAC Direct Registers */
@@ -191,13 +239,13 @@
 };
 
 static struct initvalues ibm_initregs[] = {
-	{ 0x02, 0x21 },	/* (0x01) Miscellaneous Clock Control */
-	{ 0x03, 0x00 },	/* (0x00) Sync Control */
-	{ 0x04, 0x00 },	/* (0x00) Horizontal Sync Position */
-	{ 0x05, 0x00 },	/* (0x00) Power Management */
-	{ 0x06, 0x03 },	/* (0x02) DAC Operation */
-	{ 0x07, 0x00 },	/* (0x00) Palette Control */
-	{ 0x08, 0x01 },	/* (0x01) System Clock Control */
+	{ CLKCTL,	0x21 },
+	{ SYNCCTL,	0x00 },
+	{ HSYNCPOS,	0x00 },
+	{ PWRMNGMT,	0x00 },
+	{ DACOP,	0x02 },
+	{ PALETCTL,	0x00 },
+	{ SYSCLKCTL,	0x01 },
 
 	/*
 	 * Note that colors in X are correct only if all video data is
@@ -205,72 +253,86 @@
 	 * color" must be configured.  This is the case for the IBM DAC
 	 * used in the 2MB and 4MB cards, at least.
 	 */
-	{ 0x0b, 0x00 },	/* (U) 8 BPP Control */
-	{ 0x0c, 0x00 },	/* (U) 16 BPP Control; the "1" means use 555 RGB color encoding */
-	{ 0x0d, 0x00 },	/* (U) 24 BPP Packed Control */
-	{ 0x0e, 0x00 },	/* (U) 32 BPP Control */
-
-	{ 0x10, 0x05 },	/* (0x00) Pixel PLL Control 1 */
-	{ 0x11, 0x00 },	/* (0x00) Pixel PLL Control 2 */
-	{ 0x15, 0x08 },	/* (0x08) SYSCLK N (System PLL Reference Divider) */
-	{ 0x16, 0x4f },	/* (0x41) SYSCLK M (System PLL VCO Divider) */
-	{ 0x17, 0x00 },	/* (U) SYSCLK P */
-	{ 0x18, 0x00 },	/* (U) SYSCLK C */
-	{ 0x30, 0x00 },	/* (0x00) Cursor Control */
-	{ 0x60, 0xff },	/* (U) Border Color Red */
-	{ 0x61, 0xff },	/* (U) Border Color Green */
-	{ 0x62, 0xff },	/* (U) Border Color Blue */
-	{ 0x70, 0x01 },	/* (0x00) Miscellaneous Control 1 */
-	{ 0x71, 0x45 },	/* (0x00) Miscellaneous Control 2 */
-	{ 0x72, 0x00 },	/* (0x00) Miscellaneous Control 3 */
-	{ 0x78, 0x00 }	/* (0x00) Key Control/DB Operation */
+	{ BPP8,		0x00 },
+	{ BPP16,	0x00 },
+	{ BPP24,	0x00 },
+	{ BPP32,	0x00 },
+
+	{ PIXCTL1,	0x05 },
+	{ PIXCTL2,	0x00 },
+	{ SYSCLKN,	0x08 },
+	{ SYSCLKM,	0x4f },
+	{ SYSCLKP,	0x00 },
+	{ SYSCLKC,	0x00 },
+	{ CURSCTL,	0x00 },
+	{ CURS2R,	0xff },
+	{ CURS2G,	0xff },
+	{ CURS2B,	0xff },
+	{ BORDR,	0xff },
+	{ BORDG,	0xff },
+	{ BORDB,	0xff },
+	{ MISCTL1,	0x01 },
+	{ MISCTL2,	0x45 },
+	{ MISCTL3,	0x00 },
+	{ KEYCTL,	0x00 }
 };
 
 static struct initvalues tvp_initregs[] = {
-	{ 0x6, 0x00 },
-	{ 0x7, 0xe4 },
-	{ 0xf, 0x06 },
-	{ 0x18, 0x80 },
-	{ 0x19, 0x4d },
-	{ 0x1a, 0x05 },
-	{ 0x1c, 0x00 },
-	{ 0x1d, 0x00 },
-	{ 0x1e, 0x08 },
-	{ 0x30, 0xff },
-	{ 0x31, 0xff },
-	{ 0x32, 0xff },
-	{ 0x33, 0xff },
-	{ 0x34, 0xff },
-	{ 0x35, 0xff },
-	{ 0x36, 0xff },
-	{ 0x37, 0xff },
-	{ 0x38, 0x00 },
-	{ TVPIRPLA, 0x00 },
-	{ TVPIRPPD, 0xc0 },
-	{ TVPIRPPD, 0xd5 },
-	{ TVPIRPPD, 0xea },
-	{ TVPIRPLA, 0x00 },
-	{ TVPIRMPD, 0xb9 },
-	{ TVPIRMPD, 0x3a },
-	{ TVPIRMPD, 0xb1 },
-	{ TVPIRPLA, 0x00 },
-	{ TVPIRLPD, 0xc1 },
-	{ TVPIRLPD, 0x3d },
-	{ TVPIRLPD, 0xf3 },
+	{ 0x6,	0x00 },
+	{ 0x7,	0xe4 },
+	{ 0xf,	0x06 },
+	{ 0x18,	0x80 },
+	{ 0x19,	0x4d },
+	{ 0x1a,	0x05 },
+	{ 0x1c,	0x00 },
+	{ 0x1d,	0x00 },
+	{ 0x1e,	0x08 },
+	{ 0x30,	0xff },
+	{ 0x31,	0xff },
+	{ 0x32,	0xff },
+	{ 0x33,	0xff },
+	{ 0x34,	0xff },
+	{ 0x35,	0xff },
+	{ 0x36,	0xff },
+	{ 0x37,	0xff },
+	{ 0x38,	0x00 },
+	{ TVPIRPLA,	0x00 },
+	{ TVPIRPPD,	0xc0 },
+	{ TVPIRPPD,	0xd5 },
+	{ TVPIRPPD,	0xea },
+	{ TVPIRPLA,	0x00 },
+	{ TVPIRMPD,	0xb9 },
+	{ TVPIRMPD,	0x3a },
+	{ TVPIRMPD,	0xb1 },
+	{ TVPIRPLA,	0x00 },
+	{ TVPIRLPD,	0xc1 },
+	{ TVPIRLPD,	0x3d },
+	{ TVPIRLPD,	0xf3 },
+};
+
+struct imstt_regvals {
+	__u32 pitch;
+	__u16 hes, heb, hsb, ht, ves, veb, vsb, vt, vil;
+	__u8 pclk_m, pclk_n, pclk_p;
+	/* Values of the tvp which change depending on colormode x resolution */
+	__u8 mlc[3];	/* Memory Loop Config 0x39 */
+	__u8 lckl_p[3];	/* P value of LCKL PLL */
+};
+
+struct imstt_cursor {
+	int enable;
+	int on;
+	int vbl_cnt;
+	int blink_rate;
+	__u16 x, y;
+	struct timer_list timer;
 };
 
 struct fb_info_imstt {
 	struct fb_info info;
 	struct fb_fix_screeninfo fix;
 	struct display disp;
-	struct {
-		__u8 red, green, blue;
-	} palette[256];
-	__u8 *frame_buffer_phys, *frame_buffer;
-	__u32 *dc_regs_phys, *dc_regs;
-	__u8 *cmap_regs_phys, *cmap_regs;
-	__u32 total_vram;
-	__u32 ramdac;
+	struct display_switch dispsw;
 	union {
 #ifdef FBCON_HAS_CFB16
 		__u16 cfb16[16];
@@ -282,178 +344,181 @@
 		__u32 cfb32[16];
 #endif
 	} fbcon_cmap;
+	struct {
+		__u8 red, green, blue;
+	} palette[256];
+	struct imstt_regvals init;
+	struct imstt_cursor cursor;
+	__u8 *frame_buffer_phys, *frame_buffer;
+	__u32 *dc_regs_phys, *dc_regs;
+	__u8 *cmap_regs_phys, *cmap_regs;
+	__u32 total_vram;
+	__u32 ramdac;
 };
 
-#define USE_NV_MODES	1
-#define INIT_BPP	8
-#define INIT_XRES	640
-#define INIT_YRES	480
+#define USE_NV_MODES		1
+#define INIT_BPP		8
+#define INIT_XRES		640
+#define INIT_YRES		480
+#define CURSOR_BLINK_RATE	20
+#define CURSOR_DRAW_DELAY	2
 
 static int currcon = 0;
 
-/*
- * for the IBM ramdac:
- * Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1)
- * where m = clk[0], n = clk[1], p = clk[2]
- * clk[3] is c, charge pump bias which depends on the VCO frequency  
- */
-struct imstt_regvals {
-	__u16 hes, heb, hsb, ht, ves, veb, vsb, vt, vil;
-	__u8 pclk_m, pclk_n, pclk_p;
-	__u32 pitch;
-	/* Values of the tvp which change depending on colormode x resolution */
-	__u8 mlc[3];	/* Memory Loop Config 0x39 */
-	__u8 lckl_p[3];	/* P value of LCKL PLL */
-};
-
-/* 1600x1200, 75Hz */
-static struct imstt_regvals ibm_reg_init_1600x1200x75 = {
-	0x0018, 0x0040, 0x0108, 0x010c, 0x0003, 0x002a, 0x04da, 0x04dd, 0x04da,
-	0x09, 0x00, 0x00,
-	1600
-};
-
-/* 1280x1024, 75Hz (20) */
-static struct imstt_regvals ibm_reg_init_20 = {
-	0x0012, 0x002f, 0x00cf, 0x00d3, 0x0003, 0x0029, 0x0429, 0x042a, 0x0429,
-	0x1a, 0x03, 0x00,
-	1280
-};
-
-/* 1280x960, 75Hz (19) */
-static struct imstt_regvals ibm_reg_init_19 = {
-	0x0012, 0x0030, 0x00d0, 0x00d2, 0x0003, 0x0027, 0x03e7, 0x03e8, 0x03e7,
-	0x3e, 0x09, 0x00,
-	1280
-};
-
-/* 1152x870, 75Hz (18) */
-static struct imstt_regvals ibm_reg_init_18 = {
-	0x0012, 0x0022, 0x00b2, 0x00b6, 0x0003, 0x0031, 0x0397, 0x039a, 0x0397, 
-	0x3c, 0x0b, 0x00,
-	1152
-};
-
-/* 1024x768, 75Hz (17) */
-#if 1
-static struct imstt_regvals ibm_reg_init_17 = {
-	0x000a, 0x001c, 0x009c, 0x00a6, 0x0003, 0x0020, 0x0320, 0x0323, 0x0320, 
-	0x07, 0x00, 0x01,
-	1024
-};
-#else
-/* this almost works with a 14" apple multiple scan monitor */
-static struct imstt_regvals ibm_reg_init_17 = {
-	0x000a, 0x001d, 0x009c, 0x00ac, 0x0003, 0x0020, 0x0320, 0x0323, 0x0320, 
-	0x3e, 0x0a, 0x01,
-	1024
-};
-#endif
-
-/* 832x624, 75Hz (13) */
-static struct imstt_regvals ibm_reg_init_13 = {
-	0x0005, 0x0020, 0x0088, 0x0090, 0x0003, 0x0028, 0x0298, 0x029b, 0x0298,
-	0x3e, 0x0a, 0x01,
-	832
-};
-
-/* 640x480, 67Hz (6) */
-static struct imstt_regvals ibm_reg_init_6 = {
-	0x0008, 0x0012, 0x0062, 0x006c, 0x0003, 0x002a, 0x020a, 0x020c, 0x020a,
-	0x78, 0x13, 0x02,
-	640
-};
-
 static struct imstt_regvals tvp_reg_init_2 = {
+	512,
 	0x0002, 0x0006, 0x0026, 0x0028, 0x0003, 0x0016, 0x0196, 0x0197, 0x0196,
 	0xec, 0x2a, 0xf3,
-	512,
 	{ 0x3c, 0x3b, 0x39 }, { 0xf3, 0xf3, 0xf3 }
 };
 
 static struct imstt_regvals tvp_reg_init_6 = {
+	640,
 	0x0004, 0x0009, 0x0031, 0x0036, 0x0003, 0x002a, 0x020a, 0x020d, 0x020a,
 	0xef, 0x2e, 0xb2,
-	640,
 	{ 0x39, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }
 };
 
 static struct imstt_regvals tvp_reg_init_12 = {
+	800,
 	0x0005, 0x000e, 0x0040, 0x0042, 0x0003, 0x018, 0x270, 0x271, 0x270,
 	0xf6, 0x2e, 0xf2,
-	800,
 	{ 0x3a, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }
 };
 
 static struct imstt_regvals tvp_reg_init_13 = {
+	832,
 	0x0004, 0x0011, 0x0045, 0x0048, 0x0003, 0x002a, 0x029a, 0x029b, 0x0000,
 	0xfe, 0x3e, 0xf1,
-	832,
 	{ 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
 };
 
 static struct imstt_regvals tvp_reg_init_17 = {
+	1024,
 	0x0006, 0x0210, 0x0250, 0x0053, 0x1003, 0x0021, 0x0321, 0x0324, 0x0000,
 	0xfc, 0x3a, 0xf1,
-	1024,
 	{ 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
 };
 
 static struct imstt_regvals tvp_reg_init_18 = {
+	1152,
   	0x0009, 0x0011, 0x059, 0x5b, 0x0003, 0x0031, 0x0397, 0x039a, 0x0000, 
 	0xfd, 0x3a, 0xf1,
-	1152,
 	{ 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
 };
 
 static struct imstt_regvals tvp_reg_init_19 = {
+	1280,
 	0x0009, 0x0016, 0x0066, 0x0069, 0x0003, 0x0027, 0x03e7, 0x03e8, 0x03e7,
 	0xf7, 0x36, 0xf0,
-	1280,
 	{ 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }
 };
 
 static struct imstt_regvals tvp_reg_init_20 = {
+	1280,
 	0x0009, 0x0018, 0x0068, 0x006a, 0x0003, 0x0029, 0x0429, 0x042a, 0x0000,
 	0xf0, 0x2d, 0xf0,
-	1280,
 	{ 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }
 };
 
+static __u32
+getclkMHz (struct fb_info_imstt *p)
+{
+	__u32 clk_m, clk_n, clk_p;
+
+	clk_m = p->init.pclk_m;
+	clk_n = p->init.pclk_n;
+	clk_p = p->init.pclk_p;
+
+	return 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));
+}
+
+static void
+setclkMHz (struct fb_info_imstt *p, __u32 MHz)
+{
+	__u32 clk_m, clk_n, clk_p, x, stage, spilled;
+
+	clk_m = clk_n = clk_p = 0;
+	stage = spilled = 0;
+	for (;;) {
+		switch (stage) {
+			case 0:
+				clk_m++;
+				break;
+			case 1:
+				clk_n++;
+				break;
+		}
+		x = 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));
+		if (x == MHz)
+			break;
+		if (x > MHz) {
+			spilled = 1;
+			stage = 1;
+		} else if (spilled && x < MHz) {
+			stage = 0;
+		}
+	}
+
+	p->init.pclk_m = clk_m;
+	p->init.pclk_n = clk_n;
+	p->init.pclk_p = clk_p;
+}
+
 static struct imstt_regvals *
-compute_imstt_regvals_ibm (int xres, int yres)
+compute_imstt_regvals_ibm (struct fb_info_imstt *p, int xres, int yres)
 {
-	struct imstt_regvals *init;
+	struct imstt_regvals *init = &p->init;
+	__u32 MHz, hes, heb, veb, htp, vtp;
 
 	switch (xres) {
 		case 640:
-			init = &ibm_reg_init_6;
+			hes = 0x0008; heb = 0x0012; veb = 0x002a; htp = 10; vtp = 2;
+			MHz = 30 /* .25 */ ;
 			break;
 		case 832:
-			init = &ibm_reg_init_13;
+			hes = 0x0005; heb = 0x0020; veb = 0x0028; htp = 8; vtp = 3;
+			MHz = 57 /* .27_ */ ;
 			break;
 		case 1024:
-			init = &ibm_reg_init_17;
+			hes = 0x000a; heb = 0x001c; veb = 0x0020; htp = 8; vtp = 3;
+			MHz = 80;
 			break;
 		case 1152:
-			init = &ibm_reg_init_18;
+			hes = 0x0012; heb = 0x0022; veb = 0x0031; htp = 4; vtp = 3;
+			MHz = 101 /* .6_ */ ;
 			break;
 		case 1280:
-			init = yres == 960 ? &ibm_reg_init_19 : &ibm_reg_init_20;
+			hes = 0x0012; heb = 0x002f; veb = 0x0029; htp = 4; vtp = 1;
+			MHz = yres == 960 ? 126 : 135;
 			break;
 		case 1600:
-			init = &ibm_reg_init_1600x1200x75;
+			hes = 0x0018; heb = 0x0040; veb = 0x002a; htp = 4; vtp = 3;
+			MHz = 200;
 			break;
 		default:
-			init = 0;
-			break;
+			return 0;
 	}
 
+	setclkMHz(p, MHz);
+
+	init->hes = hes;
+	init->heb = heb;
+	init->hsb = init->heb + xres / 8;
+	init->ht = init->hsb + htp;
+	init->ves = 0x0003;
+	init->veb = veb;
+	init->vsb = init->veb + yres;
+	init->vt = init->vsb + vtp;
+	init->vil = init->vsb;
+
+	init->pitch = xres;
+
 	return init;
 }
 
 static struct imstt_regvals *
-compute_imstt_regvals_tvp (int xres, int yres)
+compute_imstt_regvals_tvp (struct fb_info_imstt *p, int xres, int yres)
 {
 	struct imstt_regvals *init;
 
@@ -480,46 +545,47 @@
 			init = yres == 960 ? &tvp_reg_init_19 : &tvp_reg_init_20;
 			break;
 		default:
-			init = 0;
-			break;
+			return 0;
 	}
+	p->init = *init;
 
 	return init;
 }
 
 static struct imstt_regvals *
-compute_imstt_regvals (struct fb_info_imstt *p, int xres, int yres)
+compute_imstt_regvals (struct fb_info_imstt *p, u_int xres, u_int yres)
 {
 	if (p->ramdac == IBM)
-		return compute_imstt_regvals_ibm(xres, yres);
+		return compute_imstt_regvals_ibm(p, xres, yres);
 	else
-		return compute_imstt_regvals_tvp(xres, yres);
+		return compute_imstt_regvals_tvp(p, xres, yres);
 }
 
 static void
-set_imstt_regvals_ibm (struct fb_info_imstt *p, struct imstt_regvals *init, int bpp)
+set_imstt_regvals_ibm (struct fb_info_imstt *p, u_int bpp)
 {
+	struct imstt_regvals *init = &p->init;
 	__u8 pformat = (bpp >> 3) + 2;
 
 	p->cmap_regs[PIDXHI] = 0;		eieio();
-	p->cmap_regs[PIDXLO] = PM0;		eieio();
+	p->cmap_regs[PIDXLO] = PIXCLKM;		eieio();
 	p->cmap_regs[PIDXDATA] = init->pclk_m;	eieio();
-	p->cmap_regs[PIDXLO] = PN0;		eieio();
+	p->cmap_regs[PIDXLO] = PIXCLKN;		eieio();
 	p->cmap_regs[PIDXDATA] = init->pclk_n;	eieio();
-	p->cmap_regs[PIDXLO] = PP0;		eieio();
+	p->cmap_regs[PIDXLO] = PIXCLKP;		eieio();
 	p->cmap_regs[PIDXDATA] = init->pclk_p;	eieio();
-	p->cmap_regs[PIDXLO] = PC0;		eieio();
+	p->cmap_regs[PIDXLO] = PIXCLKC;		eieio();
 	p->cmap_regs[PIDXDATA] = 0x02;		eieio();
 
 	p->cmap_regs[PIDXHI] = 0;		eieio();
-	p->cmap_regs[PIDXLO] = PPIXREP;		eieio();
+	p->cmap_regs[PIDXLO] = PIXFMT;		eieio();
 	p->cmap_regs[PIDXDATA] = pformat;	eieio();
-	p->cmap_regs[PIDXHI] = 0;		eieio();
 }
 
 static void
-set_imstt_regvals_tvp (struct fb_info_imstt *p, struct imstt_regvals *init, int bpp)
+set_imstt_regvals_tvp (struct fb_info_imstt *p, u_int bpp)
 {
+	struct imstt_regvals *init = &p->init;
 	__u8 tcc, mxc, lckl_n, mic;
 	__u8 mlc, lckl_p;
 
@@ -583,14 +649,15 @@
 }
 
 static void
-set_imstt_regvals (struct fb_info_imstt *p, struct imstt_regvals *init, int bpp)
+set_imstt_regvals (struct fb_info_imstt *p, u_int bpp)
 {
+	struct imstt_regvals *init = &p->init;
 	__u32 ctl, pitch, byteswap, scr;
 
 	if (p->ramdac == IBM)
-		set_imstt_regvals_ibm(p, init, bpp);
+		set_imstt_regvals_ibm(p, bpp);
 	else
-		set_imstt_regvals_tvp(p, init, bpp);
+		set_imstt_regvals_tvp(p, bpp);
 
   /*
    * From what I (jsk) can gather poking around with MacsBug,
@@ -617,7 +684,7 @@
 			break;
 		case 24:
 			ctl = 0x17b9;
-			pitch = init->pitch - (init->pitch / 4);
+			pitch = init->pitch - (p->init.pitch / 4);
 			byteswap = 0x2;
 			break;
 		case 32:
@@ -676,60 +743,161 @@
 	out_le32(&p->dc_regs[STGCTL], ctl);
 }
 
-void
+static void
 set_16 (struct fb_info_imstt *p, __u8 x)
 {
 	if (p->ramdac == IBM) {
 		p->cmap_regs[PIDXHI] = 0;	eieio();
-		p->cmap_regs[PIDXLO] = 0x0c;	eieio();
+		p->cmap_regs[PIDXLO] = BPP16;	eieio();
 		p->cmap_regs[PIDXDATA] = x;	eieio();
 	} else {
 		/* ?!? */
 	}
 }
 
-#define set_555(_p)	set_16(_p, 15)	/* need 220 or 224 for X */
+#define set_555(_p)	set_16(_p, 15)
 #define set_565(_p)	set_16(_p, 0)	/* 220, 224 is darker in X */
 
-void
+static void
+imstt_set_cursor (struct fb_info_imstt *p, int on)
+{
+	struct imstt_cursor *c = &p->cursor;
+
+	p->cmap_regs[PIDXHI] = 0;
+	if (!on) {
+		p->cmap_regs[PIDXLO] = CURSCTL;
+		p->cmap_regs[PIDXDATA] = 0x00;
+	} else {
+		p->cmap_regs[PIDXLO] = CURSXHI;
+		p->cmap_regs[PIDXDATA] = c->x >> 8;
+		p->cmap_regs[PIDXLO] = CURSXLO;
+		p->cmap_regs[PIDXDATA] = c->x & 0xff;
+		p->cmap_regs[PIDXLO] = CURSYHI;
+		p->cmap_regs[PIDXDATA] = c->y >> 8;
+		p->cmap_regs[PIDXLO] = CURSYLO;
+		p->cmap_regs[PIDXDATA] = c->y & 0xff;
+		p->cmap_regs[PIDXLO] = CURSCTL;
+		p->cmap_regs[PIDXDATA] = 0x02;
+	}
+}
+
+static void
+imsttfb_cursor (struct display *disp, int mode, int x, int y)
+{
+	struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
+	struct imstt_cursor *c = &p->cursor;
+
+	x *= fontwidth(disp);
+	y *= fontheight(disp);
+
+	if (c->x == x && c->y == y && (mode == CM_ERASE) == !c->enable)
+		return;
+
+	c->enable = 0;
+	if (c->on)
+		imstt_set_cursor(p, 0);
+	c->x = x;
+	c->y = y;
+
+	switch (mode) {
+		case CM_ERASE:
+			c->on = 0;
+			break;
+		case CM_DRAW:
+		case CM_MOVE:
+			if (c->on)
+				imstt_set_cursor(p, c->on);
+			else
+				c->vbl_cnt = CURSOR_DRAW_DELAY;
+			c->enable = 1;
+			break;
+	}
+}
+
+static int
+imsttfb_set_font (struct display *disp, int width, int height)
+{
+	return 1;
+}
+
+static void
+imstt_cursor_timer_handler (unsigned long dev_addr)
+{
+	struct fb_info_imstt *p = (struct fb_info_imstt *)dev_addr;
+	struct imstt_cursor *c = &p->cursor;
+
+	if (!c->enable)
+		goto out;
+
+	if (c->vbl_cnt && --c->vbl_cnt == 0) {
+		c->on ^= 1;
+		imstt_set_cursor(p, c->on);
+		c->vbl_cnt = c->blink_rate;
+	}
+
+out:
+	c->timer.expires = jiffies + (HZ / 50);
+	add_timer(&c->timer);
+}
+
+__initfunc(static void
+imstt_cursor_init (struct fb_info_imstt *p))
+{
+	struct imstt_cursor *c = &p->cursor;
+
+	c->enable = 1;
+	c->on = 1;
+	c->blink_rate = CURSOR_BLINK_RATE;
+	c->vbl_cnt = CURSOR_DRAW_DELAY;
+	c->x = c->y = 0;
+
+	init_timer(&c->timer);
+	c->timer.expires = jiffies + (HZ / 50);
+	c->timer.data = (unsigned long)p;
+	c->timer.function = imstt_cursor_timer_handler;
+	add_timer(&c->timer);
+}
+
+static void
 imsttfb_rectcopy (struct display *disp, int sy, int sx, int dy, int dx, int height, int width)
 {
 	struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
-	__u32 tmp, cnt_reg;
+	__u32 cnt_reg, stat, xxx = 0;
 	__u32	line_pitch = disp->var.xres * (disp->var.bits_per_pixel >> 3),
 		rect_height = height,
 		rect_width = width * (disp->var.bits_per_pixel >> 3),
 		fb_offset_old = sy * line_pitch + (sx * (disp->var.bits_per_pixel >> 3)),
 		fb_offset_new = dy * line_pitch + (dx * (disp->var.bits_per_pixel >> 3));
 
+	stat = in_le32(&p->dc_regs[SSTATUS]) & 0xff;
+
 	cnt_reg = ((rect_height - 1) << 16) | (rect_width - 1);
+	out_le32(&p->dc_regs[CNT], cnt_reg);
+	out_le32(&p->dc_regs[S1SA], fb_offset_old);
+	out_le32(&p->dc_regs[DSA], fb_offset_old);
+	out_le32(&p->dc_regs[SP], line_pitch);
+	out_le32(&p->dc_regs[DP_OCTRL], line_pitch);
+	out_le32(&p->dc_regs[BLTCTL], 0x5);
 
-	tmp = (line_pitch << 16) | line_pitch;
-	out_le32(&p->dc_regs[SP], tmp);
-	tmp = line_pitch;
-	out_le32(&p->dc_regs[DP_OCTRL], tmp);
-#if 0
-	do {
-		tmp = in_le32(&p->dc_regs[SSTATUS]);
+	if (++stat == 0x20)
+		stat = 0x10;
+	while ((in_le32(&p->dc_regs[SSTATUS]) & 0xff) != stat && xxx++ < 0xff)
 		eieio();
-	} while (tmp & 0x80);
-#endif
+
+	cnt_reg = ((rect_height - 1) << 16) | (0xffff - (rect_width - 2));
 	out_le32(&p->dc_regs[CNT], cnt_reg);
-	out_le32(&p->dc_regs[S1SA], fb_offset_old);
-	out_le32(&p->dc_regs[S2SA], fb_offset_new);
 	out_le32(&p->dc_regs[DSA], fb_offset_new);
-	out_le32(&p->dc_regs[BLTCTL], 0x5);
 #if 0
-	do {
-		tmp = in_le32(&p->dc_regs[SSTATUS]);
-		eieio();
-	} while (tmp & 0x80);
+	out_le32(&p->dc_regs[S1SA], fb_offset_old);
+	out_le32(&p->dc_regs[SP], line_pitch);
+	out_le32(&p->dc_regs[DP_OCTRL], line_pitch);
+#endif
+	out_le32(&p->dc_regs[BLTCTL], 0x85);
 
-	do {
-		tmp = in_le32(&p->dc_regs[SSTATUS]);
+	if (++stat == 0x20)
+		stat = 0x10;
+	while ((in_le32(&p->dc_regs[SSTATUS]) & 0xff) != stat && xxx++ < 0xff)
 		eieio();
-	} while (tmp & 0x40);
-#endif
 }
 
 static void
@@ -745,29 +913,34 @@
 	imsttfb_rectcopy(disp, sy, sx, dy, dx, height, width);
 }
 
+#ifdef FBCON_HAS_CFB8
 static struct display_switch fbcon_imstt8 = {
 	fbcon_cfb8_setup, imsttfbcon_bmove, fbcon_cfb8_clear, fbcon_cfb8_putc,
 	fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
 	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
-
+#endif
+#ifdef FBCON_HAS_CFB16
 static struct display_switch fbcon_imstt16 = {
 	fbcon_cfb16_setup, imsttfbcon_bmove, fbcon_cfb16_clear, fbcon_cfb16_putc,
 	fbcon_cfb16_putcs, fbcon_cfb16_revc, NULL, NULL, fbcon_cfb16_clear_margins,
 	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
-
+#endif
+#ifdef FBCON_HAS_CFB24
 static struct display_switch fbcon_imstt24 = {
 	fbcon_cfb24_setup, imsttfbcon_bmove, fbcon_cfb24_clear, fbcon_cfb24_putc,
 	fbcon_cfb24_putcs, fbcon_cfb24_revc, NULL, NULL, fbcon_cfb24_clear_margins,
 	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
-
+#endif
+#ifdef FBCON_HAS_CFB32
 static struct display_switch fbcon_imstt32 = {
 	fbcon_cfb32_setup, imsttfbcon_bmove, fbcon_cfb32_clear, fbcon_cfb32_putc,
 	fbcon_cfb32_putcs, fbcon_cfb32_revc, NULL, NULL, fbcon_cfb32_clear_margins,
 	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
+#endif
 
 #ifdef CONFIG_FB_COMPAT_XPMAC
 #include <asm/vc_ioctl.h>
@@ -832,8 +1005,8 @@
 		   u_int transp, struct fb_info *info)
 {
 	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	unsigned int bpp = fb_display[currcon].var.bits_per_pixel;
-	unsigned int i;
+	u_int bpp = fb_display[currcon].var.bits_per_pixel;
+	u_int i;
 
 	if (regno > 255)
 		return 1;
@@ -847,7 +1020,7 @@
 	p->palette[regno].blue = blue;
 
 	/* PADDRW/PDATA are the same as TVPPADDRW/TVPPDATA */
-	if (fb_display[currcon].var.green.length == 5 /* && bpp == 16 */ && p->ramdac == TVP) {
+	if (p->ramdac == TVP && fb_display[currcon].var.green.length == 5 /* && bpp == 16 */) {
 		p->cmap_regs[PADDRW] = regno << 3;	eieio();
 	} else {
 		p->cmap_regs[PADDRW] = regno;		eieio();
@@ -885,7 +1058,7 @@
 	if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, 1, imsttfb_setcolreg, info);
 	else {
-		int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+		u_int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
 		fb_set_cmap(fb_default_cmap(size), 1, imsttfb_setcolreg, info);
 	}
 }
@@ -926,13 +1099,88 @@
 	return 0;
 }
 
+static void
+set_dispsw (struct display *disp, struct fb_info_imstt *p)
+{
+	u_int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
+
+	disp->visual = disp->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
+					 	     : FB_VISUAL_DIRECTCOLOR;
+	p->dispsw = fbcon_dummy;
+	disp->dispsw = &p->dispsw;
+	disp->dispsw_data = 0;
+	switch (disp->var.bits_per_pixel) {
+		case 8:
+			disp->var.red.offset = 0;
+			disp->var.red.length = 8;
+			disp->var.green.offset = 0;
+			disp->var.green.length = 8;
+			disp->var.blue.offset = 0;
+			disp->var.blue.length = 8;
+			disp->var.transp.offset = 0;
+			disp->var.transp.length = 0;
+#ifdef FBCON_HAS_CFB8
+			p->dispsw = accel ? fbcon_imstt8 : fbcon_cfb8;
+#endif
+			break;
+		case 16:	/* RGB 555 */
+			if (disp->var.red.offset != 11)
+				disp->var.red.offset = 10;
+			disp->var.red.length = 5;
+			disp->var.green.offset = 5;
+			if (disp->var.green.length != 6)
+				disp->var.green.length = 5;
+			disp->var.blue.offset = 0;
+			disp->var.blue.length = 5;
+			disp->var.transp.offset = 0;
+			disp->var.transp.length = 0;
+#ifdef FBCON_HAS_CFB16
+			p->dispsw = accel ? fbcon_imstt16 : fbcon_cfb16;
+			disp->dispsw_data = p->fbcon_cmap.cfb16;
+#endif
+			break;
+		case 24:	/* RGB 888 */
+			disp->var.red.offset = 16;
+			disp->var.red.length = 8;
+			disp->var.green.offset = 8;
+			disp->var.green.length = 8;
+			disp->var.blue.offset = 0;
+			disp->var.blue.length = 8;
+			disp->var.transp.offset = 0;
+			disp->var.transp.length = 0;
+#ifdef FBCON_HAS_CFB24
+			p->dispsw = accel ? fbcon_imstt24 : fbcon_cfb24;
+			disp->dispsw_data = p->fbcon_cmap.cfb24;
+#endif
+			break;
+		case 32:	/* RGBA 8888 */
+			disp->var.red.offset = 16;
+			disp->var.red.length = 8;
+			disp->var.green.offset = 8;
+			disp->var.green.length = 8;
+			disp->var.blue.offset = 0;
+			disp->var.blue.length = 8;
+			disp->var.transp.offset = 24;
+			disp->var.transp.length = 8;
+#ifdef FBCON_HAS_CFB32
+			p->dispsw = accel ? fbcon_imstt32 : fbcon_cfb32;
+			disp->dispsw_data = p->fbcon_cmap.cfb32;
+#endif
+			break;
+	}
+
+	if (p->ramdac == IBM) {
+		p->dispsw.cursor = imsttfb_cursor;
+		p->dispsw.set_font = imsttfb_set_font;
+	}
+}
+
 static int
 imsttfb_set_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
 	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
 	struct display *disp;
-	unsigned int oldbpp, oldxres, oldyres, oldgreenlen, oldaccel;
-	struct imstt_regvals *init;
+	u_int oldbpp, oldxres, oldyres, oldgreenlen, oldaccel;
 
 	disp = &fb_display[con];
 
@@ -950,8 +1198,7 @@
 	if (!((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW))
 		return 0;
 
-	init = compute_imstt_regvals(p, var->xres, var->yres);
-	if (!init)
+	if (!compute_imstt_regvals(p, var->xres, var->yres))
 		return -EINVAL;
 
 	oldbpp = disp->var.bits_per_pixel;
@@ -970,7 +1217,6 @@
 	disp->var.height = -1;
 	disp->var.width = -1;
 	disp->var.vmode = FB_VMODE_NONINTERLACED;
-	disp->var.pixclock = 10000;
 	disp->var.left_margin = disp->var.right_margin = 16;
 	disp->var.upper_margin = disp->var.lower_margin = 16;
 	disp->var.hsync_len = disp->var.vsync_len = 8;
@@ -981,73 +1227,8 @@
 	disp->ywrapstep = 0;
 	disp->scrollmode = SCROLL_YREDRAW;
 
-	if (oldbpp != disp->var.bits_per_pixel || oldaccel != disp->var.accel_flags) {
-		unsigned int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
-
-		disp->visual = disp->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
-						 	     : FB_VISUAL_DIRECTCOLOR;
-		disp->dispsw = &fbcon_dummy;
-		disp->dispsw_data = 0;
-		switch (disp->var.bits_per_pixel) {
-			case 8:
-				disp->var.red.offset = 0;
-				disp->var.red.length = 8;
-				disp->var.green.offset = 0;
-				disp->var.green.length = 8;
-				disp->var.blue.offset = 0;
-				disp->var.blue.length = 8;
-				disp->var.transp.offset = 0;
-				disp->var.transp.length = 0;
-#ifdef FBCON_HAS_CFB8
-				disp->dispsw = accel ? &fbcon_imstt8 : &fbcon_cfb8;
-#endif
-				break;
-			case 16:	/* RGB 565 */
-				if (disp->var.red.offset != 10 && disp->var.red.offset != 11)
-					disp->var.red.offset = 10;
-				disp->var.red.length = 5;
-				disp->var.green.offset = 5;
-				if (disp->var.green.length != 5 && disp->var.green.length != 6)
-					disp->var.green.length = 5;
-				disp->var.blue.offset = 0;
-				disp->var.blue.length = 5;
-				disp->var.transp.offset = 0;
-				disp->var.transp.length = 0;
-#ifdef FBCON_HAS_CFB16
-				disp->dispsw = accel ? &fbcon_imstt16 : &fbcon_cfb16;
-				disp->dispsw_data = p->fbcon_cmap.cfb16;
-#endif
-				break;
-			case 24:	/* RGB 888 */
-				disp->var.red.offset = 16;
-				disp->var.red.length = 8;
-				disp->var.green.offset = 8;
-				disp->var.green.length = 8;
-				disp->var.blue.offset = 0;
-				disp->var.blue.length = 8;
-				disp->var.transp.offset = 0;
-				disp->var.transp.length = 0;
-#ifdef FBCON_HAS_CFB24
-				disp->dispsw = accel ? &fbcon_imstt24 : &fbcon_cfb24;
-				disp->dispsw_data = p->fbcon_cmap.cfb24;
-#endif
-				break;
-			case 32:	/* RGBA 8888 */
-				disp->var.red.offset = 16;
-				disp->var.red.length = 8;
-				disp->var.green.offset = 8;
-				disp->var.green.length = 8;
-				disp->var.blue.offset = 0;
-				disp->var.blue.length = 8;
-				disp->var.transp.offset = 24;
-				disp->var.transp.length = 8;
-#ifdef FBCON_HAS_CFB32
-				disp->dispsw = accel ? &fbcon_imstt32 : &fbcon_cfb32;
-				disp->dispsw_data = p->fbcon_cmap.cfb32;
-#endif
-				break;
-		}
-	}
+	if (oldbpp != disp->var.bits_per_pixel || oldgreenlen != disp->var.green.length || oldaccel != disp->var.accel_flags)
+		set_dispsw(disp, p);
 
 	if (oldxres != disp->var.xres || oldbpp != disp->var.bits_per_pixel)
 		disp->line_length = disp->var.xres * (disp->var.bits_per_pixel >> 3);
@@ -1067,9 +1248,11 @@
 				set_555(p);
 		}
 		if (oldxres != disp->var.xres || oldyres != disp->var.yres || oldbpp != disp->var.bits_per_pixel)
-			set_imstt_regvals(p, init, disp->var.bits_per_pixel);
+			set_imstt_regvals(p, disp->var.bits_per_pixel);
 			
 	}
+	disp->var.pixclock = 1000000 / getclkMHz(p);
+
 	if (oldbpp != disp->var.bits_per_pixel) {
 		int err = fb_alloc_cmap(&disp->cmap, 0, 0);
 		if (err)
@@ -1084,7 +1267,7 @@
 imsttfb_pan_display (struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
 	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	unsigned int off;
+	u_int off;
 
 	if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual
 	    || var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)
@@ -1109,7 +1292,7 @@
 	else if (fb_display[con].cmap.len)	/* non default colormap? */
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else {
-		int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+		u_int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
 		fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
 	}
 
@@ -1165,12 +1348,12 @@
 		case FBIMSTT_SETCMAPREG:
 			if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x17c0000 - sizeof(reg[0])) / sizeof(reg[0]))
 				return -EFAULT;
-			out_le32(&((unsigned int *)p->cmap_regs)[reg[0]], reg[1]);
+			out_le32(&((u_int *)p->cmap_regs)[reg[0]], reg[1]);
 			break;
 		case FBIMSTT_GETCMAPREG:
 			if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x17c0000 - sizeof(reg[0])) / sizeof(reg[0]))
 				return -EFAULT;
-			reg[1] = in_le32(&((unsigned int *)p->cmap_regs)[reg[0]]);
+			reg[1] = in_le32(&((u_int *)p->cmap_regs)[reg[0]]);
 			if (copy_to_user((void *)(arg + 4), &reg[1], 4))
 				return -EFAULT;
 			break;
@@ -1212,28 +1395,36 @@
 static int
 imsttfbcon_switch (int con, struct fb_info *info)
 {
+	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
 	struct display *old = &fb_display[currcon], *new = &fb_display[con];
 
+	if (old->cmap.len)
+		fb_get_cmap(&old->cmap, 1, imsttfb_getcolreg, info);
+	
+	if (p->ramdac == IBM)
+		imsttfb_cursor(old, CM_ERASE, p->cursor.x, p->cursor.y);
+
+	currcon = con;
+
 	if (old->var.xres != new->var.xres
 	    || old->var.yres != new->var.yres
-	    || old->var.bits_per_pixel != new->var.bits_per_pixel) {
-		struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-		struct imstt_regvals *init = compute_imstt_regvals(p, new->var.xres, new->var.yres);
-		if (!init) /* ?!? */ return -1;
+	    || old->var.bits_per_pixel != new->var.bits_per_pixel
+	    || old->var.green.length != new->var.green.length) {
+		set_dispsw(new, p);
+		if (!compute_imstt_regvals(p, new->var.xres, new->var.yres))
+			return -1;
 		if (new->var.bits_per_pixel == 16) {
 			if (new->var.green.length == 6)
 				set_565(p);
 			else
 				set_555(p);
 		}
-		set_imstt_regvals(p, init, new->var.bits_per_pixel);
+		set_imstt_regvals(p, new->var.bits_per_pixel);
 #ifdef CONFIG_FB_COMPAT_XPMAC
 		set_display_info(new);
 #endif
 	}
-	if (old->cmap.len)
-		fb_get_cmap(&old->cmap, 1, imsttfb_getcolreg, info);
-	currcon = con;
+
 	do_install_cmap(con, info);
 
 	return 0;
@@ -1243,7 +1434,7 @@
 imsttfbcon_updatevar (int con, struct fb_info *info)
 {
 	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	unsigned int off;
+	u_int off;
 
 	if (con == currcon) {
 		off = fb_display[con].var.yoffset * (fb_display[con].line_length / 8)
@@ -1264,7 +1455,7 @@
 	if (blank > 0) {
 		switch (blank - 1) {
 			case VESA_NO_BLANKING:
-				ctrl &= ~0x000000f0;
+				ctrl &= ~0x00000380;
 				break;
 			case VESA_VSYNC_SUSPEND:
 				ctrl &= ~0x00000020;
@@ -1273,23 +1464,19 @@
 				ctrl &= ~0x00000010;
 				break;
 			case VESA_POWERDOWN:
-				ctrl &= ~0x000000f0;
+				ctrl &= ~0x00000380;
 				break;
 		}
 	} else {
-		ctrl |= p->ramdac == IBM ? 0x000000b0 : 0x00000080;
+		ctrl |= p->ramdac == IBM ? 0x000017b0 : 0x00001780;
 	}
 	out_le32(&p->dc_regs[STGCTL], ctrl);
 }
 
-__initfunc(static void init_imstt(struct fb_info_imstt *p))
+__initfunc(static void
+init_imstt(struct fb_info_imstt *p))
 {
 	__u32 i, tmp;
-	struct imstt_regvals *init;
-	unsigned int accel;
-
-	tmp = in_le32(&p->dc_regs[SSTATUS]);
-	/* printk("chip version %ld, ", (tmp & 0x0F00) >> 8); */
 
 	tmp = in_le32(&p->dc_regs[PRC]);
 	if (p->ramdac == IBM)
@@ -1318,7 +1505,7 @@
 		}
 	}
 
-#if USE_NV_MODES && (defined(CONFIG_PMAC) || defined(CONFIG_CHRP))
+#if USE_NV_MODES && defined(CONFIG_PPC)
 	{
 		int vmode, cmode;
 
@@ -1342,75 +1529,14 @@
 
 	p->disp.var.height = p->disp.var.width = -1;
 	p->disp.var.vmode = FB_VMODE_NONINTERLACED;
-	p->disp.var.pixclock = 10000;
 	p->disp.var.left_margin = p->disp.var.right_margin = 16;
 	p->disp.var.upper_margin = p->disp.var.lower_margin = 16;
 	p->disp.var.hsync_len = p->disp.var.vsync_len = 8;
 	p->disp.var.accel_flags = 0; /* FB_ACCELF_TEXT; */
 
-	accel = p->disp.var.accel_flags & FB_ACCELF_TEXT;
-
-	p->disp.dispsw = &fbcon_dummy;
-	p->disp.dispsw_data = 0;
-	switch (p->disp.var.bits_per_pixel) {
-		case 8:
-			p->disp.var.red.offset = 0;
-			p->disp.var.red.length = 8;
-			p->disp.var.green.offset = 0;
-			p->disp.var.green.length = 8;
-			p->disp.var.blue.offset = 0;
-			p->disp.var.blue.length = 8;
-			p->disp.var.transp.offset = 0;
-			p->disp.var.transp.length = 0;
-#ifdef FBCON_HAS_CFB8
-			p->disp.dispsw = accel ? &fbcon_imstt8 : &fbcon_cfb8;
-#endif
-			break;
-		case 16:	/* RGB 565 */
-			if (p->disp.var.red.offset != 10 && p->disp.var.red.offset != 11)
-				p->disp.var.red.offset = 10;
-			p->disp.var.red.length = 5;
-			p->disp.var.green.offset = 5;
-			if (p->disp.var.green.length != 5 && p->disp.var.green.length != 6)
-				p->disp.var.green.length = 5;
-			p->disp.var.blue.offset = 0;
-			p->disp.var.blue.length = 5;
-			p->disp.var.transp.offset = 0;
-			p->disp.var.transp.length = 0;
-#ifdef FBCON_HAS_CFB16
-			p->disp.dispsw = accel ? &fbcon_imstt16 : &fbcon_cfb16;
-			p->disp.dispsw_data = p->fbcon_cmap.cfb16;
-#endif
-			break;
-		case 24:	/* RGB 888 */
-			p->disp.var.red.offset = 16;
-			p->disp.var.red.length = 8;
-			p->disp.var.green.offset = 8;
-			p->disp.var.green.length = 8;
-			p->disp.var.blue.offset = 0;
-			p->disp.var.blue.length = 8;
-			p->disp.var.transp.offset = 0;
-			p->disp.var.transp.length = 0;
-#ifdef FBCON_HAS_CFB24
-			p->disp.dispsw = accel ? &fbcon_imstt24 : &fbcon_cfb24;
-			p->disp.dispsw_data = p->fbcon_cmap.cfb24;
-#endif
-			break;
-		case 32:	/* RGBA 8888 */
-			p->disp.var.red.offset = 16;
-			p->disp.var.red.length = 8;
-			p->disp.var.green.offset = 8;
-			p->disp.var.green.length = 8;
-			p->disp.var.blue.offset = 0;
-			p->disp.var.blue.length = 8;
-			p->disp.var.transp.offset = 24;
-			p->disp.var.transp.length = 8;
-#ifdef FBCON_HAS_CFB32
-			p->disp.dispsw = accel ? &fbcon_imstt32 : &fbcon_cfb32;
-			p->disp.dispsw_data = p->fbcon_cmap.cfb32;
-#endif
-			break;
-	}
+	set_dispsw(&p->disp, p);
+	if (p->ramdac == IBM)
+		imstt_cursor_init(p);
 
 	if (p->disp.var.green.length == 6)
 		set_565(p);
@@ -1418,13 +1544,15 @@
 		set_555(p);
 
 	if ((p->disp.var.xres * p->disp.var.yres) * (p->disp.var.bits_per_pixel >> 3) > p->total_vram
-	    || !(init = compute_imstt_regvals(p, p->disp.var.xres, p->disp.var.yres))) {
-		printk("imsttfb: %dx%dx%d not supported\n", p->disp.var.xres, p->disp.var.yres, p->disp.var.bits_per_pixel);
+	    || !(compute_imstt_regvals(p, p->disp.var.xres, p->disp.var.yres))) {
+		printk("imsttfb: %ux%ux%u not supported\n", p->disp.var.xres, p->disp.var.yres, p->disp.var.bits_per_pixel);
 		kfree(p);
 		return;
 	}
 
-	set_imstt_regvals(p, init, p->disp.var.bits_per_pixel);
+	set_imstt_regvals(p, p->disp.var.bits_per_pixel);
+
+	p->disp.var.pixclock = 1000000 / getclkMHz(p);
 
 	sprintf(p->fix.id, "IMS TT (%s)", p->ramdac == IBM ? "IBM" : "TVP");
 	p->fix.smem_start = (__u8 *)p->frame_buffer_phys;
@@ -1462,7 +1590,7 @@
 	p->info.flags = FBINFO_FLAG_DEFAULT;
 
 	for (i = 0; i < 16; i++) {
-		unsigned int j = color_table[i];
+		u_int j = color_table[i];
 		p->palette[i].red = default_red[j];
 		p->palette[i].green = default_grn[j];
 		p->palette[i].blue = default_blu[j];
@@ -1473,8 +1601,9 @@
 		return;
 	}
 
-	printk("fb%d: %s frame buffer; %uMB vram\n",
-		GET_FB_IDX(p->info.node), p->fix.id, p->total_vram >> 20);
+	tmp = (in_le32(&p->dc_regs[SSTATUS]) & 0x0f00) >> 8;
+	printk("fb%d: %s frame buffer; %uMB vram; chip version %u\n",
+		GET_FB_IDX(p->info.node), p->fix.id, p->total_vram >> 20, tmp);
 
 #ifdef CONFIG_FB_COMPAT_XPMAC
 	strncpy(display_info.name, p->fix.id, sizeof display_info.name);
@@ -1483,11 +1612,14 @@
 	display_info.cmap_data_address = (__u32)&p->cmap_regs_phys[PDATA];
 	display_info.disp_reg_address = 0;
 	set_display_info(&p->disp);
-	console_fb_info = &p->info;
+	if (!console_fb_info)
+		console_fb_info = &p->info;
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 }
 
-__initfunc(void imsttfb_of_init(struct device_node *dp))
+#if defined(CONFIG_FB_OF) || defined(CONFIG_PPC)
+__initfunc(void
+imsttfb_of_init(struct device_node *dp))
 {
 	struct fb_info_imstt *p;
 	int i;
@@ -1530,19 +1662,27 @@
 
 	init_imstt(p);
 }
+#endif
 
-__initfunc(void imsttfb_init(void))
+__initfunc(void
+imsttfb_init(void))
 {
-	unsigned int i;
+#if defined(CONFIG_PPC)
+	u_int i;
 	struct device_node *dp;
 	char *names[4] = {"IMS,tt128mb","IMS,tt128mbA","IMS,tt128mb8","IMS,tt128mb8A"};
 
+#ifdef CONFIG_FB_OF
 	if (prom_num_displays)
 		return;
+#endif
 
 	for (i = 0; i < 4; i++) {
 		dp = find_devices(names[i]);
 		if (dp)
 			imsttfb_of_init(dp);
 	}
+#else
+	/* ... */
+#endif
 }
diff -u --recursive --new-file v2.1.125/linux/fs/Config.in linux/fs/Config.in
--- v2.1.125/linux/fs/Config.in	Mon Sep 28 10:51:34 1998
+++ linux/fs/Config.in	Wed Oct 21 15:31:05 1998
@@ -27,6 +27,9 @@
     bool '   Root file system on NFS' CONFIG_ROOT_NFS
   fi
   tristate 'NFS server support' CONFIG_NFSD
+  if [ "$CONFIG_NFSD" != "n" ]; then
+    bool '   Emulate SUN NFS server' CONFIG_NFSD_SUN
+  fi
   if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then
     define_bool CONFIG_SUNRPC y
     define_bool CONFIG_LOCKD y
diff -u --recursive --new-file v2.1.125/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.1.125/linux/fs/binfmt_elf.c	Mon Oct  5 13:13:42 1998
+++ linux/fs/binfmt_elf.c	Wed Oct 21 10:02:48 1998
@@ -273,13 +273,13 @@
 	    if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
 	    if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
 	    if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
+	    vaddr = eppnt->p_vaddr;
 	    if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
 	    	elf_type |= MAP_FIXED;
-	    	vaddr = eppnt->p_vaddr;
 #ifdef __sparc__
 	    } else {
 		load_addr = get_unmapped_area(0, eppnt->p_filesz +
-					ELF_PAGEOFFSET(eppnt->p_vaddr));
+					ELF_PAGEOFFSET(vaddr));
 #endif
 	    }
 
@@ -293,7 +293,7 @@
 		goto out_close;
 
 	    if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
-		load_addr = map_addr;
+		load_addr = map_addr - ELF_PAGESTART(vaddr);
 		load_addr_set = 1;
 	    }
 
@@ -433,6 +433,13 @@
 		goto out;
 	if (!elf_check_arch(elf_ex.e_machine))
 		goto out;
+#ifdef __mips__
+	/* IRIX binaries handled elsewhere. */
+	if (elf_ex.e_flags & EF_MIPS_ARCH) {
+		retval = -ENOEXEC;
+		goto out;
+	}
+#endif
 	if (!bprm->dentry->d_inode->i_op		   ||
 	    !bprm->dentry->d_inode->i_op->default_file_ops ||
 	    !bprm->dentry->d_inode->i_op->default_file_ops->mmap)
@@ -613,7 +620,7 @@
 	for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
 		if (elf_ppnt->p_type == PT_LOAD) {
 			int elf_prot = 0, elf_flags;
-			unsigned long vaddr = 0;
+			unsigned long vaddr;
 
 			if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
 			if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
@@ -621,8 +628,8 @@
 
 			elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
 
+			vaddr = elf_ppnt->p_vaddr;
 			if (elf_ex.e_type == ET_EXEC || load_addr_set) {
-				vaddr = elf_ppnt->p_vaddr;
 				elf_flags |= MAP_FIXED;
 			}
 
@@ -639,7 +646,7 @@
 				load_addr = (elf_ppnt->p_vaddr -
 					     elf_ppnt->p_offset);
 				if (elf_ex.e_type == ET_DYN) {
-					load_bias = error;
+					load_bias = error - ELF_PAGESTART(load_bias + vaddr);
 					load_addr += error;
 				}
 			}
@@ -1118,12 +1125,16 @@
 #else
 	corefile[4] = '\0';
 #endif
-	dentry = open_namei(corefile, O_CREAT | 2 | O_TRUNC, 0600);
+	dentry = open_namei(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
 	if (IS_ERR(dentry)) {
 		dentry = NULL;
 		goto end_coredump;
 	}
 	inode = dentry->d_inode;
+
+	if(inode->i_nlink > 1)
+		goto end_coredump;	/* multiple links - don't dump */
+
 	if (!S_ISREG(inode->i_mode))
 		goto end_coredump;
 	if (!inode->i_op || !inode->i_op->default_file_ops)
diff -u --recursive --new-file v2.1.125/linux/fs/buffer.c linux/fs/buffer.c
--- v2.1.125/linux/fs/buffer.c	Wed Aug 26 11:37:40 1998
+++ linux/fs/buffer.c	Mon Oct 12 13:11:49 1998
@@ -734,7 +734,7 @@
 	needed = bdf_prm.b_un.nrefill * size;  
 
 	while ((nr_free_pages > freepages.min*2) &&
-	        (buffermem >> PAGE_SHIFT) * 100 < (buffer_mem.max_percent * num_physpages) &&
+	        !buffer_over_max() &&
 		grow_buffers(GFP_BUFFER, size)) {
 		obtained += PAGE_SIZE;
 		if (obtained >= needed)
diff -u --recursive --new-file v2.1.125/linux/fs/exec.c linux/fs/exec.c
--- v2.1.125/linux/fs/exec.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/exec.c	Wed Oct 21 10:02:48 1998
@@ -702,17 +702,17 @@
 
 void compute_creds(struct linux_binprm *bprm) 
 {
+	int new_permitted = cap_t(bprm->cap_permitted) |
+		(cap_t(bprm->cap_inheritable) & 
+		 cap_t(current->cap_inheritable));
+
 	/* For init, we want to retain the capabilities set
          * in the init_task struct. Thus we skip the usual
          * capability rules */
 	if (current->pid != 1) {
-		int new_permitted = bprm->cap_permitted.cap |
-			(bprm->cap_inheritable.cap & 
-			current->cap_inheritable.cap);
-
-		current->cap_permitted.cap = new_permitted;
-		current->cap_effective.cap = new_permitted & 
-						bprm->cap_effective.cap;
+		cap_t(current->cap_permitted) = new_permitted;
+		cap_t(current->cap_effective) = new_permitted & 
+						cap_t(bprm->cap_effective);
 	}
 	
         /* AUD: Audit candidate if current->cap_effective is set */
@@ -720,7 +720,7 @@
         current->suid = current->euid = current->fsuid = bprm->e_uid;
         current->sgid = current->egid = current->fsgid = bprm->e_gid;
         if (current->euid != current->uid || current->egid != current->gid ||
-	    !cap_isclear(current->cap_permitted))
+	    !cap_issubset(new_permitted, current->cap_permitted))
                 current->dumpable = 0;
 }
 
diff -u --recursive --new-file v2.1.125/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
--- v2.1.125/linux/fs/ext2/balloc.c	Mon Sep 28 10:51:34 1998
+++ linux/fs/ext2/balloc.c	Mon Oct 12 11:35:42 1998
@@ -86,11 +86,12 @@
 {
 	struct ext2_group_desc * gdp;
 	struct buffer_head * bh = NULL;
-	int retval = 0;
+	int retval = -EIO;
 	
 	gdp = ext2_get_group_desc (sb, block_group, NULL);
 	if (!gdp)
 		goto error_out;
+	retval = 0;
 	bh = bread (sb->s_dev, le32_to_cpu(gdp->bg_block_bitmap), sb->s_blocksize);
 	if (!bh) {
 		ext2_error (sb, "read_block_bitmap",
diff -u --recursive --new-file v2.1.125/linux/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c
--- v2.1.125/linux/fs/ext2/ialloc.c	Mon Oct  5 13:13:42 1998
+++ linux/fs/ext2/ialloc.c	Tue Oct 20 14:08:14 1998
@@ -318,7 +318,7 @@
 
 	sb = dir->i_sb;
 	inode->i_sb = sb;
-	inode->i_flags = sb->s_flags;
+	inode->i_flags = 0;
 	lock_super (sb);
 	es = sb->u.ext2_sb.s_es;
 repeat:
diff -u --recursive --new-file v2.1.125/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.1.125/linux/fs/ext2/namei.c	Tue Aug 18 22:02:06 1998
+++ linux/fs/ext2/namei.c	Sat Oct 10 10:29:48 1998
@@ -257,7 +257,7 @@
 				ext2_debug ("creating next block\n");
 
 				de = (struct ext2_dir_entry_2 *) bh->b_data;
-				de->inode = le32_to_cpu(0);
+				de->inode = 0;
 				de->rec_len = le16_to_cpu(sb->s_blocksize);
 				dir->i_size = offset + sb->s_blocksize;
 				dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
@@ -291,7 +291,7 @@
 				de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
 				de = de1;
 			}
-			de->inode = cpu_to_le32(0);
+			de->inode = 0;
 			de->name_len = namelen;
 			de->file_type = 0;
 			memcpy (de->name, name, namelen);
@@ -344,7 +344,8 @@
 				pde->rec_len =
 					cpu_to_le16(le16_to_cpu(pde->rec_len) +
 						    le16_to_cpu(dir->rec_len));
-			dir->inode = le32_to_cpu(0);
+			else
+				dir->inode = 0;
 			return 0;
 		}
 		i += le16_to_cpu(de->rec_len);
diff -u --recursive --new-file v2.1.125/linux/fs/inode.c linux/fs/inode.c
--- v2.1.125/linux/fs/inode.c	Mon Sep 28 10:51:34 1998
+++ linux/fs/inode.c	Tue Oct 20 14:08:14 1998
@@ -559,6 +559,9 @@
 
 /*
  * This is called with the inode lock held.. Be careful.
+ *
+ * We no longer cache the sb_flags in i_flags - see fs.h
+ *	-- rmk@arm.uk.linux.org
  */
 static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, struct list_head *head)
 {
@@ -575,7 +578,7 @@
 		inode->i_sb = sb;
 		inode->i_dev = sb->s_dev;
 		inode->i_ino = ino;
-		inode->i_flags = sb->s_flags;
+		inode->i_flags = 0;
 		inode->i_count = 1;
 		inode->i_state = I_LOCK;
 		spin_unlock(&inode_lock);
diff -u --recursive --new-file v2.1.125/linux/fs/lockd/clntlock.c linux/fs/lockd/clntlock.c
--- v2.1.125/linux/fs/lockd/clntlock.c	Fri Sep 19 10:14:53 1997
+++ linux/fs/lockd/clntlock.c	Thu Oct 15 21:42:32 1998
@@ -15,6 +15,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
+#include <linux/smp_lock.h>
 
 #define NLMDBG_FACILITY		NLMDBG_CIENT
 
@@ -167,6 +168,7 @@
 
 	/* This one ensures that our parent doesn't terminate while the
 	 * reclaim is in progress */
+	lock_kernel();
 	lockd_up();
 
 	/* First, reclaim all locks that have been granted previously. */
@@ -198,6 +200,7 @@
 	/* Release host handle after use */
 	nlm_release_host(host);
 	lockd_down();
+	unlock_kernel();
 
 	return 0;
 }
diff -u --recursive --new-file v2.1.125/linux/fs/minix/bitmap.c linux/fs/minix/bitmap.c
--- v2.1.125/linux/fs/minix/bitmap.c	Tue Jun 23 10:01:25 1998
+++ linux/fs/minix/bitmap.c	Tue Oct 20 14:08:14 1998
@@ -249,7 +249,7 @@
 		return NULL;
 	sb = dir->i_sb;
 	inode->i_sb = sb;
-	inode->i_flags = inode->i_sb->s_flags;
+	inode->i_flags = 0;
 	j = 8192;
 	bh = NULL;
 	for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) {
diff -u --recursive --new-file v2.1.125/linux/fs/namei.c linux/fs/namei.c
--- v2.1.125/linux/fs/namei.c	Fri Oct  9 13:27:14 1998
+++ linux/fs/namei.c	Wed Oct 21 10:10:12 1998
@@ -460,7 +460,6 @@
 			break;
 		if (flags & LOOKUP_SLASHOK)
 			goto return_base;
-		dentry = ERR_PTR(-ENOTDIR);
 		break;
 	}
 	dput(base);
@@ -536,6 +535,28 @@
 	return dir;
 }
 
+/* 
+ * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
+ * reasons.
+ *
+ * O_DIRECTORY translates into forcing a directory lookup.
+ */
+static inline int lookup_flags(unsigned int f)
+{
+	unsigned long retval = LOOKUP_FOLLOW;
+
+	if (f & O_NOFOLLOW)
+		retval &= ~LOOKUP_FOLLOW;
+	
+	if ((f & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
+		retval &= ~LOOKUP_FOLLOW;
+	
+	if (f & O_DIRECTORY)
+		retval |= LOOKUP_DIRECTORY;
+	
+	return retval;
+}
+
 /*
  *	open_namei()
  *
@@ -558,13 +579,7 @@
 	mode &= S_IALLUGO & ~current->fs->umask;
 	mode |= S_IFREG;
 
-	/* 
-	 * Special case: O_CREAT|O_EXCL on a dangling symlink should
-	 * give EEXIST for security reasons.  While inconsistent, this
-	 * is the same scheme used by, for example, Solaris 2.5.1.  --KAB
-	 */
-	dentry = lookup_dentry(pathname, NULL,
-			       (flag & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL));
+	dentry = lookup_dentry(pathname, NULL, lookup_flags(flag));
 	if (IS_ERR(dentry))
 		return dentry;
 
@@ -611,6 +626,10 @@
 	if (!inode)
 		goto exit;
 
+	error = -EACCES;
+	if (S_ISLNK(inode->i_mode))
+		goto exit;
+	
 	error = -EISDIR;
 	if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
 		goto exit;
diff -u --recursive --new-file v2.1.125/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v2.1.125/linux/fs/nfs/file.c	Wed Aug 26 11:37:41 1998
+++ linux/fs/nfs/file.c	Sat Oct 17 19:37:20 1998
@@ -169,6 +169,7 @@
 	return status;
 }
 
+
 /* 
  * Write to a file (through the page cache).
  */
@@ -179,14 +180,10 @@
 	struct inode * inode = dentry->d_inode;
 	ssize_t result;
 
-	dfprintk(VFS, "nfs: write(%s/%s (%d), %lu@%lu)\n",
+	dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		inode->i_count, (unsigned long) count, (unsigned long) *ppos);
+		inode->i_ino, (unsigned long) count, (unsigned long) *ppos);
 
-	if (!inode) {
-		printk("nfs_file_write: inode = NULL\n");
-		return -EINVAL;
-	}
 	result = -EBUSY;
 	if (IS_SWAPFILE(inode))
 		goto out_swapfile;
@@ -194,14 +191,6 @@
 	if (result)
 		goto out;
 
-#ifdef NFS_PARANOIA
-/* N.B. This should be impossible now -- inodes can't change mode */
-if (!S_ISREG(inode->i_mode)) {
-	printk("nfs_file_write: write to non-file, mode %07o\n",
-		inode->i_mode);
-	return -EINVAL;
-}
-#endif
 	result = count;
 	if (!count)
 		goto out;
@@ -214,7 +203,7 @@
 	return result;
 
 out_swapfile:
-	printk(KERN_ERR "NFS: attempt to write to active swap file!\n");
+	printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
 	goto out;
 }
 
diff -u --recursive --new-file v2.1.125/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.1.125/linux/fs/nfs/inode.c	Mon Sep 28 10:51:35 1998
+++ linux/fs/nfs/inode.c	Tue Oct 20 14:08:14 1998
@@ -481,7 +481,7 @@
 			goto out;	
 		inode->i_sb = sb;
 		inode->i_dev = sb->s_dev;
-		inode->i_flags = sb->s_flags;
+		inode->i_flags = 0;
 		inode->i_ino = fattr->fileid;
 		nfs_read_inode(inode);
 		nfs_fill_inode(inode, fattr);
diff -u --recursive --new-file v2.1.125/linux/fs/nfsd/export.c linux/fs/nfsd/export.c
--- v2.1.125/linux/fs/nfsd/export.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/nfsd/export.c	Wed Oct 21 15:31:05 1998
@@ -33,7 +33,10 @@
 typedef struct svc_export	svc_export;
 
 static svc_export *	exp_find(svc_client *clp, kdev_t dev);
-static svc_export *	exp_parent(svc_client *clp, kdev_t dev);
+static svc_export *	exp_parent(svc_client *clp, kdev_t dev,
+					struct dentry *dentry);
+static svc_export *	exp_child(svc_client *clp, kdev_t dev,
+					struct dentry *dentry);
 static void		exp_unexport_all(svc_client *clp);
 static void		exp_do_unexport(svc_export *unexp);
 static svc_client *	exp_getclientbyname(char *name);
@@ -90,8 +93,16 @@
 
 	if (!clp)
 		return NULL;
-	exp = exp_find(clp, dev);
-	return (exp && exp->ex_ino == ino)? exp : NULL;
+
+	exp = clp->cl_export[EXPORT_HASH(dev)];
+	if (exp)
+		do {
+			if (exp->ex_ino == ino && exp->ex_dev == dev)
+				goto out;
+		} while (NULL != (exp = exp->ex_next));
+	exp = NULL;
+out:
+	return exp;
 }
 
 /*
@@ -126,22 +137,80 @@
 }
 
 /*
- * Find the parent export entry for a given fs. This function is used
- * only by the export syscall to keep the export tree consistent.
+ * Find the export entry for a given dentry.  <gam3@acm.org>
  */
 static svc_export *
-exp_parent(svc_client *clp, kdev_t dev)
+exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry)
 {
-	svc_export	*exp;
+	svc_export      *exp;
 	kdev_t		xdev = dev;
+	struct dentry	*xdentry = dentry;
+	struct dentry	*ndentry = NULL;
+
+	if (clp == NULL || dentry == NULL)
+		return NULL;
 
 	do {
-		exp = exp_find(clp, xdev);
-		if (exp)
-			return exp;
-	} while (nfsd_parentdev(&xdev));
+		xdev = dev;
+		do {
+			exp = clp->cl_export[EXPORT_HASH(xdev)];
+			if (exp)
+				do {
+					ndentry = exp->ex_dentry;
+				        if (ndentry == xdentry) {
+#ifdef NFSD_PARANOIA
+if (dev == xdev)
+	dprintk("nfsd: exp_parent submount over mount.\n");
+else
+	dprintk("nfsd: exp_parent found.\n");
+#endif
+						goto out;
+					}
+				} while (NULL != (exp = exp->ex_next));
+		} while (nfsd_parentdev(&xdev));
+		if (xdentry == xdentry->d_parent) {
+			break;
+		}
+	} while ((xdentry = xdentry->d_parent));
+	exp = NULL;
+out:
+	return exp;
+}
+
+/*
+ * Find the child export entry for a given fs. This function is used
+ * only by the export syscall to keep the export tree consistent.
+ * <gam3@acm.org>
+ */
+static svc_export *
+exp_child(svc_client *clp, kdev_t dev, struct dentry *dentry)
+{
+	svc_export      *exp;
+	struct dentry	*xdentry = dentry;
+	struct dentry	*ndentry = NULL;
+
+	if (clp == NULL || dentry == NULL)
+		return NULL;
 
-	return NULL;
+	exp = clp->cl_export[EXPORT_HASH(dev)];
+	if (exp)
+		do {
+			ndentry = exp->ex_dentry;
+			if (ndentry)
+				while ((ndentry = ndentry->d_parent)) {
+					if (ndentry == xdentry) {
+#ifdef NFSD_PARANOIA
+dprintk("nfsd: exp_child mount under submount.\n");
+#endif
+						goto out;
+					}
+					if (ndentry == ndentry->d_parent)
+						break;
+				}
+		} while (NULL != (exp = exp->ex_next));
+	exp = NULL;
+out:
+	return exp;
 }
 
 /*
@@ -160,9 +229,10 @@
 	ino_t		ino;
 
 	/* Consistency check */
+	err = -EINVAL;
 	if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) ||
 	    !exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
-		return -EINVAL;
+		goto out;
 
 	dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n",
 			nxp->ex_client, nxp->ex_path,
@@ -183,15 +253,11 @@
 	 * If there's already an export for this file, assume this
 	 * is just a flag update.
 	 */
-	if ((exp = exp_find(clp, dev)) != NULL) {
-		/* Ensure there's only one export per FS. */
-		err = -EPERM;
-		if (exp->ex_ino == ino) {
-			exp->ex_flags    = nxp->ex_flags;
-			exp->ex_anon_uid = nxp->ex_anon_uid;
-			exp->ex_anon_gid = nxp->ex_anon_gid;
-			err = 0;
-		}
+	if ((exp = exp_get(clp, dev, ino)) != NULL) {
+		exp->ex_flags    = nxp->ex_flags;
+		exp->ex_anon_uid = nxp->ex_anon_uid;
+		exp->ex_anon_gid = nxp->ex_anon_gid;
+		err = 0;
 		goto out_unlock;
 	}
 
@@ -203,32 +269,32 @@
 
 	err = -ENOENT;
 	inode = dentry->d_inode;
-	if(!inode)
+	if (!inode)
 		goto finish;
 	err = -EINVAL;
-	if(inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
-
+	if (inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
 		printk(KERN_DEBUG "exp_export: i_dev = %x, dev = %x\n",
 			inode->i_dev, dev); 
 		/* I'm just being paranoid... */
 		goto finish;
 	}
 
-	/* We currently export only dirs. */
+	/* We currently export only dirs and regular files.
+	 * This is what umountd does.
+	 */
 	err = -ENOTDIR;
-	if (!S_ISDIR(inode->i_mode))
+	if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
 		goto finish;
 
-	/* If this is a sub-export, must be root of FS */
 	err = -EINVAL;
-	if ((parent = exp_parent(clp, dev)) != NULL) {
-		struct super_block *sb = inode->i_sb;
-
-		if (inode != sb->s_root->d_inode) {
-#ifdef NFSD_PARANOIA
-printk("exp_export: sub-export %s not root of device %s\n",
-nxp->ex_path, kdevname(sb->s_dev));
-#endif
+	if ((parent = exp_child(clp, dev, dentry)) != NULL) {
+		dprintk("exp_export: export not valid (Rule 3).\n");
+		goto finish;
+	}
+	/* Is this is a sub-export, must be a proper subset of FS */
+	if ((parent = exp_parent(clp, dev, dentry)) != NULL) {
+		if (dev == parent->ex_dev) {
+			dprintk("exp_export: sub-export not valid (Rule 2).\n");
 			goto finish;
 		}
 	}
@@ -306,7 +372,7 @@
 	 */
 	if (!exp_device_in_use(unexp->ex_dev)) {
 printk("exp_do_unexport: %s last use, flushing cache\n",
-kdevname(unexp->ex_dev));
+	kdevname(unexp->ex_dev));
 		nfsd_fh_flush(unexp->ex_dev);
 	}
 
@@ -362,18 +428,15 @@
 	err = -EINVAL;
 	clp = exp_getclientbyname(nxp->ex_client);
 	if (clp) {
-printk("exp_unexport: found client %s\n", nxp->ex_client);
 		expp = clp->cl_export + EXPORT_HASH(nxp->ex_dev);
 		while ((exp = *expp) != NULL) {
 			if (exp->ex_dev == nxp->ex_dev) {
-				if (exp->ex_ino != nxp->ex_ino) {
-printk("exp_unexport: ino mismatch, %ld not %ld\n", exp->ex_ino, nxp->ex_ino);
+				if (exp->ex_ino == nxp->ex_ino) {
+					*expp = exp->ex_next;
+					exp_do_unexport(exp);
+					err = 0;
 					break;
 				}
-				*expp = exp->ex_next;
-				exp_do_unexport(exp);
-				err = 0;
-				break;
 			}
 			expp = &(exp->ex_next);
 		}
@@ -390,28 +453,43 @@
  * since its harder to fool a kernel module than a user space program.
  */
 int
-exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, struct knfs_fh *f)
+exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino,
+	   char *path, struct knfs_fh *f)
 {
 	struct svc_export	*exp;
 	struct dentry		*dentry;
 	struct inode		*inode;
 	struct svc_fh		fh;
+	int			err;
 
-	dprintk("nfsd: exp_rootfh(%s:%x/%ld)\n", clp->cl_ident, dev, ino);
+	if (path) {
+		dentry = lookup_dentry(path, NULL, 0);
 
-	exp = exp_get(clp, dev, ino);
+		dev = dentry->d_inode->i_dev;
+		ino = dentry->d_inode->i_ino;
+	
+		dprintk("nfsd: exp_rootfh(%s [%p] %s:%x/%ld)\n",
+		         path, dentry, clp->cl_ident, dev, ino);
+		exp = exp_parent(clp, dev, dentry);
+	} else {
+		dprintk("nfsd: exp_rootfh(%s:%x/%ld)\n",
+		         clp->cl_ident, dev, ino);
+		exp = exp_get(clp, dev, ino);
+		dentry = dget(exp->ex_dentry);
+	}
+	err = -EPERM;
 	if (!exp)
-		return -EPERM;
+		goto out;
 
-	dentry = exp->ex_dentry;
 	inode = dentry->d_inode;
-	if(!inode) {
+	if (!inode) {
 		printk("exp_rootfh: Aieee, NULL d_inode\n");
 		return -EPERM;
 	}
-	if(inode->i_dev != dev || inode->i_ino != ino) {
+	if (inode->i_dev != dev || inode->i_ino != ino) {
 		printk("exp_rootfh: Aieee, ino/dev mismatch\n");
-		printk("exp_rootfh: arg[dev(%x):ino(%ld)] inode[dev(%x):ino(%ld)]\n",
+		printk("exp_rootfh: arg[dev(%x):ino(%ld)]"
+		       " inode[dev(%x):ino(%ld)]\n",
 		       dev, ino, inode->i_dev, inode->i_ino);
 	}
 
@@ -419,11 +497,14 @@
 	 * fh must be initialized before calling fh_compose
 	 */
 	fh_init(&fh);
-	fh_compose(&fh, exp, dget(dentry));
+	fh_compose(&fh, exp, dentry);
 	memcpy(f, &fh.fh_handle, sizeof(struct knfs_fh));
 	fh_put(&fh);
-
 	return 0;
+
+out:
+	dput(dentry);
+	return err;
 }
 
 /*
diff -u --recursive --new-file v2.1.125/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- v2.1.125/linux/fs/nfsd/nfsctl.c	Sun Jun  7 11:16:36 1998
+++ linux/fs/nfsd/nfsctl.c	Wed Oct 21 15:31:05 1998
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  */
+#define NFS_GETFH_NEW
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -47,6 +48,7 @@
 static int	nfsctl_export(struct nfsctl_export *data);
 static int	nfsctl_unexport(struct nfsctl_export *data);
 static int	nfsctl_getfh(struct nfsctl_fhparm *, struct knfs_fh *);
+static int	nfsctl_getfd(struct nfsctl_fdparm *, struct knfs_fh *);
 /* static int	nfsctl_ugidupdate(struct nfsctl_ugidmap *data); */
 
 static int	initialized = 0;
@@ -108,6 +110,29 @@
 #endif
 
 static inline int
+nfsctl_getfd(struct nfsctl_fdparm *data, struct knfs_fh *res)
+{
+	struct sockaddr_in	*sin;
+	struct svc_client	*clp;
+	int			err = 0;
+
+	if (data->gd_addr.sa_family != AF_INET)
+		return -EPROTONOSUPPORT;
+	if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS)
+		return -EINVAL;
+	sin = (struct sockaddr_in *)&data->gd_addr;
+
+	exp_readlock();
+	if (!(clp = exp_getclient(sin)))
+		err = -EPERM;
+	else
+		err = exp_rootfh(clp, 0, 0, data->gd_path, res);
+	exp_unlock();
+
+	return err;
+}
+
+static inline int
 nfsctl_getfh(struct nfsctl_fhparm *data, struct knfs_fh *res)
 {
 	struct sockaddr_in	*sin;
@@ -124,7 +149,7 @@
 	if (!(clp = exp_getclient(sin)))
 		err = -EPERM;
 	else
-		err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, res);
+		err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, res);
 	exp_unlock();
 
 	return err;
@@ -193,6 +218,9 @@
 #endif
 	case NFSCTL_GETFH:
 		err = nfsctl_getfh(&arg->ca_getfh, &res->cr_getfh);
+		break;
+	case NFSCTL_GETFD:
+		err = nfsctl_getfd(&arg->ca_getfd, &res->cr_getfh);
 		break;
 	default:
 		err = -EINVAL;
diff -u --recursive --new-file v2.1.125/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.1.125/linux/fs/nfsd/nfsfh.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/nfsd/nfsfh.c	Wed Oct 21 15:31:05 1998
@@ -493,6 +493,9 @@
 	struct fh_entry *fhe;
 	int i, found = (empty == NULL) ? 1 : 0;
 
+	if (!dentry)
+		goto out;
+
 	fhe = (cache == NFSD_FILE_CACHE) ? &filetable[0] : &dirstable[0];
 	for (i = 0; i < NFSD_MAXFH; i++, fhe++) {
 		if (fhe->dentry == dentry) {
@@ -504,6 +507,7 @@
 			*empty = fhe;
 		}
 	}
+out:
 	return NULL;
 }
 
@@ -756,8 +760,12 @@
 
 	fhe = find_fhe(fh->fh_dcookie, NFSD_FILE_CACHE, NULL);
 	if (fhe) {
-		struct dentry *parent, *dentry = fhe->dentry;
-		struct inode *inode = dentry->d_inode;
+		struct dentry *parent, *dentry;
+		struct inode *inode;
+
+		dentry = fhe->dentry;
+		inode = dentry->d_inode;
+
 		if (!inode) {
 #ifdef NFSD_PARANOIA
 printk("find_dentry_in_fhcache: %s/%s has no inode!\n",
@@ -1019,7 +1027,7 @@
 	dprintk("nfsd: fh_verify(exp %x/%u cookie %p)\n",
 		fh->fh_xdev, fh->fh_xino, fh->fh_dcookie);
 
-	if(fhp->fh_dverified)
+	if (fhp->fh_dverified)
 		goto check_type;
 	/*
 	 * Look up the export entry.
@@ -1051,11 +1059,37 @@
 	dentry = find_fh_dentry(fh);
 	if (!dentry)
 		goto out;
+
+	/*
+	 * Security: Check that the export is valid for dentry <gam3@acm.org>
+	 */
+	if (fh->fh_dev != fh->fh_xdev) {
+		printk("fh_verify: Security: export on other device"
+		       " (%d, %d).\n", fh->fh_dev, fh->fh_xdev);
+		goto out;
+	} else {
+		struct dentry *tdentry = dentry;
+
+		do {
+			if (exp->ex_dentry == tdentry) {
+				error = 0;
+				break;
+			}
+			if (tdentry->d_parent == tdentry)
+				break;
+		} while ((tdentry = tdentry->d_parent));
+		if (error) {
+			printk("fh_verify: Security: %s/%s bad export.\n",
+			       dentry->d_parent->d_name.name,
+			       dentry->d_name.name);
+			goto out;
+		}
+	}
 	/*
 	 * Note:  it's possible the returned dentry won't be the one in the
-         * file handle.  We can correct the file handle for our use, but
-         * unfortunately the client will keep sending the broken one.  Let's
-         * hope the lookup will keep patching things up.
+	 * file handle.  We can correct the file handle for our use, but
+	 * unfortunately the client will keep sending the broken one.  Let's
+	 * hope the lookup will keep patching things up.
 	 */
 	fhp->fh_dentry = dentry;
 	fhp->fh_export = exp;
diff -u --recursive --new-file v2.1.125/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- v2.1.125/linux/fs/nfsd/vfs.c	Tue Aug 18 22:02:06 1998
+++ linux/fs/nfsd/vfs.c	Wed Oct 21 15:31:05 1998
@@ -39,6 +39,7 @@
 #endif
 
 #define NFSDDBG_FACILITY		NFSDDBG_FILEOP
+#define NFSD_PARANOIA
 
 /* Open mode for nfsd_open */
 #define OPEN_READ	0
@@ -168,13 +169,19 @@
 	if (IS_ERR(dchild))
 		goto out_nfserr;
 	/*
-	 * Make sure we haven't crossed a mount point ...
+	 * check if we have crossed a mount point ...
 	 */
 	if (dchild->d_sb != dparent->d_sb) {
-#ifdef NFSD_PARANOIA
-printk("nfsd_lookup: %s/%s crossed mount point!\n", dparent->d_name.name, name);
-#endif
-		goto out_dput;
+		struct dentry *tdentry;
+		tdentry = dchild->d_covers;
+		if (tdentry == dchild)
+			goto out_dput;
+	        dput(dchild);
+		dchild = dget(tdentry);
+	        if (dchild->d_sb != dparent->d_sb) {
+printk("nfsd_lookup: %s/%s crossed mount point!\n", dparent->d_name.name, dchild->d_name.name);
+			goto out_dput;
+		}
 	}
 
 	/*
@@ -416,8 +423,8 @@
  * N.B. After this call fhp needs an fh_put
  */
 int
-nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, char *buf,
-						unsigned long *count)
+nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
+          char *buf, unsigned long *count)
 {
 	struct raparms	*ra;
 	mm_segment_t	oldfs;
@@ -1239,6 +1246,12 @@
 	dprintk("      owner %d/%d user %d/%d\n",
 		inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
 	 */
+
+#ifndef CONFIG_NFSD_SUN
+        if (dentry->d_mounts != dentry) {
+		return nfserr_perm;
+	}
+#endif
 
 	if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
 		if (EX_RDONLY(exp) || IS_RDONLY(inode))
diff -u --recursive --new-file v2.1.125/linux/fs/ntfs/attr.c linux/fs/ntfs/attr.c
--- v2.1.125/linux/fs/ntfs/attr.c	Tue Jul 21 00:15:32 1998
+++ linux/fs/ntfs/attr.c	Mon Oct 12 11:47:23 1998
@@ -9,7 +9,7 @@
 #include "struct.h"
 #include "attr.h"
 
-#include <errno.h>
+#include <linux/errno.h>
 #include "macros.h"
 #include "support.h"
 #include "util.h"
diff -u --recursive --new-file v2.1.125/linux/fs/ntfs/dir.c linux/fs/ntfs/dir.c
--- v2.1.125/linux/fs/ntfs/dir.c	Wed Jun 24 22:54:10 1998
+++ linux/fs/ntfs/dir.c	Mon Oct 12 11:47:23 1998
@@ -8,7 +8,7 @@
 #include "struct.h"
 #include "dir.h"
 
-#include <errno.h>
+#include <linux/errno.h>
 #include "super.h"
 #include "inode.h"
 #include "attr.h"
diff -u --recursive --new-file v2.1.125/linux/fs/ntfs/inode.c linux/fs/ntfs/inode.c
--- v2.1.125/linux/fs/ntfs/inode.c	Wed Jun 24 22:54:10 1998
+++ linux/fs/ntfs/inode.c	Mon Oct 12 11:47:23 1998
@@ -10,7 +10,7 @@
 #include "struct.h"
 #include "inode.h"
 
-#include <errno.h>
+#include <linux/errno.h>
 #include "macros.h"
 #include "attr.h"
 #include "super.h"
diff -u --recursive --new-file v2.1.125/linux/fs/ntfs/super.c linux/fs/ntfs/super.c
--- v2.1.125/linux/fs/ntfs/super.c	Tue Aug 18 22:02:06 1998
+++ linux/fs/ntfs/super.c	Mon Oct 12 11:47:23 1998
@@ -9,7 +9,7 @@
 #include "struct.h"
 #include "super.h"
 
-#include <errno.h>
+#include <linux/errno.h>
 #include "macros.h"
 #include "inode.h"
 #include "support.h"
diff -u --recursive --new-file v2.1.125/linux/fs/ntfs/util.c linux/fs/ntfs/util.c
--- v2.1.125/linux/fs/ntfs/util.c	Fri Dec 19 15:24:21 1997
+++ linux/fs/ntfs/util.c	Mon Oct 12 11:47:23 1998
@@ -12,7 +12,7 @@
 #include "struct.h"
 #include "util.h"
 
-#include <errno.h>
+#include <linux/errno.h>
 /* FreeBSD doesn't seem to have EILSEQ in errno.h */
 #ifndef EILSEQ
 # define EILSEQ	EINVAL
diff -u --recursive --new-file v2.1.125/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.1.125/linux/fs/proc/array.c	Fri Oct  9 13:27:15 1998
+++ linux/fs/proc/array.c	Wed Oct 21 10:02:48 1998
@@ -799,9 +799,9 @@
     return buffer + sprintf(buffer, "CapInh:\t%016x\n"
 			    "CapPrm:\t%016x\n"
 			    "CapEff:\t%016x\n",
-			    p->cap_inheritable.cap,
-			    p->cap_permitted.cap,
-			    p->cap_effective.cap);
+			    cap_t(p->cap_inheritable),
+			    cap_t(p->cap_permitted),
+			    cap_t(p->cap_effective));
 }
 
 
diff -u --recursive --new-file v2.1.125/linux/fs/proc/procfs_syms.c linux/fs/proc/procfs_syms.c
--- v2.1.125/linux/fs/proc/procfs_syms.c	Thu Jul 16 18:09:28 1998
+++ linux/fs/proc/procfs_syms.c	Fri Oct  9 11:56:59 1998
@@ -13,7 +13,9 @@
 extern struct inode_operations proc_scsi_inode_operations;
 extern struct proc_dir_entry proc_sys_root;
 
+#ifdef CONFIG_SYSCTL
 EXPORT_SYMBOL(proc_sys_root);
+#endif
 EXPORT_SYMBOL(proc_register);
 EXPORT_SYMBOL(proc_unregister);
 EXPORT_SYMBOL(create_proc_entry);
diff -u --recursive --new-file v2.1.125/linux/fs/sysv/ialloc.c linux/fs/sysv/ialloc.c
--- v2.1.125/linux/fs/sysv/ialloc.c	Mon Sep  8 21:33:42 1997
+++ linux/fs/sysv/ialloc.c	Tue Oct 20 14:08:14 1998
@@ -112,7 +112,7 @@
 		return NULL;
 	sb = dir->i_sb;
 	inode->i_sb = sb;
-	inode->i_flags = inode->i_sb->s_flags;
+	inode->i_flags = 0;
 	lock_super(sb);		/* protect against task switches */
 	if ((*sb->sv_sb_fic_count == 0)
 	    || (*sv_sb_fic_inode(sb,(*sb->sv_sb_fic_count)-1) == 0) /* Applies only to SystemV2 FS */
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/balloc.c linux/fs/ufs/balloc.c
--- v2.1.125/linux/fs/ufs/balloc.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/ufs/balloc.c	Fri Oct 16 11:53:19 1998
@@ -20,7 +20,6 @@
 #include "util.h"
 
 #undef UFS_BALLOC_DEBUG
-#undef UFS_BALLOC_DEBUG_MORE
 
 #ifdef UFS_BALLOC_DEBUG
 #define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
@@ -28,27 +27,12 @@
 #define UFSD(x)
 #endif
 
-#ifdef UFS_BALLOC_DEBUG_MORE
-#define UFSDM \
-ufs_print_cylinder_stuff (ucg, swab); \
-printk("inode: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nifree), \
-SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nifree), SWAB32(ucg->cg_cs.cs_nifree)); \
-printk("block: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nbfree), \
-SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nbfree), SWAB32(ucg->cg_cs.cs_nbfree)); \
-printk("fragment: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nffree), \
-SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nffree), SWAB32(ucg->cg_cs.cs_nffree)); \
-printk("ndir: total %u, fs %u, cg %u\n\n", SWAB32(usb1->fs_cstotal.cs_ndir), \
-SWAB32(sb->fs_cs(ucpi->c_cgx).cs_ndir), SWAB32(ucg->cg_cs.cs_ndir));
-#else
-#define UFSDM
-#endif
-
-
 unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, unsigned, int *);
 unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, unsigned, int *);
 unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info *, unsigned, int *);
 unsigned ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, unsigned, unsigned);
 static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[];
+void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, unsigned, int);
 
 /*
  * Free 'count' fragments from fragment number 'fragment'
@@ -90,8 +74,6 @@
 		goto failed;
 	}
 
-	UFSDM
-	
 	end_bit = bit + count;
 	bbase = ufs_blknum (bit);
 	blkmap = ubh_blkmap (UCPI_UBH, ucpi->c_freeoff, bbase);
@@ -118,6 +100,8 @@
 		SUB_SWAB32(ucg->cg_cs.cs_nffree, uspi->s_fpb);
 		SUB_SWAB32(usb1->fs_cstotal.cs_nffree, uspi->s_fpb);
 		SUB_SWAB32(sb->fs_cs(cgno).cs_nffree, uspi->s_fpb);
+		if ((sb->u.ufs_sb.s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
+			ufs_clusteracct (sb, ucpi, blkno, 1);
 		INC_SWAB32(ucg->cg_cs.cs_nbfree);
 		INC_SWAB32(usb1->fs_cstotal.cs_nbfree);
 		INC_SWAB32(sb->fs_cs(cgno).cs_nbfree);
@@ -126,8 +110,6 @@
 		INC_SWAB32(ubh_cg_blktot (ucpi, cylno));
 	}
 	
-	UFSDM
-	
 	ubh_mark_buffer_dirty (USPI_UBH, 1);
 	ubh_mark_buffer_dirty (UCPI_UBH, 1);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
@@ -166,7 +148,8 @@
 	UFSD(("ENTER, fragment %u, count %u\n", fragment, count))
 	
 	if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) {
-		ufs_error (sb, "ufs_free_blocks", "internal error");
+		ufs_error (sb, "ufs_free_blocks", "internal error, "
+			"fragment %u, count %u\n", fragment, count);
 		goto failed;
 	}
 
@@ -196,14 +179,14 @@
 		goto failed;
 	}
 
-	UFSDM
-	
 	for (i = bit; i < end_bit; i += uspi->s_fpb) {
 		blkno = ufs_fragstoblks(i);
 		if (ubh_isblockset(UCPI_UBH, ucpi->c_freeoff, blkno)) {
 			ufs_error(sb, "ufs_free_blocks", "freeing free fragment");
 		}
 		ubh_setblock(UCPI_UBH, ucpi->c_freeoff, blkno);
+		if ((sb->u.ufs_sb.s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
+			ufs_clusteracct (sb, ucpi, blkno, 1);
 		DQUOT_FREE_BLOCK(sb, inode, uspi->s_fpb);
 		INC_SWAB32(ucg->cg_cs.cs_nbfree);
 		INC_SWAB32(usb1->fs_cstotal.cs_nbfree);
@@ -213,8 +196,6 @@
 		INC_SWAB32(ubh_cg_blktot(ucpi, cylno));
 	}
 
-	UFSDM
-	
 	ubh_mark_buffer_dirty (USPI_UBH, 1);
 	ubh_mark_buffer_dirty (UCPI_UBH, 1);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
@@ -294,7 +275,6 @@
 		}
 		if (fragment < inode->u.ufs_i.i_lastfrag) {
 			UFSD(("EXIT (ALREADY ALLOCATED)\n"))
-			printk("hlaska 2\n");
 			unlock_super (sb);
 			return 0;
 		}
@@ -302,7 +282,6 @@
 	else {
 		if (tmp) {
 			UFSD(("EXIT (ALREADY ALLOCATED)\n"))
-			printk("hlaska 3, fragment %u, tmp %u, oldcount %u\n", fragment, tmp, oldcount);
 			unlock_super(sb);
 			return 0;
 		}
@@ -442,8 +421,6 @@
 		return 0;
 	}
 
-	UFSDM
-	
 	fragno = ufs_dtogd (fragment);
 	fragoff = ufs_fragnum (fragno);
 	for (i = oldcount; i < newcount; i++)
@@ -472,9 +449,6 @@
 	SUB_SWAB32(ucg->cg_cs.cs_nffree, count);
 	SUB_SWAB32(sb->fs_cs(cgno).cs_nffree, count);
 	SUB_SWAB32(usb1->fs_cstotal.cs_nffree, count);
-	usb1->fs_fmod = SWAB32(1);
-	
-	UFSDM
 	
 	ubh_mark_buffer_dirty (USPI_UBH, 1);
 	ubh_mark_buffer_dirty (UCPI_UBH, 1);
@@ -556,8 +530,6 @@
 			"internal error, bad magic number on cg %u", cgno);
 	ucg->cg_time = SWAB32(CURRENT_TIME);
 
-	UFSDM
-	
 	if (count == uspi->s_fpb) {
 		result = ufs_alloccg_block (inode, ucpi, goal, err);
 		if (result == (unsigned)-1)
@@ -602,10 +574,6 @@
 		INC_SWAB32(ucg->cg_frsum[allocsize - count]);
 
 succed:
-	usb1->fs_fmod = SWAB32(1);
-	
-	UFSDM
-	
 	ubh_mark_buffer_dirty (USPI_UBH, 1);
 	ubh_mark_buffer_dirty (UCPI_UBH, 1);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
@@ -652,8 +620,6 @@
 		goto gotit;
 	}
 	
-	/*** This function should be optimized later ***/
-
 norot:	
 	result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb);
 	if (result == (unsigned)-1)
@@ -661,7 +627,9 @@
 	ucpi->c_rotor = result;
 gotit:
 	blkno = ufs_fragstoblks(result);
-	ubh_clrblock(UCPI_UBH, ucpi->c_freeoff, blkno);
+	ubh_clrblock (UCPI_UBH, ucpi->c_freeoff, blkno);
+	if ((sb->u.ufs_sb.s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
+		ufs_clusteracct (sb, ucpi, blkno, -1);
 	if(DQUOT_ALLOC_BLOCK(sb, inode, uspi->s_fpb)) {
 		*err = -EDQUOT;
 		return (unsigned)-1;
@@ -672,7 +640,6 @@
 	cylno = ufs_cbtocylno(result);
 	DEC_SWAB16(ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(result)));
 	DEC_SWAB32(ubh_cg_blktot(ucpi, cylno));
-	usb1->fs_fmod = 1;
 	
 	UFSD(("EXIT, result %u\n", result))
 
@@ -685,7 +652,7 @@
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
 	struct ufs_cylinder_group * ucg;
-	unsigned start, length, length2, location, result;
+	unsigned start, length, location, result;
 	unsigned possition, fragsize, blockmap, mask;
 	unsigned swab;
 	
@@ -706,8 +673,8 @@
 		(uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other,
 		1 << (count - 1 + (uspi->s_fpb & 7))); 
 	if (location == 0) {
-		length2 = start + 1;
-		location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff, length2, 
+		length = start + 1;
+		location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff, length, 
 			(uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other,
 			1 << (count - 1 + (uspi->s_fpb & 7)));
 		if (location == 0) {
@@ -717,7 +684,6 @@
 			return (unsigned)-1;
 		}
 		start = 0;
-		length = length2;
 	}
 	result = (start + length - location) << 3;
 	ucpi->c_frotor = result;
@@ -752,6 +718,64 @@
 	UFSD(("EXIT (FAILED)\n"))
 	return (unsigned)-1;
 }
+
+void ufs_clusteracct(struct super_block * sb, 
+	struct ufs_cg_private_info * ucpi, unsigned blkno, int cnt)
+{
+	struct ufs_sb_private_info * uspi;
+	int i, start, end, forw, back;
+	unsigned swab;
+	
+	
+	uspi = sb->u.ufs_sb.s_uspi;
+	swab = sb->u.ufs_sb.s_swab;
+	
+	if (uspi->s_contigsumsize <= 0)
+		return;
+
+	if (cnt > 0)
+		ubh_setbit(UCPI_UBH, ucpi->c_clusteroff, blkno);
+	else
+		ubh_clrbit(UCPI_UBH, ucpi->c_clusteroff, blkno);
+
+	/*
+	 * Find the size of the cluster going forward.
+	 */
+	start = blkno + 1;
+	end = start + uspi->s_contigsumsize;
+	if ( end >= ucpi->c_nclusterblks)
+		end = ucpi->c_nclusterblks;
+	i = ubh_find_next_zero_bit (UCPI_UBH, ucpi->c_clusteroff, end, start);
+	if (i > end)
+		i = end;
+	forw = i - start;
+	
+	/*
+	 * Find the size of the cluster going backward.
+	 */
+	start = blkno - 1;
+	end = start - uspi->s_contigsumsize;
+	if (end < 0 ) 
+		end = -1;
+	i = ubh_find_last_zero_bit (UCPI_UBH, ucpi->c_clusteroff, start, end);
+	if ( i < end) 
+		i = end;
+	back = start - i;
+	
+	/*
+	 * Account for old cluster and the possibly new forward and
+	 * back clusters.
+	 */
+	i = back + forw + 1;
+	if (i > uspi->s_contigsumsize)
+		i = uspi->s_contigsumsize;
+	ADD_SWAB32(*((u32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (i << 2))), cnt);
+	if (back > 0)
+		SUB_SWAB32(*((u32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (back << 2))), cnt);
+	if (forw > 0)
+		SUB_SWAB32(*((u32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (forw << 2))), cnt);
+}
+
 
 static unsigned char ufs_fragtable_8fpb[] = {
 	0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/cylinder.c linux/fs/ufs/cylinder.c
--- v2.1.125/linux/fs/ufs/cylinder.c	Tue Jul 28 14:21:09 1998
+++ linux/fs/ufs/cylinder.c	Fri Oct 16 11:53:19 1998
@@ -22,7 +22,6 @@
 #include "util.h"
 
 #undef UFS_CYLINDER_DEBUG
-#undef UFS_CYLINDER_DEBUG_MORE
 
 #ifdef UFS_CYLINDER_DEBUG
 #define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
@@ -50,10 +49,6 @@
 	ucpi = sb->u.ufs_sb.s_ucpi[bitmap_nr];
 	ucg = (struct ufs_cylinder_group *)sb->u.ufs_sb.s_ucg[cgno]->b_data;
 
-#ifdef UFS_CYLINDER_DEBUG_MORE
-	ufs_print_cylinder_stuff (ucg, swab);
-#endif
-
 	UCPI_UBH->fragment = ufs_cgcmin(cgno);
 	UCPI_UBH->count = uspi->s_cgsize >> sb->s_blocksize_bits;
 	/*
@@ -77,7 +72,9 @@
 	ucpi->c_iusedoff = SWAB32(ucg->cg_iusedoff);
 	ucpi->c_freeoff = SWAB32(ucg->cg_freeoff);
 	ucpi->c_nextfreeoff = SWAB32(ucg->cg_nextfreeoff);
-	
+	ucpi->c_clustersumoff = SWAB32(ucg->cg_u.cg_44.cg_clustersumoff);
+	ucpi->c_clusteroff = SWAB32(ucg->cg_u.cg_44.cg_clusteroff);
+	ucpi->c_nclusterblks = SWAB32(ucg->cg_u.cg_44.cg_nclusterblks);
 	UFSD(("EXIT\n"))
 	return;	
 	
@@ -201,10 +198,12 @@
 			sb->u.ufs_sb.s_cg_loaded++;
 		else
 			ufs_put_cylinder (sb, UFS_MAX_GROUP_LOADED-1);
+		ucpi = sb->u.ufs_sb.s_ucpi[sb->u.ufs_sb.s_cg_loaded - 1];
 		for (j = sb->u.ufs_sb.s_cg_loaded - 1; j > 0; j--) {
 			sb->u.ufs_sb.s_cgno[j] = sb->u.ufs_sb.s_cgno[j-1];
 			sb->u.ufs_sb.s_ucpi[j] = sb->u.ufs_sb.s_ucpi[j-1];
 		}
+		sb->u.ufs_sb.s_ucpi[0] = ucpi;
 		ufs_read_cylinder (sb, cgno, 0);
 	}
 	UFSD(("EXIT\n"))
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/dir.c linux/fs/ufs/dir.c
--- v2.1.125/linux/fs/ufs/dir.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/ufs/dir.c	Fri Oct 16 11:53:19 1998
@@ -11,8 +11,6 @@
  * 4.4BSD (FreeBSD) support added on February 1st 1998 by
  * Niels Kristian Bech Jensen <nkbj@image.dk> partially based
  * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
- *
- * write support by Daniel Pirkl <daniel.pirkl@email.cz> 1998
  */
 
 #include <linux/fs.h>
@@ -104,11 +102,11 @@
 		       && offset < sb->s_blocksize) {
 			de = (struct ufs_dir_entry *) (bh->b_data + offset);
 			/* XXX - put in a real ufs_check_dir_entry() */
-			if ((de->d_reclen == 0) || (ufs_namlen(de) == 0)) {
+			if ((de->d_reclen == 0) || (ufs_get_de_namlen(de) == 0)) {
 			/* SWAB16() was unneeded -- compare to 0 */
 				filp->f_pos = (filp->f_pos &
-					      (sb->s_blocksize - 1)) +
-					       sb->s_blocksize;
+				              (sb->s_blocksize - 1)) +
+				               sb->s_blocksize;
 				brelse(bh);
 				return stored;
 			}
@@ -119,7 +117,7 @@
 				/* On error, skip the f_pos to the
 				   next block. */
 				filp->f_pos = (filp->f_pos &
-					      (sb->s_blocksize - 1)) +
+				              (sb->s_blocksize - 1)) +
 					       sb->s_blocksize;
 				brelse (bh);
 				return stored;
@@ -137,8 +135,8 @@
 				unsigned long version = inode->i_version;
 
 				UFSD(("filldir(%s,%u)\n", de->d_name, SWAB32(de->d_ino)))
-				UFSD(("namlen %u\n", ufs_namlen(de)))
-				error = filldir(dirent, de->d_name, ufs_namlen(de),
+				UFSD(("namlen %u\n", ufs_get_de_namlen(de)))
+				error = filldir(dirent, de->d_name, ufs_get_de_namlen(de),
 						filp->f_pos, SWAB32(de->d_ino));
 				if (error)
 					break;
@@ -172,7 +170,7 @@
 		error_msg = "reclen is smaller than minimal";
 	else if (SWAB16(de->d_reclen) % 4 != 0)
 		error_msg = "reclen % 4 != 0";
-	else if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(ufs_namlen(de)))
+	else if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(ufs_get_de_namlen(de)))
 		error_msg = "reclen is too small for namlen";
 	else if (dir && ((char *) de - bh->b_data) + SWAB16(de->d_reclen) >
 		 dir->i_sb->s_blocksize)
@@ -185,7 +183,7 @@
 			    "offset=%lu, inode=%lu, reclen=%d, namlen=%d",
 			    dir->i_ino, dir->i_size, error_msg, offset,
 			    (unsigned long) SWAB32(de->d_ino),
-			    SWAB16(de->d_reclen), ufs_namlen(de));
+			    SWAB16(de->d_reclen), ufs_get_de_namlen(de));
 	
 	return (error_msg == NULL ? 1 : 0);
 }
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/ialloc.c linux/fs/ufs/ialloc.c
--- v2.1.125/linux/fs/ufs/ialloc.c	Tue Jul 28 14:21:09 1998
+++ linux/fs/ufs/ialloc.c	Tue Oct 20 14:08:14 1998
@@ -34,7 +34,6 @@
 #include "util.h"
 
 #undef UFS_IALLOC_DEBUG
-#undef UFS_IALLOC_DEBUG_MORE
 
 #ifdef UFS_IALLOC_DEBUG
 #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
@@ -42,18 +41,6 @@
 #define UFSD(x)
 #endif
 
-#ifdef UFS_IALLOC_DEBUG_MORE
-#define UFSDM \
-ufs_print_cylinder_stuff (ucg, swab); \
-printk("inode: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nifree), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nifree), SWAB32(ucg->cg_cs.cs_nifree)); \
-printk("block: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nbfree), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nbfree), SWAB32(ucg->cg_cs.cs_nbfree)); \
-printk("fragment: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nffree), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nffree), SWAB32(ucg->cg_cs.cs_nffree)); \
-printk("ndir: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_ndir), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_ndir), SWAB32(ucg->cg_cs.cs_ndir));
-#else
-#define UFSDM
-#endif
-
-
 /*
  * NOTE! When we get the inode, we're the only people
  * that have access to it, and as such there are no
@@ -120,8 +107,6 @@
 	if (!ufs_cg_chkmagic(ucg))
 		ufs_panic (sb, "ufs_free_fragments", "internal error, bad cg magic number");
 
-	UFSDM
-	
 	ucg->cg_time = SWAB32(CURRENT_TIME);
 
 	is_directory = S_ISDIR(inode->i_mode);
@@ -153,8 +138,6 @@
 		ubh_wait_on_buffer (UCPI_UBH);
 	}
 	
-	UFSDM
-	
 	sb->s_dirt = 1;
 	unlock_super (sb);
 	UFSD(("EXIT\n"))
@@ -199,7 +182,7 @@
 	usb1 = ubh_get_usb_first(USPI_UBH);
 
 	inode->i_sb = sb;
-	inode->i_flags = sb->s_flags;
+	inode->i_flags = 0;
 	
 	lock_super (sb);
 
@@ -251,8 +234,6 @@
 	if (!ufs_cg_chkmagic(ucg)) 
 		ufs_panic (sb, "ufs_new_inode", "internal error, bad cg magic number");
 
-	UFSDM
-	
 	start = ucpi->c_irotor;
 	bit = ubh_find_next_zero_bit (UCPI_UBH, ucpi->c_iusedoff, uspi->s_ipg, start);
 	if (!(bit < uspi->s_ipg)) {
@@ -316,8 +297,6 @@
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
 
-	UFSDM
-	
 	unlock_super (sb);
 
 	if(DQUOT_ALLOC_INODE(sb, inode)) {
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/inode.c linux/fs/ufs/inode.c
--- v2.1.125/linux/fs/ufs/inode.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/ufs/inode.c	Tue Oct 20 14:37:01 1998
@@ -53,10 +53,11 @@
 static void ufs_print_inode(struct inode * inode)
 {
 	unsigned swab = inode->i_sb->u.ufs_sb.s_swab;
-	printk("ino %lu  mode 0%6.6o  nlink %d  uid %d  gid %d"
-	       "  size %lu blocks %lu\n",
+	printk("ino %lu  mode 0%6.6o  nlink %d  uid %d  uid32 %u"
+	       "  gid %d  gid32 %u  size %lu blocks %lu\n",
 	       inode->i_ino, inode->i_mode, inode->i_nlink,
-	       inode->i_uid,inode->i_gid, inode->i_size, inode->i_blocks);
+	       inode->i_uid, inode->u.ufs_i.i_uid, inode->i_gid, 
+	       inode->u.ufs_i.i_gid, inode->i_size, inode->i_blocks);
 	printk("  db <%u %u %u %u %u %u %u %u %u %u %u %u>\n",
 		SWAB32(inode->u.ufs_i.i_u1.i_data[0]),
 		SWAB32(inode->u.ufs_i.i_u1.i_data[1]),
@@ -117,7 +118,7 @@
 	 * direct fragment
 	 */
 	if (fragment < UFS_NDIR_FRAGMENT)
-		return ufs_inode_bmap (inode, fragment);
+		return (uspi->s_sbbase + ufs_inode_bmap (inode, fragment));
 
 	/*
 	 * indirect fragment
@@ -128,8 +129,9 @@
 			UFS_IND_FRAGMENT + (fragment >> uspi->s_apbshift));
 		if (!tmp)
 			return 0;
-		return ufs_block_bmap (bread (sb->s_dev, tmp, sb->s_blocksize), 
-			fragment & uspi->s_apbmask, uspi, swab);
+		return (uspi->s_sbbase + 
+			ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize),
+			fragment & uspi->s_apbmask, uspi, swab));
 	}
 
 	/*
@@ -141,12 +143,13 @@
 			UFS_DIND_FRAGMENT + (fragment >> uspi->s_2apbshift));
 		if (!tmp)
 			return 0;
-		tmp = ufs_block_bmap (bread (sb->s_dev, tmp, sb->s_blocksize),
+		tmp = ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize),
 			(fragment >> uspi->s_apbshift) & uspi->s_apbmask, uspi, swab);
 		if (!tmp)
 			return 0;
-		return ufs_block_bmap (bread (sb->s_dev, tmp, sb->s_blocksize),
-			fragment & uspi->s_apbmask, uspi, swab);
+		return (uspi->s_sbbase + 
+			ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize),
+			fragment & uspi->s_apbmask, uspi, swab));
 	}
 
 	/*
@@ -157,16 +160,17 @@
 		UFS_TIND_FRAGMENT + (fragment >> uspi->s_3apbshift));
 	if (!tmp)
 		return 0;
-	tmp = ufs_block_bmap (bread (sb->s_dev, tmp, sb->s_blocksize),
+	tmp = ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize),
 		(fragment >> uspi->s_2apbshift) & uspi->s_apbmask, uspi, swab);
 	if (!tmp)
 		return 0;
-	tmp = ufs_block_bmap (bread (sb->s_dev, tmp, sb->s_blocksize),
+	tmp = ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize),
 		(fragment >> uspi->s_apbshift) & uspi->s_apbmask, uspi, swab);
 	if (!tmp)
 		return 0;
-	return ufs_block_bmap (bread (sb->s_dev, tmp, sb->s_blocksize),
-		fragment & uspi->s_apbmask, uspi, swab);
+	return (uspi->s_sbbase + 
+		ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize),
+		fragment & uspi->s_apbmask, uspi, swab));
 }
 
 static struct buffer_head * ufs_inode_getfrag (struct inode * inode, 
@@ -197,7 +201,7 @@
 	tmp = SWAB32(*p);
 	lastfrag = inode->u.ufs_i.i_lastfrag;
 	if (tmp && fragment < lastfrag) {
-		result = getblk (sb->s_dev, tmp + blockoff, sb->s_blocksize);
+		result = getblk (sb->s_dev, uspi->s_sbbase + tmp + blockoff, sb->s_blocksize);
 		if (tmp == SWAB32(*p)) {
 			UFSD(("EXIT, result %u\n", tmp + blockoff))
 			return result;
@@ -308,7 +312,7 @@
 repeat:
 	tmp = SWAB32(*p);
 	if (tmp) {
-		result = getblk (bh->b_dev, tmp + blockoff, sb->s_blocksize);
+		result = getblk (bh->b_dev, uspi->s_sbbase + tmp + blockoff, sb->s_blocksize);
 		if (tmp == SWAB32(*p)) {
 			brelse (bh);
 			UFSD(("EXIT, result %u\n", tmp + blockoff))
@@ -329,7 +333,6 @@
 	tmp = ufs_new_fragments (inode, p, ufs_blknum(new_fragment), goal, uspi->s_fpb, err);
 	if (!tmp) {
 		if (SWAB32(*p)) {
-			printk("REPEAT\n");
 			goto repeat;
 		}
 		else {
@@ -464,7 +467,7 @@
 		return;
 	}
 	
-	bh = bread (sb->s_dev, ufs_inotofsba(inode->i_ino), sb->s_blocksize);
+	bh = bread (sb->s_dev, uspi->s_sbbase + ufs_inotofsba(inode->i_ino), sb->s_blocksize);
 	if (!bh) {
 		ufs_warning (sb, "ufs_read_inode", "unable to read inode %lu\n", inode->i_ino);
 		return;
@@ -483,11 +486,12 @@
 	 * Linux has only 16-bit uid and gid, so we can't support EFT.
 	 * Files are dynamically chown()ed to root.
 	 */
-	inode->i_uid = ufs_uid(ufs_inode);
-	if (inode->i_uid == UFS_USEEFT) {
+	inode->i_uid = inode->u.ufs_i.i_uid = ufs_get_inode_uid(ufs_inode);
+	inode->i_gid = inode->u.ufs_i.i_gid = ufs_get_inode_gid(ufs_inode);
+	if (inode->u.ufs_i.i_uid >= UFS_USEEFT) {
 		inode->i_uid = 0;
 	}
-	if (inode->i_gid == UFS_USEEFT) {
+	if (inode->u.ufs_i.i_gid >= UFS_USEEFT) {
 		inode->i_gid = 0;
 	}
 	
@@ -510,8 +514,6 @@
 	inode->u.ufs_i.i_flags = SWAB32(ufs_inode->ui_flags);
 	inode->u.ufs_i.i_gen = SWAB32(ufs_inode->ui_gen);
 	inode->u.ufs_i.i_shadow = SWAB32(ufs_inode->ui_u3.ui_sun.ui_shadow);
-	inode->u.ufs_i.i_uid = SWAB32(ufs_inode->ui_u3.ui_sun.ui_uid);
-	inode->u.ufs_i.i_gid = SWAB32(ufs_inode->ui_u3.ui_sun.ui_gid);
 	inode->u.ufs_i.i_oeftflag = SWAB32(ufs_inode->ui_u3.ui_sun.ui_oeftflag);
 	inode->u.ufs_i.i_lastfrag = howmany (inode->i_size, uspi->s_fsize);
 	
@@ -540,8 +542,6 @@
 		inode->i_op = &chrdev_inode_operations;
 	else if (S_ISBLK(inode->i_mode))
 		inode->i_op = &blkdev_inode_operations;
-	else if (S_ISSOCK(inode->i_mode))
-		; /* nothing */
 	else if (S_ISFIFO(inode->i_mode))
 		init_fifo(inode);
 
@@ -558,12 +558,13 @@
 	struct buffer_head * bh;
 	struct ufs_inode * ufs_inode;
 	unsigned i;
-	unsigned swab;
+	unsigned flags, swab;
 
 	UFSD(("ENTER, ino %lu\n", inode->i_ino))
 
 	sb = inode->i_sb;
 	uspi = sb->u.ufs_sb.s_uspi;
+	flags = sb->u.ufs_sb.s_flags;
 	swab = sb->u.ufs_sb.s_swab;
 
 	if (inode->i_ino < UFS_ROOTINO || 
@@ -582,22 +583,15 @@
 	ufs_inode->ui_mode = SWAB16(inode->i_mode);
 	ufs_inode->ui_nlink = SWAB16(inode->i_nlink);
 
-	if (inode->i_uid == 0 && inode->u.ufs_i.i_uid >= UFS_USEEFT) {
-		ufs_inode->ui_u3.ui_sun.ui_uid = SWAB32(inode->u.ufs_i.i_uid);
-		ufs_inode->ui_u1.oldids.ui_suid = (__u16)ufs_inode->ui_u3.ui_sun.ui_uid;
-	}
-	else {
-		ufs_inode->ui_u1.oldids.ui_suid = SWAB16(inode->i_uid);
-		ufs_inode->ui_u3.ui_sun.ui_uid = (__u32) ufs_inode->ui_u1.oldids.ui_suid;
-	}
-	if (inode->i_gid == 0 && inode->u.ufs_i.i_gid >= UFS_USEEFT) {
-		ufs_inode->ui_u3.ui_sun.ui_gid = SWAB32(inode->u.ufs_i.i_gid);
-		ufs_inode->ui_u1.oldids.ui_sgid = (__u16)ufs_inode->ui_u3.ui_sun.ui_gid;
-	}
-	else {
-		ufs_inode->ui_u1.oldids.ui_sgid = SWAB16(inode->i_gid);
-		ufs_inode->ui_u3.ui_sun.ui_gid = (__u32) ufs_inode->ui_u1.oldids.ui_sgid;
-	}
+	if (inode->i_uid == 0 && inode->u.ufs_i.i_uid >= UFS_USEEFT)
+		ufs_set_inode_uid (ufs_inode, inode->u.ufs_i.i_uid);
+	else
+		ufs_set_inode_uid (ufs_inode, inode->i_uid);
+
+	if (inode->i_gid == 0 && inode->u.ufs_i.i_gid >= UFS_USEEFT)
+		ufs_set_inode_gid (ufs_inode, inode->u.ufs_i.i_gid);
+	else
+		ufs_set_inode_gid (ufs_inode, inode->i_gid);
 		
 	ufs_inode->ui_size = SWAB64((u64)inode->i_size);
 	ufs_inode->ui_atime.tv_sec = SWAB32(inode->i_atime);
@@ -607,11 +601,13 @@
 	ufs_inode->ui_mtime.tv_sec = SWAB32(inode->i_mtime);
 	ufs_inode->ui_mtime.tv_usec = SWAB32(0);
 	ufs_inode->ui_blocks = SWAB32(inode->i_blocks);
-
 	ufs_inode->ui_flags = SWAB32(inode->u.ufs_i.i_flags);
 	ufs_inode->ui_gen = SWAB32(inode->u.ufs_i.i_gen);
-	ufs_inode->ui_u3.ui_sun.ui_shadow = SWAB32(inode->u.ufs_i.i_shadow);
-	ufs_inode->ui_u3.ui_sun.ui_oeftflag = SWAB32(inode->u.ufs_i.i_oeftflag);
+
+	if ((flags & UFS_UID_MASK) == UFS_UID_EFT) {
+		ufs_inode->ui_u3.ui_sun.ui_shadow = SWAB32(inode->u.ufs_i.i_shadow);
+		ufs_inode->ui_u3.ui_sun.ui_oeftflag = SWAB32(inode->u.ufs_i.i_oeftflag);
+	}
 
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		ufs_inode->ui_u2.ui_addr.ui_db[0] = SWAB32(kdev_t_to_nr(inode->i_rdev));
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/namei.c linux/fs/ufs/namei.c
--- v2.1.125/linux/fs/ufs/namei.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/ufs/namei.c	Fri Oct 16 11:53:20 1998
@@ -65,10 +65,10 @@
 	/*
 	 * "" means "." ---> so paths like "/usr/lib//libc.a" work
 	 */
-	if (!len && ufs_namlen(de) == 1 && (de->d_name[0] == '.') &&
+	if (!len && ufs_get_de_namlen(de) == 1 && (de->d_name[0] == '.') &&
 	   (de->d_name[1] == '\0'))
 		return 1;
-	if (len != ufs_namlen(de))
+	if (len != ufs_get_de_namlen(de))
 		return 0;
 	return !memcmp(name, de->d_name, len);
 }
@@ -286,7 +286,7 @@
 				de = (struct ufs_dir_entry *) (bh->b_data + fragoff);
 				de->d_ino = SWAB32(0);
 				de->d_reclen = SWAB16(UFS_SECTOR_SIZE);
-				de->d_u.d_namlen = SWAB16(0);
+				ufs_set_de_namlen(de,0);
 				dir->i_size = offset + UFS_SECTOR_SIZE;
 				mark_inode_dirty(dir);
 			} else {
@@ -304,18 +304,18 @@
 				return NULL;
 		}
 		if ((SWAB32(de->d_ino) == 0 && SWAB16(de->d_reclen) >= rec_len) ||
-		    (SWAB16(de->d_reclen) >= UFS_DIR_REC_LEN(SWAB16(de->d_u.d_namlen)) + rec_len)) {
+		    (SWAB16(de->d_reclen) >= UFS_DIR_REC_LEN(ufs_get_de_namlen(de)) + rec_len)) {
 			offset += SWAB16(de->d_reclen);
 			if (SWAB32(de->d_ino)) {
 				de1 = (struct ufs_dir_entry *) ((char *) de +
-					UFS_DIR_REC_LEN(SWAB16(de->d_u.d_namlen)));
+					UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
 				de1->d_reclen = SWAB16(SWAB16(de->d_reclen) -
-					UFS_DIR_REC_LEN(SWAB16(de->d_u.d_namlen)));
-				de->d_reclen = SWAB16(UFS_DIR_REC_LEN(SWAB16(de->d_u.d_namlen)));
+					UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
+				de->d_reclen = SWAB16(UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
 				de = de1;
 			}
 			de->d_ino = SWAB32(0);
-			de->d_u.d_namlen = SWAB16(namelen);
+			ufs_set_de_namlen(de, namelen);
 			memcpy (de->d_name, name, namelen + 1);
 			/*
 			 * XXX shouldn't update any times until successful
@@ -369,7 +369,7 @@
 	de = (struct ufs_dir_entry *) bh->b_data;
 	
 	UFSD(("ino %u, reclen %u, namlen %u, name %s\n", SWAB32(de->d_ino),
-		SWAB16(de->d_reclen), ufs_namlen(de), de->d_name))
+		SWAB16(de->d_reclen), ufs_get_de_namlen(de), de->d_name))
 
 	while (i < bh->b_size) {
 		if (!ufs_check_dir_entry ("ufs_delete_entry", inode, de, bh, i))
@@ -410,11 +410,11 @@
 	struct buffer_head * bh;
 	struct ufs_dir_entry * de;
 	int err = -EIO;
-	unsigned swab;
+	unsigned flags, swab;
 	
 	sb = dir->i_sb;
 	swab = sb->u.ufs_sb.s_swab;
-
+	flags = sb->u.ufs_sb.s_flags;
 	/*
 	 * N.B. Several error exits in ufs_new_inode don't set err.
 	 */
@@ -434,6 +434,7 @@
 		return err;
 	}
 	de->d_ino = SWAB32(inode->i_ino);
+	ufs_set_de_type (de, inode->i_mode);
 	dir->i_version = ++event;
 	mark_buffer_dirty(bh, 1);
 	if (IS_SYNC(dir)) {
@@ -455,9 +456,10 @@
 	struct buffer_head * bh;
 	struct ufs_dir_entry * de;
 	int err = -EIO;
-	unsigned swab;
+	unsigned flags, swab;
 	
 	sb = dir->i_sb;
+	flags = sb->u.ufs_sb.s_flags;
 	swab = sb->u.ufs_sb.s_swab;
 	
 	err = -ENAMETOOLONG;
@@ -493,6 +495,7 @@
 	if (!bh)
 		goto out_no_entry;
 	de->d_ino = SWAB32(inode->i_ino);
+	ufs_set_de_type (de, inode->i_mode);
 	dir->i_version = ++event;
 	mark_buffer_dirty(bh, 1);
 	if (IS_SYNC(dir)) {
@@ -519,9 +522,10 @@
 	struct buffer_head * bh, * dir_block;
 	struct ufs_dir_entry * de;
 	int err;
-	unsigned swab;
+	unsigned flags, swab;
 	
 	sb = dir->i_sb;
+	flags = sb->u.ufs_sb.s_flags;
 	swab = sb->u.ufs_sb.s_swab;
 	
 	err = -ENAMETOOLONG;
@@ -548,13 +552,15 @@
 	inode->i_blocks = sb->s_blocksize / UFS_SECTOR_SIZE;
 	de = (struct ufs_dir_entry *) dir_block->b_data;
 	de->d_ino = SWAB32(inode->i_ino);
-	de->d_u.d_namlen = SWAB16(1);
+	ufs_set_de_type (de, inode->i_mode);
+	ufs_set_de_namlen(de,1);
 	de->d_reclen = SWAB16(UFS_DIR_REC_LEN(1));
 	strcpy (de->d_name, ".");
 	de = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
 	de->d_ino = SWAB32(dir->i_ino);
+	ufs_set_de_type (de, dir->i_mode);
 	de->d_reclen = SWAB16(UFS_SECTOR_SIZE - UFS_DIR_REC_LEN(1));
-	de->d_u.d_namlen = SWAB16(2);
+	ufs_set_de_namlen(de,2);
 	strcpy (de->d_name, "..");
 	inode->i_nlink = 2;
 	mark_buffer_dirty(dir_block, 1);
@@ -567,6 +573,7 @@
 	if (!bh)
 		goto out_no_entry;
 	de->d_ino = SWAB32(inode->i_ino);
+	ufs_set_de_type (de, inode->i_mode);
 	dir->i_version = ++event;
 	mark_buffer_dirty(bh, 1);
 	if (IS_SYNC(dir)) {
@@ -605,7 +612,7 @@
 
 	if (inode->i_size < UFS_DIR_REC_LEN(1) + UFS_DIR_REC_LEN(2) ||
 	    !(bh = ufs_bread (inode, 0, 0, &err))) {
-		ufs_warning (inode->i_sb, "empty_dir",
+	    	ufs_warning (inode->i_sb, "empty_dir",
 			      "bad directory (dir #%lu) - no data block",
 			      inode->i_ino);
 		return 1;
@@ -614,7 +621,7 @@
 	de1 = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
 	if (SWAB32(de->d_ino) != inode->i_ino || !SWAB32(de1->d_ino) || 
 	    strcmp (".", de->d_name) || strcmp ("..", de1->d_name)) {
-		ufs_warning (inode->i_sb, "empty_dir",
+	    	ufs_warning (inode->i_sb, "empty_dir",
 			      "bad directory (dir #%lu) - no `.' or `..'",
 			      inode->i_ino);
 		return 1;
@@ -625,7 +632,7 @@
 		if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
 			brelse (bh);
 			bh = ufs_bread (inode, offset >> sb->s_blocksize_bits, 1, &err);
-			if (!bh) {
+	 		if (!bh) {
 				ufs_error (sb, "empty_dir",
 					    "directory #%lu contains a hole at offset %lu",
 					    inode->i_ino, offset);
@@ -768,7 +775,7 @@
 	retval = -ENOENT;
 	bh = ufs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
 	UFSD(("de: ino %u, reclen %u, namelen %u, name %s\n", SWAB32(de->d_ino),
-		SWAB16(de->d_reclen), ufs_namlen(de), de->d_name))
+		SWAB16(de->d_reclen), ufs_get_de_namlen(de), de->d_name))
 	if (!bh)
 		goto end_unlink;
 
@@ -984,7 +991,7 @@
 	UFSD(("name %s, len %u\n", old_dentry->d_name.name, old_dentry->d_name.len)) 
 	old_bh = ufs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de);
 	UFSD(("ino %u, reclen %u, namlen %u, name %s\n", SWAB32(old_de->d_ino),
-		SWAB16(old_de->d_reclen), ufs_namlen(old_de), old_de->d_name))
+		SWAB16(old_de->d_reclen), ufs_get_de_namlen(old_de), old_de->d_name))
 	    
 	retval = -ENOENT;
 	if (!old_bh)
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/super.c linux/fs/ufs/super.c
--- v2.1.125/linux/fs/ufs/super.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/ufs/super.c	Fri Oct 16 11:53:20 1998
@@ -1,6 +1,35 @@
 /*
  *  linux/fs/ufs/super.c
  *
+ * Copyright (C) 1998
+ * Daniel Pirkl <daniel.pirkl@email.cz>
+ * Charles University, Faculty of Mathematics and Physics
+ */
+
+/* Derivated from
+ *
+ *  linux/fs/ext2/super.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/inode.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ */
+ 
+/*
+ * Inspirated by
+ *
+ *  linux/fs/ufs/super.c
+ *
  * Copyright (C) 1996
  * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
  * Laboratory for Computer Science Research Computing Facility
@@ -28,20 +57,29 @@
  * 
  */
 
+
 #include <linux/module.h>
-#include <linux/init.h>
 
-#include <linux/kernel.h>
+#include <stdarg.h>
+
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
-#include <linux/locks.h>
-#include <asm/uaccess.h>
 #include <linux/malloc.h>
+#include <linux/sched.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/locks.h>
+#include <linux/blkdev.h>
+#include <linux/init.h>
 
 #include "swab.h"
 #include "util.h"
 
-
 #undef UFS_SUPER_DEBUG
 #undef UFS_SUPER_DEBUG_MORE
 
@@ -59,39 +97,41 @@
 	struct ufs_super_block_second * usb2, 
 	struct ufs_super_block_third * usb3, unsigned swab)
 {
-	printk("\nufs_print_super_stuff\n");
-	printk("size of usb:    %lu\n", sizeof(struct ufs_super_block));
-	printk("  magic:        0x%x\n", SWAB32(usb3->fs_magic));
-	printk("  sblkno:       %u\n", SWAB32(usb1->fs_sblkno));
-	printk("  cblkno:       %u\n", SWAB32(usb1->fs_cblkno));
-	printk("  iblkno:       %u\n", SWAB32(usb1->fs_iblkno));
-	printk("  dblkno:       %u\n", SWAB32(usb1->fs_dblkno));
-	printk("  cgoffset:     %u\n", SWAB32(usb1->fs_cgoffset));
-	printk("  ~cgmask:      0x%x\n", ~SWAB32(usb1->fs_cgmask));
-	printk("  size:         %u\n", SWAB32(usb1->fs_size));
-	printk("  dsize:        %u\n", SWAB32(usb1->fs_dsize));
-	printk("  ncg:          %u\n", SWAB32(usb1->fs_ncg));
-	printk("  bsize:        %u\n", SWAB32(usb1->fs_bsize));
-	printk("  fsize:        %u\n", SWAB32(usb1->fs_fsize));
-	printk("  frag:         %u\n", SWAB32(usb1->fs_frag));
-	printk("  fragshift:    %u\n", SWAB32(usb1->fs_fragshift));
-	printk("  ~fmask:       %u\n", ~SWAB32(usb1->fs_fmask));
-	printk("  fshift:       %u\n", SWAB32(usb1->fs_fshift));
-	printk("  sbsize:       %u\n", SWAB32(usb1->fs_sbsize));
-	printk("  spc:          %u\n", SWAB32(usb1->fs_spc));
-	printk("  cpg:          %u\n", SWAB32(usb1->fs_cpg));
-	printk("  ipg:          %u\n", SWAB32(usb1->fs_ipg));
-	printk("  fpg:          %u\n", SWAB32(usb1->fs_fpg));
-	printk("  csaddr:       %u\n", SWAB32(usb1->fs_csaddr));
-	printk("  cssize:       %u\n", SWAB32(usb1->fs_cssize));
-	printk("  cgsize:       %u\n", SWAB32(usb1->fs_cgsize));
-	printk("  fstodb:       %u\n", SWAB32(usb1->fs_fsbtodb));
-	printk("  postblformat: %u\n", SWAB32(usb3->fs_postblformat));
-	printk("  nrpos:        %u\n", SWAB32(usb3->fs_nrpos));
-	printk("  ndir          %u\n", SWAB32(usb1->fs_cstotal.cs_ndir));
-	printk("  nifree        %u\n", SWAB32(usb1->fs_cstotal.cs_nifree));
-	printk("  nbfree        %u\n", SWAB32(usb1->fs_cstotal.cs_nbfree));
-	printk("  nffree        %u\n", SWAB32(usb1->fs_cstotal.cs_nffree));
+	printk("ufs_print_super_stuff\n");
+	printk("size of usb:     %u\n", sizeof(struct ufs_super_block));
+	printk("  magic:         0x%x\n", SWAB32(usb3->fs_magic));
+	printk("  sblkno:        %u\n", SWAB32(usb1->fs_sblkno));
+	printk("  cblkno:        %u\n", SWAB32(usb1->fs_cblkno));
+	printk("  iblkno:        %u\n", SWAB32(usb1->fs_iblkno));
+	printk("  dblkno:        %u\n", SWAB32(usb1->fs_dblkno));
+	printk("  cgoffset:      %u\n", SWAB32(usb1->fs_cgoffset));
+	printk("  ~cgmask:       0x%x\n", ~SWAB32(usb1->fs_cgmask));
+	printk("  size:          %u\n", SWAB32(usb1->fs_size));
+	printk("  dsize:         %u\n", SWAB32(usb1->fs_dsize));
+	printk("  ncg:           %u\n", SWAB32(usb1->fs_ncg));
+	printk("  bsize:         %u\n", SWAB32(usb1->fs_bsize));
+	printk("  fsize:         %u\n", SWAB32(usb1->fs_fsize));
+	printk("  frag:          %u\n", SWAB32(usb1->fs_frag));
+	printk("  fragshift:     %u\n", SWAB32(usb1->fs_fragshift));
+	printk("  ~fmask:        %u\n", ~SWAB32(usb1->fs_fmask));
+	printk("  fshift:        %u\n", SWAB32(usb1->fs_fshift));
+	printk("  sbsize:        %u\n", SWAB32(usb1->fs_sbsize));
+	printk("  spc:           %u\n", SWAB32(usb1->fs_spc));
+	printk("  cpg:           %u\n", SWAB32(usb1->fs_cpg));
+	printk("  ipg:           %u\n", SWAB32(usb1->fs_ipg));
+	printk("  fpg:           %u\n", SWAB32(usb1->fs_fpg));
+	printk("  csaddr:        %u\n", SWAB32(usb1->fs_csaddr));
+	printk("  cssize:        %u\n", SWAB32(usb1->fs_cssize));
+	printk("  cgsize:        %u\n", SWAB32(usb1->fs_cgsize));
+	printk("  fstodb:        %u\n", SWAB32(usb1->fs_fsbtodb));
+	printk("  contigsumsize: %d\n", SWAB32(usb3->fs_u.fs_44.fs_contigsumsize));
+	printk("  postblformat:  %u\n", SWAB32(usb3->fs_postblformat));
+	printk("  nrpos:         %u\n", SWAB32(usb3->fs_nrpos));
+	printk("  ndir           %u\n", SWAB32(usb1->fs_cstotal.cs_ndir));
+	printk("  nifree         %u\n", SWAB32(usb1->fs_cstotal.cs_nifree));
+	printk("  nbfree         %u\n", SWAB32(usb1->fs_cstotal.cs_nbfree));
+	printk("  nffree         %u\n", SWAB32(usb1->fs_cstotal.cs_nffree));
+	printk("\n");
 }
 
 
@@ -101,107 +141,411 @@
 void ufs_print_cylinder_stuff(struct ufs_cylinder_group *cg, unsigned swab)
 {
 	printk("\nufs_print_cylinder_stuff\n");
-	printk("size of ucg: %lu\n", sizeof(struct ufs_cylinder_group));
-	printk("  magic:       %x\n", SWAB32(cg->cg_magic));
-	printk("  time:        %u\n", SWAB32(cg->cg_time));
-	printk("  cgx:         %u\n", SWAB32(cg->cg_cgx));
-	printk("  ncyl:        %u\n", SWAB16(cg->cg_ncyl));
-	printk("  niblk:       %u\n", SWAB16(cg->cg_niblk));
-	printk("  ndblk:       %u\n", SWAB32(cg->cg_ndblk));
-	printk("  cs_ndir:     %u\n", SWAB32(cg->cg_cs.cs_ndir));
-	printk("  cs_nbfree:   %u\n", SWAB32(cg->cg_cs.cs_nbfree));
-	printk("  cs_nifree:   %u\n", SWAB32(cg->cg_cs.cs_nifree));
-	printk("  cs_nffree:   %u\n", SWAB32(cg->cg_cs.cs_nffree));
-	printk("  rotor:       %u\n", SWAB32(cg->cg_rotor));
-	printk("  frotor:      %u\n", SWAB32(cg->cg_frotor));
-	printk("  irotor:      %u\n", SWAB32(cg->cg_irotor));
-	printk("  frsum:       %u, %u, %u, %u, %u, %u, %u, %u\n",
+	printk("size of ucg: %u\n", sizeof(struct ufs_cylinder_group));
+	printk("  magic:        %x\n", SWAB32(cg->cg_magic));
+	printk("  time:         %u\n", SWAB32(cg->cg_time));
+	printk("  cgx:          %u\n", SWAB32(cg->cg_cgx));
+	printk("  ncyl:         %u\n", SWAB16(cg->cg_ncyl));
+	printk("  niblk:        %u\n", SWAB16(cg->cg_niblk));
+	printk("  ndblk:        %u\n", SWAB32(cg->cg_ndblk));
+	printk("  cs_ndir:      %u\n", SWAB32(cg->cg_cs.cs_ndir));
+	printk("  cs_nbfree:    %u\n", SWAB32(cg->cg_cs.cs_nbfree));
+	printk("  cs_nifree:    %u\n", SWAB32(cg->cg_cs.cs_nifree));
+	printk("  cs_nffree:    %u\n", SWAB32(cg->cg_cs.cs_nffree));
+	printk("  rotor:        %u\n", SWAB32(cg->cg_rotor));
+	printk("  frotor:       %u\n", SWAB32(cg->cg_frotor));
+	printk("  irotor:       %u\n", SWAB32(cg->cg_irotor));
+	printk("  frsum:        %u, %u, %u, %u, %u, %u, %u, %u\n",
 	    SWAB32(cg->cg_frsum[0]), SWAB32(cg->cg_frsum[1]),
 	    SWAB32(cg->cg_frsum[2]), SWAB32(cg->cg_frsum[3]),
 	    SWAB32(cg->cg_frsum[4]), SWAB32(cg->cg_frsum[5]),
 	    SWAB32(cg->cg_frsum[6]), SWAB32(cg->cg_frsum[7]));
-	printk("  btotoff:     %u\n", SWAB32(cg->cg_btotoff));
-	printk("  boff:        %u\n", SWAB32(cg->cg_boff));
-	printk("  iuseoff:     %u\n", SWAB32(cg->cg_iusedoff));
-	printk("  freeoff:     %u\n", SWAB32(cg->cg_freeoff));
-	printk("  nextfreeoff: %u\n", SWAB32(cg->cg_nextfreeoff));
+	printk("  btotoff:      %u\n", SWAB32(cg->cg_btotoff));
+	printk("  boff:         %u\n", SWAB32(cg->cg_boff));
+	printk("  iuseoff:      %u\n", SWAB32(cg->cg_iusedoff));
+	printk("  freeoff:      %u\n", SWAB32(cg->cg_freeoff));
+	printk("  nextfreeoff:  %u\n", SWAB32(cg->cg_nextfreeoff));
+	printk("  clustersumoff %u\n", SWAB32(cg->cg_u.cg_44.cg_clustersumoff));
+	printk("  clusteroff    %u\n", SWAB32(cg->cg_u.cg_44.cg_clusteroff));
+	printk("  nclusterblks  %u\n", SWAB32(cg->cg_u.cg_44.cg_nclusterblks));
+	printk("\n");
 }
 #endif /* UFS_SUPER_DEBUG_MORE */
 
+static char error_buf[1024];
+
+void ufs_error (struct super_block * sb, const char * function,
+	const char * fmt, ...)
+{
+	struct ufs_sb_private_info * uspi;
+	struct ufs_super_block_first * usb1;
+	va_list args;
+
+	uspi = sb->u.ufs_sb.s_uspi;
+	usb1 = ubh_get_usb_first(USPI_UBH);
+	
+	if (!(sb->s_flags & MS_RDONLY)) {
+		usb1->fs_clean = UFS_FSBAD;
+		ubh_mark_buffer_dirty(USPI_UBH, 1);
+		sb->s_dirt = 1;
+		sb->s_flags |= MS_RDONLY;
+	}
+	va_start (args, fmt);
+	vsprintf (error_buf, fmt, args);
+	va_end (args);
+	switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_ONERROR) {
+	case UFS_MOUNT_ONERROR_PANIC:
+		panic ("UFS-fs panic (device %s): %s: %s\n", 
+			kdevname(sb->s_dev), function, error_buf);
+
+	case UFS_MOUNT_ONERROR_LOCK:
+	case UFS_MOUNT_ONERROR_UMOUNT:
+	case UFS_MOUNT_ONERROR_REPAIR:
+		printk (KERN_CRIT "UFS-fs error (device %s): %s: %s\n",
+			kdevname(sb->s_dev), function, error_buf);
+	}		
+}
+
+void ufs_panic (struct super_block * sb, const char * function,
+	const char * fmt, ...)
+{
+	struct ufs_sb_private_info * uspi;
+	struct ufs_super_block_first * usb1;
+	va_list args;
+	
+	uspi = sb->u.ufs_sb.s_uspi;
+	usb1 = ubh_get_usb_first(USPI_UBH);
+	
+	if (!(sb->s_flags & MS_RDONLY)) {
+		usb1->fs_clean = UFS_FSBAD;
+		ubh_mark_buffer_dirty(USPI_UBH, 1);
+		sb->s_dirt = 1;
+	}
+	va_start (args, fmt);
+	vsprintf (error_buf, fmt, args);
+	va_end (args);
+	/* this is to prevent panic from syncing this filesystem */
+	if (sb->s_lock)
+		sb->s_lock = 0;
+	sb->s_flags |= MS_RDONLY;
+	printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n",
+		kdevname(sb->s_dev), function, error_buf);
+/*** 
+	panic ("UFS-fs panic (device %s): %s: %s\n", 
+		kdevname(sb->s_dev), function, error_buf);
+***/
+}
+
+void ufs_warning (struct super_block * sb, const char * function,
+	const char * fmt, ...)
+{
+	va_list args;
+
+	va_start (args, fmt);
+	vsprintf (error_buf, fmt, args);
+	va_end (args);
+	printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n",
+		kdevname(sb->s_dev), function, error_buf);
+}
+
+static int ufs_parse_options (char * options, unsigned * mount_options)
+{
+	char * this_char;
+	char * value;
+	
+	UFSD(("ENTER\n"))
+	
+	if (!options)
+		return 1;
+		
+	for (this_char = strtok (options, ",");
+	     this_char != NULL;
+	     this_char = strtok (NULL, ",")) {
+	     
+		if ((value = strchr (this_char, '=')) != NULL)
+			*value++ = 0;
+		if (!strcmp (this_char, "ufstype")) {
+			ufs_clear_opt (*mount_options, UFSTYPE);
+			if (!strcmp (value, "old"))
+				ufs_set_opt (*mount_options, UFSTYPE_OLD);
+			else if (!strcmp (value, "sun"))
+				ufs_set_opt (*mount_options, UFSTYPE_SUN);
+			else if (!strcmp (value, "44bsd"))
+				ufs_set_opt (*mount_options, UFSTYPE_44BSD);
+			else if (!strcmp (value, "next"))
+				ufs_set_opt (*mount_options, UFSTYPE_NEXT);
+			else {
+				printk ("UFS-fs: Invalid type option: %s\n", value);
+				return 0;
+			}
+		}
+		else if (!strcmp (this_char, "onerror")) {
+			ufs_clear_opt (*mount_options, ONERROR);
+			if (!strcmp (value, "panic"))
+				ufs_set_opt (*mount_options, ONERROR_PANIC);
+			else if (!strcmp (value, "lock"))
+				ufs_set_opt (*mount_options, ONERROR_LOCK);
+			else if (!strcmp (value, "umount"))
+				ufs_set_opt (*mount_options, ONERROR_UMOUNT);
+			else if (!strcmp (value, "repair")) {
+				printk("UFS-fs: Unable to do repair on error, "
+					"will lock lock instead \n");
+				ufs_set_opt (*mount_options, ONERROR_REPAIR);
+			}
+			else {
+				printk ("UFS-fs: Invalid action onerror: %s\n", value);
+				return 0;
+			}
+		}
+		else {
+			printk("UFS-fs: Invalid option: %s\n", this_char);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+/*
+ * Read on-disk structures asscoiated with cylinder groups
+ */
+int ufs_read_cylinder_structures (struct super_block * sb) {
+	struct ufs_sb_private_info * uspi;
+	struct ufs_buffer_head * ubh;
+	unsigned char * base, * space;
+	unsigned size, blks, i;
+	unsigned swab;
+	
+	UFSD(("ENTER\n"))
+	
+	uspi = sb->u.ufs_sb.s_uspi;
+	swab = sb->u.ufs_sb.s_swab;
+	
+	/*
+	 * Read cs structures from (usually) first data block
+	 * on the device. 
+	 */
+	size = uspi->s_cssize;
+	blks = howmany(size, uspi->s_fsize);
+	base = space = kmalloc(size, GFP_KERNEL);
+	if (!base)
+		goto failed; 
+	for (i = 0; i < blks; i += uspi->s_fpb) {
+		size = uspi->s_bsize;
+		if (i + uspi->s_fpb > blks)
+			size = (blks - i) * uspi->s_fsize;
+		ubh = ubh_bread(sb->s_dev, uspi->s_csaddr + i, size);
+		if (!ubh)
+			goto failed;
+		ubh_ubhcpymem (space, ubh, size);
+		sb->u.ufs_sb.s_csp[ufs_fragstoblks(i)] = (struct ufs_csum *)space;
+		space += size;
+		ubh_brelse (ubh);
+		ubh = NULL;
+	}
+
+	/*
+	 * Read cylinder group (we read only first fragment from block
+	 * at this time) and prepare internal data structures for cg caching.
+	 */
+	if (!(sb->u.ufs_sb.s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_KERNEL)))
+		goto failed;
+	for (i = 0; i < uspi->s_ncg; i++) 
+		sb->u.ufs_sb.s_ucg[i] = NULL;
+	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
+		sb->u.ufs_sb.s_ucpi[i] = NULL;
+		sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;
+	}
+	for (i = 0; i < uspi->s_ncg; i++) {
+		UFSD(("read cg %u\n", i))
+		if (!(sb->u.ufs_sb.s_ucg[i] = bread (sb->s_dev, ufs_cgcmin(i), sb->s_blocksize)))
+			goto failed;
+		if (!ufs_cg_chkmagic ((struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data))
+			goto failed;
+#ifdef UFS_SUPER_DEBUG_MORE
+		ufs_print_cylinder_stuff((struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data, swab);
+#endif
+	}
+	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
+		if (!(sb->u.ufs_sb.s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL)))
+			goto failed;
+		sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;
+	}
+	sb->u.ufs_sb.s_cg_loaded = 0;
+	UFSD(("EXIT\n"))
+	return 1;
+
+failed:
+	if (base) kfree (base);
+	if (sb->u.ufs_sb.s_ucg) {
+		for (i = 0; i < uspi->s_ncg; i++)
+			if (sb->u.ufs_sb.s_ucg[i]) brelse (sb->u.ufs_sb.s_ucg[i]);
+		kfree (sb->u.ufs_sb.s_ucg);
+		for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
+			if (sb->u.ufs_sb.s_ucpi[i]) kfree (sb->u.ufs_sb.s_ucpi[i]);
+	}
+	UFSD(("EXIT (FAILED)\n"))
+	return 0;
+}
+
 /*
- * Called while file system is mounted, read super block
- * and create important internal structures.
+ * Put on-disk structures associated with cylidner groups and 
+ * write them back to disk
  */
-struct super_block * ufs_read_super (
-	struct super_block * sb,
-	void * data,
+void ufs_put_cylinder_structures (struct super_block * sb) {
+	struct ufs_sb_private_info * uspi;
+	struct ufs_buffer_head * ubh;
+	unsigned char * base, * space;
+	unsigned blks, size, i;
+	
+	UFSD(("ENTER\n"))
+	
+	uspi = sb->u.ufs_sb.s_uspi;
+
+	size = uspi->s_cssize;
+	blks = howmany(size, uspi->s_fsize);
+	base = space = (char*) sb->u.ufs_sb.s_csp[0];
+	for (i = 0; i < blks; i += uspi->s_fpb) {
+		size = uspi->s_bsize;
+		if (i + uspi->s_fpb > blks)
+			size = (blks - i) * uspi->s_fsize;
+		ubh = ubh_bread (sb->s_dev, uspi->s_csaddr + i, size);
+		ubh_memcpyubh (ubh, space, size);
+		space += size;
+		ubh_mark_buffer_uptodate (ubh, 1);
+		ubh_mark_buffer_dirty (ubh, 0);
+		ubh_brelse (ubh);
+	}
+	for (i = 0; i < sb->u.ufs_sb.s_cg_loaded; i++) {
+		ufs_put_cylinder (sb, i);
+		kfree (sb->u.ufs_sb.s_ucpi[i]);
+	}
+	for (; i < UFS_MAX_GROUP_LOADED; i++) 
+		kfree (sb->u.ufs_sb.s_ucpi[i]);
+	for (i = 0; i < uspi->s_ncg; i++) 
+		brelse (sb->u.ufs_sb.s_ucg[i]);
+	kfree (sb->u.ufs_sb.s_ucg);
+	kfree (base);
+	UFSD(("EXIT\n"))
+}
+
+struct super_block * ufs_read_super (struct super_block * sb, void * data,
 	int silent)
 {
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
 	struct ufs_super_block_second * usb2;
 	struct ufs_super_block_third * usb3;
-	struct ufs_buffer_head * ubh;
-	unsigned char * base, * space;
-	unsigned size, blks, i;
+	struct ufs_buffer_head * ubh;	
 	unsigned block_size, super_block_size;
 	unsigned flags, swab;
-	s64 tmp;
-	static unsigned offsets[] = {0, 96, 160};  /* different superblock locations */
-		    
-	UFSD(("ENTER\n"))
-	
+
 	uspi = NULL;
 	ubh = NULL;
-	base = space = NULL;
-	sb->u.ufs_sb.s_ucg = NULL;
 	flags = 0;
+	swab = 0;
 	
-	/* sb->s_dev and sb->s_flags are set by our caller
-	 * data is the mystery argument to sys_mount()
-	 *
-	 * Our caller also sets s_dev, s_covered, s_rd_only, s_dirt,
-	 *   and s_type when we return.
-	 */
-
+	UFSD(("ENTER\n"))
+		
 	MOD_INC_USE_COUNT;
 	lock_super (sb);
 
-	sb->u.ufs_sb.s_uspi = uspi = 
+	/*
+	 * Set default mount options
+	 * Parse mount options
+	 */
+	sb->u.ufs_sb.s_mount_opt = 0;
+	ufs_set_opt (sb->u.ufs_sb.s_mount_opt, ONERROR_LOCK);
+	if (!ufs_parse_options ((char *) data, &sb->u.ufs_sb.s_mount_opt)) {
+		printk("wrong mount options\n");
+		goto failed;
+	}
+	if (!(sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE)) {
+		printk("You didn't specify type of your ufs file system\n\n"
+		"       mount -t ufs -o ufstype=sun|44bsd|old|next ....\n\n"
+		"!!! WARNING !!! wrong value may corrupt you file system\n"
+		"default value is ufstype=old\n");
+		ufs_set_opt (sb->u.ufs_sb.s_mount_opt, UFSTYPE_OLD);
+	}
+
+	sb->u.ufs_sb.s_uspi = uspi =
 		kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL);
 	if (!uspi)
 		goto failed;
+
+	switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) {
+	case UFS_MOUNT_UFSTYPE_44BSD:
+		UFSD(("44bsd ufstype\n"))
+		uspi->s_fsize = block_size = 512;
+		uspi->s_fmask = ~(512 - 1);
+		uspi->s_fshift = 9;
+		uspi->s_sbsize = super_block_size = 1536;
+		uspi->s_sbbase = 0;
+		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
+		break;
+		
+	case UFS_MOUNT_UFSTYPE_SUN:
+		UFSD(("sun  ufstype\n"))
+		uspi->s_fsize = block_size = 1024;
+		uspi->s_fmask = ~(1024 - 1);
+		uspi->s_fshift = 10;
+		uspi->s_sbsize = super_block_size = 2048;
+		uspi->s_sbbase = 0;
+		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;
+		break;
+
+	case UFS_MOUNT_UFSTYPE_OLD:
+		UFSD(("old ufstype\n"))
+		uspi->s_fsize = block_size = 1024;
+		uspi->s_fmask = ~(1024 - 1);
+		uspi->s_fshift = 10;
+		uspi->s_sbsize = super_block_size = 2048;
+		uspi->s_sbbase = 0;
+		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
+		if (!(sb->s_flags & MS_RDONLY)) {
+			printk("old type of ufs is supported read-only\n"); 
+			goto failed;
+		}
+		break;
+	
+	case UFS_MOUNT_UFSTYPE_NEXT:
+		UFSD(("next ufstype\n"))
+		uspi->s_fsize = block_size = 1024;
+		uspi->s_fmask = ~(1024 - 1);
+		uspi->s_fshift = 10;
+		uspi->s_sbsize = super_block_size = 2048;
+		uspi->s_sbbase = 0;
+		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
+		if (!(sb->s_flags & MS_RDONLY)) {
+			printk("nextstep type of ufs is supported read-only\n");
+			goto failed;
+		}
+		break;
 	
-	block_size = BLOCK_SIZE;
-	super_block_size = BLOCK_SIZE * 2;
 	
-	uspi->s_fsize = block_size;
-	uspi->s_fmask = ~(BLOCK_SIZE - 1);
-	uspi->s_fshift = BLOCK_SIZE_BITS;
-	uspi->s_sbsize = super_block_size;
-	i = 0;
-	uspi->s_sbbase = offsets[i];
+	default:
+		printk("this fs type of ufs is not supported\n");
+		goto failed;
+	}
 	
-again:
+	if (!(sb->s_flags & MS_RDONLY))
+		printk("!!! warning !!! write support of ufs is still in experimental state\n"); 
+
+again:	
 	set_blocksize (sb->s_dev, block_size);
 
 	/*
 	 * read ufs super block from device
 	 */
-	ubh = ubh_bread2 (sb->s_dev, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size);
+	ubh = ubh_bread_uspi (uspi, sb->s_dev, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size);
 	if (!ubh) 
 		goto failed;
 	
 	usb1 = ubh_get_usb_first(USPI_UBH);
 	usb2 = ubh_get_usb_second(USPI_UBH);
 	usb3 = ubh_get_usb_third(USPI_UBH);
-	
+
 	/*
 	 * Check ufs magic number
-	 * This code uses goto, because it's a lesser evil than unbalanced
-	 * structure in conditional code. Brought to you by Fare' as a minimal
-	 * hack to live with Daniel's (unnecessary, IMNSHO) manual swab
-	 * optimization -- see swab.h.
 	 */
 #if defined(__LITTLE_ENDIAN) || defined(__BIG_ENDIAN) /* sane bytesex */
 	switch (usb3->fs_magic) {
@@ -222,108 +566,68 @@
 			goto magic_found;
 	}
 #endif
-	/*
-	 * Magic number not found -- try another super block location
-	 */
-	if (++i < sizeof(offsets)/sizeof(unsigned)) {
-		ubh_brelse2(ubh);
+
+	if ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == 
+	UFS_MOUNT_UFSTYPE_NEXT && uspi->s_sbbase < 256) {
+		ubh_brelse_uspi(uspi);
 		ubh = NULL;
-		uspi->s_sbbase = offsets[i];
+		uspi->s_sbbase += 8;
 		goto again;
-	} else {
-		printk("ufs_read_super: "
-		       "super block location not in "
-		       "{ 0, 96, 160} "
-		       "or bad magic number\n");
-		goto failed;
 	}
-	magic_found:
+	printk("ufs_read_super: bad magic number\n");
+	goto failed;
 
+magic_found:
 	/*
 	 * Check block and fragment sizes
 	 */
 	uspi->s_bsize = SWAB32(usb1->fs_bsize);
 	uspi->s_fsize = SWAB32(usb1->fs_fsize);
 	uspi->s_sbsize = SWAB32(usb1->fs_sbsize);
+	uspi->s_fmask = SWAB32(usb1->fs_fmask);
+	uspi->s_fshift = SWAB32(usb1->fs_fshift);
 
 	if (uspi->s_bsize != 4096 && uspi->s_bsize != 8192) {
-		printk("ufs_read_super: fs_bsize %u != {4096, 8192}\n",
-		       uspi->s_bsize);
+		printk("ufs_read_super: fs_bsize %u != {4096, 8192}\n", uspi->s_bsize);
 		goto failed;
 	}
 	if (uspi->s_fsize != 512 && uspi->s_fsize != 1024) {
-		printk("ufs_read_super: fs_fsize %u != {512, 1024}\n",
-		       uspi->s_fsize);
+		printk("ufs_read_super: fs_fsize %u != {512, 1024}\n", uspi->s_fsize);
 		goto failed;
 	}
-	
-	/*
-	 * Block size is not 1024. Free buffers, set block_size and
-	 * super_block_size to superblock-declared values, and try again.
-	 */
 	if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
-		ubh_brelse2(ubh);
+		ubh_brelse_uspi(uspi);
 		ubh = NULL;
-		uspi->s_fmask = SWAB32(usb1->fs_fmask);
-		uspi->s_fshift = SWAB32(usb1->fs_fshift);
 		block_size = uspi->s_fsize;
 		super_block_size = uspi->s_sbsize;
+		UFSD(("another value of block_size or super_block_size %u, %u\n", block_size, super_block_size))
 		goto again;
 	}
 
 #ifdef UFS_SUPER_DEBUG_MORE
 	ufs_print_super_stuff (usb1, usb2, usb3, swab);
 #endif
-	/*
-	 * Check file system flavor
-	 */
-	flags |= UFS_VANILLA;
-	/* XXX more consistency check */
-	UFSD(("ufs_read_super: maxsymlinklen 0x%8.8x\n", usb3->fs_u.fs_44.fs_maxsymlinklen))
-	if (usb3->fs_u.fs_44.fs_maxsymlinklen >= 0) {
-		if (usb3->fs_u.fs_44.fs_inodefmt >= UFS_44INODEFMT) {
-			UFSD(("Flavor: 44BSD\n"))
-			flags |= UFS_44BSD;
-			sb->s_flags |= MS_RDONLY;
-		} else {
-			UFSD(("Flavor: OLD\n"))
-			sb->s_flags |= UFS_OLD;       /* 4.2BSD */
-		}
-	} else if (uspi->s_sbbase > 0) {
-		UFSD(("Flavor: NEXT\n"))
-		flags |= UFS_NEXT;
-		sb->s_flags |= MS_RDONLY;
-	} else {
-		UFSD(("Flavor: SUN\n"))
-		flags |= UFS_SUN;
-	}
 
 	/*
-	 * Check whether file system was correctly unmounted.
+	 * Check, if file system was correctly unmounted.
 	 * If not, make it read only.
 	 */
 	if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
 	    ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
-	    ((flags & UFS_ST_MASK) == UFS_ST_NEXT) ||
-	    (((flags & UFS_ST_MASK) == UFS_ST_SUN) &&
-	    ufs_state(usb3) == UFS_FSOK - usb1->fs_time)) {
+	   (((flags & UFS_ST_MASK) == UFS_ST_SUN) && 
+	     (ufs_get_fs_state(usb3) == (UFS_FSOK - SWAB32(usb1->fs_time))))) {
 		switch(usb1->fs_clean) {
-		case UFS_FSACTIVE:	/* 0x00 */
-			printk("ufs_read_super: fs is active\n");
-			sb->s_flags |= MS_RDONLY;
-			break;
-		case UFS_FSCLEAN:	/* 0x01 */
-			UFSD(("ufs_read_super: fs is clean\n"))
+		case UFS_FSCLEAN:
+			UFSD(("fs is clean\n"))
 			break;
 		case UFS_FSSTABLE:
-			UFSD(("ufs_read_super: fs is stable\n"))
+			UFSD(("fs is stable\n"))
 			break;
-		case UFS_FSOSF1:	/* 0x03 */
-		/* XXX - is this the correct interpretation under DEC OSF/1? */
-			printk("ufs_read_super: "
-			       "fs is clean and stable (OSF/1)\n");
+		case UFS_FSACTIVE:
+			printk("ufs_read_super: fs is active\n");
+			sb->s_flags |= MS_RDONLY;
 			break;
-		case UFS_FSBAD:		/* 0xFF */
+		    case UFS_FSBAD:
 			printk("ufs_read_super: fs is bad\n");
 			sb->s_flags |= MS_RDONLY;
 			break;
@@ -333,19 +637,19 @@
 			sb->s_flags |= MS_RDONLY;
 			break;
 		}
-	} else {
+	}
+	else {
 		printk("ufs_read_super: fs needs fsck\n");
 		sb->s_flags |= MS_RDONLY;
 	}
 
-	sb->s_flags &= ~MS_RDONLY;
 	/*
 	 * Read ufs_super_block into internal data structures
 	 */
 	sb->s_blocksize =  SWAB32(usb1->fs_fsize);
 	sb->s_blocksize_bits = SWAB32(usb1->fs_fshift);
 	sb->s_op = &ufs_super_ops;
-	sb->dq_op = 0; /* XXX */
+	sb->dq_op = NULL; /***/
 	sb->s_magic = SWAB32(usb3->fs_magic);
 
 	uspi->s_sblkno = SWAB32(usb1->fs_sblkno);
@@ -385,12 +689,9 @@
 	uspi->s_ipg = SWAB32(usb1->fs_ipg);
 	uspi->s_fpg = SWAB32(usb1->fs_fpg);
 	uspi->s_cpc = SWAB32(usb2->fs_cpc);
-	((u32 *)&tmp)[0] = usb3->fs_u.fs_sun.fs_qbmask[0];
-	((u32 *)&tmp)[1] = usb3->fs_u.fs_sun.fs_qbmask[1];
-	uspi->s_qbmask = SWAB64(tmp);
-	((u32 *)&tmp)[0] = usb3->fs_u.fs_sun.fs_qfmask[0];
-	((u32 *)&tmp)[1] = usb3->fs_u.fs_sun.fs_qfmask[1];
-	uspi->s_qfmask = SWAB64(tmp);
+	uspi->s_contigsumsize = SWAB32(usb3->fs_u.fs_44.fs_contigsumsize);
+	uspi->s_qbmask = ufs_get_fs_qbmask(usb3);
+	uspi->s_qfmask = ufs_get_fs_qfmask(usb3);
 	uspi->s_postblformat = SWAB32(usb3->fs_postblformat);
 	uspi->s_nrpos = SWAB32(usb3->fs_nrpos);
 	uspi->s_postbloff = SWAB32(usb3->fs_postbloff);
@@ -410,86 +711,32 @@
 	uspi->s_nspfshift = uspi->s_fshift - UFS_SECTOR_BITS;
 	uspi->s_nspb = uspi->s_nspf << uspi->s_fpbshift;
 	uspi->s_inopf = uspi->s_inopb >> uspi->s_fpbshift;
-
-	/* we could merge back s_swab and s_flags by having
-	   foo.s_flags = flags | swab; here, and #defining
-	   s_swab to s_flags & UFS_BYTESEX in swab.h */
+	uspi->s_bpf = uspi->s_fsize << 3;
+	uspi->s_bpfshift = uspi->s_fshift + 3;
+	uspi->s_bpfmask = uspi->s_bpf - 1;
+	
 	sb->u.ufs_sb.s_flags = flags;
 	sb->u.ufs_sb.s_swab = swab;
 	sb->u.ufs_sb.s_rename_lock = 0;
 	sb->u.ufs_sb.s_rename_wait = NULL;
-									  
+	 	                                                          
 	sb->s_root = d_alloc_root(iget(sb, UFS_ROOTINO), NULL);
 
-	/*
-	 * Read cs structures from (usually) first data block
-	 * on the device. 
-	 */
-	size = uspi->s_cssize;
-	blks = howmany(size, uspi->s_fsize);
-	base = space = kmalloc(size, GFP_KERNEL);
-	if (!base)
-		goto failed; 
-	for (i = 0; i < blks; i += uspi->s_fpb) {
-		size = uspi->s_bsize;
-		if (i + uspi->s_fpb > blks)
-			size = (blks - i) * uspi->s_fsize;
-		ubh = ubh_bread(sb->s_dev, uspi->s_csaddr + i, size);
-		if (!ubh)
-			goto failed;
-		ubh_ubhcpymem (space, ubh, size);
-		sb->u.ufs_sb.s_csp[ufs_fragstoblks(i)] = (struct ufs_csum *)space;
-		space += size;
-		ubh_brelse (ubh);
-		ubh = NULL;
-	}
 
 	/*
-	 * Read cylinder group (we read only first fragment from block
-	 * at this time) and prepare internal data structures for cg caching.
-	 * XXX - something here fails on CDROMs from DEC!
+	 * Read cylinder group structures
 	 */
-	if (!(sb->u.ufs_sb.s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_KERNEL)))
-		goto failed;
-	for (i = 0; i < uspi->s_ncg; i++) 
-		sb->u.ufs_sb.s_ucg[i] = NULL;
-	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
-		sb->u.ufs_sb.s_ucpi[i] = NULL;
-		sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;
-	}
-	for (i = 0; i < uspi->s_ncg; i++) {
-		UFSD(("read cg %u\n", i))
-		if (!(sb->u.ufs_sb.s_ucg[i] = bread (sb->s_dev, ufs_cgcmin(i), sb->s_blocksize)))
-			goto failed;
-		if (!ufs_cg_chkmagic ((struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data))
-			goto failed;
-#ifdef UFS_SUPER_DEBUG_MORE
-		ufs_print_cylinder_stuff((struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data, swab);
-#endif
-	}
-	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
-		if (!(sb->u.ufs_sb.s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL)))
+	if (!(sb->s_flags & MS_RDONLY))
+		if (!ufs_read_cylinder_structures(sb))
 			goto failed;
-		sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;
-	}
-	sb->u.ufs_sb.s_cg_loaded = 0;
 
 	unlock_super(sb);
 	UFSD(("EXIT\n"))
 	return(sb);
 
 failed:
-	if (ubh) ubh_brelse2 (ubh);
+	if (ubh) ubh_brelse_uspi (uspi);
 	if (uspi) kfree (uspi);
-	if (base) kfree (base);
-
-	if (sb->u.ufs_sb.s_ucg) {
-		for (i = 0; i < uspi->s_ncg; i++)
-			if (sb->u.ufs_sb.s_ucg[i]) brelse (sb->u.ufs_sb.s_ucg[i]);
-		kfree (sb->u.ufs_sb.s_ucg);
-		for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
-			if (sb->u.ufs_sb.s_ucpi[i]) kfree (sb->u.ufs_sb.s_ucpi[i]);
-	}
 	sb->s_dev = 0;
 	unlock_super (sb);
 	MOD_DEC_USE_COUNT;
@@ -497,187 +744,132 @@
 	return(NULL);
 }
 
-/*
- * Put super block, release internal structures
- */
-void ufs_put_super (struct super_block * sb)
-{
-	struct ufs_sb_private_info * uspi;
-	struct ufs_buffer_head * ubh;
-	unsigned char * base, * space;
-	unsigned size, blks, i;
-	
-	UFSD(("ENTER\n"))
-	
-	uspi = sb->u.ufs_sb.s_uspi;
-	size = uspi->s_cssize;
-	blks = howmany(size, uspi->s_fsize);
-	base = space = (char*) sb->u.ufs_sb.s_csp[0];
-	for (i = 0; i < blks; i += uspi->s_fpb) {
-		size = uspi->s_bsize;
-		if (i + uspi->s_fpb > blks)
-			size = (blks - i) * uspi->s_fsize;
-		ubh = ubh_bread (sb->s_dev, uspi->s_csaddr + i, size);
-		if (!ubh)
-			goto go_on;
-		ubh_memcpyubh (ubh, space, size);
-		space += size;
-		ubh_mark_buffer_uptodate (ubh, 1);
-		ubh_mark_buffer_dirty (ubh, 0);
-		ubh_brelse (ubh);
-	}
-
-go_on:
-	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
-		ufs_put_cylinder (sb, i);
-		kfree (sb->u.ufs_sb.s_ucpi[i]);
-	}
-	for (i = 0; i < uspi->s_ncg; i++) 
-		brelse (sb->u.ufs_sb.s_ucg[i]);
-	kfree (sb->u.ufs_sb.s_ucg);
-	kfree (base);
-	ubh_brelse2 (USPI_UBH);
-	kfree (sb->u.ufs_sb.s_uspi);
-	sb->s_dev = 0;
-	MOD_DEC_USE_COUNT;
-	return;
-}
-
-/*
- * Write super block to device
- */
 void ufs_write_super (struct super_block * sb) {
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
 	struct ufs_super_block_third * usb3;
-	unsigned swab;
-	
+	unsigned flags, swab;
+
 	UFSD(("ENTER\n"))
 	swab = sb->u.ufs_sb.s_swab;
+	flags = sb->u.ufs_sb.s_flags;
 	uspi = sb->u.ufs_sb.s_uspi;
 	usb1 = ubh_get_usb_first(USPI_UBH);
 	usb3 = ubh_get_usb_third(USPI_UBH);
-	
+
 	if (!(sb->s_flags & MS_RDONLY)) {
-		if (SWAB16(usb3->fs_u.fs_sun.fs_state) & UFS_FSOK)
-			usb3->fs_u.fs_sun.fs_state = SWAB16(SWAB16(usb3->fs_u.fs_sun.fs_state) & ~UFS_FSOK);
 		usb1->fs_time = SWAB32(CURRENT_TIME);
-		usb3->fs_u.fs_sun.fs_state = SWAB32(UFS_FSOK - SWAB32(usb1->fs_time));
+		if (usb1->fs_clean == UFS_FSCLEAN && (flags&UFS_ST_MASK) == UFS_ST_SUN)
+			ufs_set_fs_state(usb3, UFS_FSOK - SWAB32(usb1->fs_time));
 		ubh_mark_buffer_dirty (USPI_UBH, 1);
 	}
 	sb->s_dirt = 0;
 	UFSD(("EXIT\n"))
 }
 
-/*
- * Copy some info about file system to user
- */
-int ufs_statfs(struct super_block * sb, struct statfs * buf, int bufsiz)
+void ufs_put_super (struct super_block * sb)
 {
 	struct ufs_sb_private_info * uspi;
-	struct ufs_super_block_first * usb1;
-	struct statfs tmp;
-	struct statfs *sp = &tmp;
-	unsigned long used, avail;
 	unsigned swab;
-	
+		
 	UFSD(("ENTER\n"))
-	
-	swab = sb->u.ufs_sb.s_swab;
-	uspi = sb->u.ufs_sb.s_uspi;
-	usb1 = ubh_get_usb_first (USPI_UBH);
 
-	sp->f_type = UFS_MAGIC;
-	sp->f_bsize = sb->s_blocksize;
-	sp->f_blocks = uspi->s_dsize;
-	sp->f_bfree = (SWAB32(usb1->fs_cstotal.cs_nbfree) << uspi->s_fpbshift )+
-		SWAB32(usb1->fs_cstotal.cs_nffree);
+	uspi = sb->u.ufs_sb.s_uspi;
+	swab = sb->u.ufs_sb.s_swab;
 
-	avail = sp->f_blocks - (sp->f_blocks / 100) * uspi->s_minfree;
-	used = sp->f_blocks - sp->f_bfree;
-	if (avail > used)
-		sp->f_bavail = avail - used;
-	else
-		sp->f_bavail = 0;
-	sp->f_files = uspi->s_ncg * uspi->s_ipg;
-	sp->f_ffree = SWAB32(usb1->fs_cstotal.cs_nifree);
-	sp->f_fsid.val[0] = SWAB32(usb1->fs_id[0]);
-	sp->f_fsid.val[1] = SWAB32(usb1->fs_id[1]);
-	sp->f_namelen = UFS_MAXNAMLEN;
+	if (!(sb->s_flags & MS_RDONLY))
+		ufs_put_cylinder_structures (sb);
 	
-	UFSD(("EXIT\n"))
-
-	return copy_to_user(buf, sp, bufsiz) ? -EFAULT : 0;
+	ubh_brelse_uspi (uspi);
+	kfree (sb->u.ufs_sb.s_uspi);
+	sb->s_dev = 0;
+	MOD_DEC_USE_COUNT;
+	return;
 }
 
 
-static char error_buf[1024];
-
-void ufs_warning (struct super_block * sb, const char * function,
-	const char * fmt, ...)
-{
-	va_list args;
-
-	va_start (args, fmt);
-	vsprintf (error_buf, fmt, args);
-	va_end (args);
-	printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n",
-		kdevname(sb->s_dev), function, error_buf);
-}
-
-void ufs_error (struct super_block * sb, const char * function,
-	const char * fmt, ...)
+int ufs_remount (struct super_block * sb, int * mount_flags, char * data)
 {
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
-	va_list args;
-
+	struct ufs_super_block_third * usb3;
+	unsigned new_mount_opt, ufstype;
+	unsigned flags, swab;
+	
 	uspi = sb->u.ufs_sb.s_uspi;
+	flags = sb->u.ufs_sb.s_flags;
+	swab = sb->u.ufs_sb.s_swab;
 	usb1 = ubh_get_usb_first(USPI_UBH);
+	usb3 = ubh_get_usb_third(USPI_UBH);
 	
-	if (!(sb->s_flags & MS_RDONLY)) {
-		usb1->fs_clean = UFS_FSBAD;
-		ubh_mark_buffer_dirty(USPI_UBH, 1);
-		sb->s_dirt = 1;
+	/*
+	 * Allow the "check" option to be passed as a remount option.
+	 * It is not possible to change ufstype option during remount
+	 */
+	ufstype = sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE;
+	new_mount_opt = 0;
+	ufs_set_opt (new_mount_opt, ONERROR_LOCK);
+	if (!ufs_parse_options (data, &new_mount_opt))
+		return -EINVAL;
+	if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
+		new_mount_opt |= ufstype;
+	}
+	else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
+		printk("ufstype can't be changed during remount\n");
+		return -EINVAL;
+	}
+	sb->u.ufs_sb.s_mount_opt = new_mount_opt;
+
+	if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+		return 0;
+	if (*mount_flags & MS_RDONLY) {
+		ufs_put_cylinder_structures(sb);
+		usb1->fs_time = SWAB32(CURRENT_TIME);
+		if (usb1->fs_clean == UFS_FSCLEAN && (flags&UFS_ST_MASK) == UFS_ST_SUN)
+			ufs_set_fs_state(usb3, UFS_FSOK - SWAB32(usb1->fs_time));
+		ubh_mark_buffer_dirty (USPI_UBH, 1);
+		sb->s_dirt = 0;
 		sb->s_flags |= MS_RDONLY;
 	}
-	va_start (args, fmt);
-	vsprintf (error_buf, fmt, args);
-	va_end (args);
-	printk (KERN_CRIT "UFS-fs error (device %s): %s: %s\n",
-		kdevname(sb->s_dev), function, error_buf);
+	else {
+		if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
+		    ufstype != UFS_MOUNT_UFSTYPE_44BSD) {
+			printk("this ufstype is read-only supported\n");
+			return 0;
+		}
+		if (!ufs_read_cylinder_structures (sb)) {
+			printk("failed during remounting\n");
+			return 0;
+		}
+		sb->s_flags &= ~MS_RDONLY;
+	}
+	return 0;
 }
 
-void ufs_panic (struct super_block * sb, const char * function,
-	const char * fmt, ...)
+int ufs_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
 {
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
-	va_list args;
-	
+	struct statfs tmp;
+	unsigned swab;
+
+	swab = sb->u.ufs_sb.s_swab;
 	uspi = sb->u.ufs_sb.s_uspi;
-	usb1 = ubh_get_usb_first(USPI_UBH);
+	usb1 = ubh_get_usb_first (USPI_UBH);
 	
-	if (!(sb->s_flags & MS_RDONLY)) {
-		usb1->fs_clean = UFS_FSBAD;
-		ubh_mark_buffer_dirty(USPI_UBH, 1);
-		sb->s_dirt = 1;
-	}
-	va_start (args, fmt);
-	vsprintf (error_buf, fmt, args);
-	va_end (args);
-	/* this is to prevent panic from syncing this filesystem */
-	if (sb->s_lock)
-		sb->s_lock = 0;
-	sb->s_flags |= MS_RDONLY;
-	printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n",
-		kdevname(sb->s_dev), function, error_buf);
-/*	panic ("UFS-fs panic (device %s): %s: %s\n", 
-		kdevname(sb->s_dev), function, error_buf);
-*/
+	tmp.f_type = UFS_MAGIC;
+	tmp.f_bsize = sb->s_blocksize;
+	tmp.f_blocks = uspi->s_dsize;
+	tmp.f_bfree = ufs_blkstofrags(SWAB32(usb1->fs_cstotal.cs_nbfree)) +
+		SWAB32(usb1->fs_cstotal.cs_nffree);
+	tmp.f_bavail = (tmp.f_bfree > ((tmp.f_blocks / 100) * uspi->s_minfree))
+		? (tmp.f_bfree - ((tmp.f_blocks / 100) * uspi->s_minfree)) : 0;
+	tmp.f_files = uspi->s_ncg * uspi->s_ipg;
+	tmp.f_ffree = SWAB32(usb1->fs_cstotal.cs_nifree);
+	tmp.f_namelen = UFS_MAXNAMLEN;
+	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
-
 static struct super_operations ufs_super_ops = {
 	ufs_read_inode,
 	ufs_write_inode,
@@ -687,20 +879,19 @@
 	ufs_put_super,
 	ufs_write_super,
 	ufs_statfs,
-	NULL,			/* XXX - ufs_remount() */
+	ufs_remount
 };
 
 static struct file_system_type ufs_fs_type = {
-	"ufs",
+	"ufs", 
 	FS_REQUIRES_DEV,
 	ufs_read_super,
 	NULL
 };
 
-
 __initfunc(int init_ufs_fs(void))
 {
-	return(register_filesystem(&ufs_fs_type));
+	return register_filesystem(&ufs_fs_type);
 }
 
 #ifdef MODULE
@@ -715,5 +906,5 @@
 {
 	unregister_filesystem(&ufs_fs_type);
 }
-#endif
 
+#endif
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/util.c linux/fs/ufs/util.c
--- v2.1.125/linux/fs/ufs/util.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/ufs/util.c	Fri Oct 16 11:53:20 1998
@@ -49,7 +49,7 @@
 	return NULL;
 }
 
-struct ufs_buffer_head * _ubh_bread2_ (struct ufs_sb_private_info * uspi,
+struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi,
 	kdev_t dev, unsigned fragment, unsigned size)
 {
 	unsigned i, j, count;
@@ -82,14 +82,14 @@
 	kfree (ubh);
 }
 
-void ubh_brelse2 (struct ufs_buffer_head * ubh)
+void ubh_brelse_uspi (struct ufs_sb_private_info * uspi)
 {
 	unsigned i;
-	if (!ubh)
+	if (!USPI_UBH)
 		return;
-	for ( i = 0; i < ubh->count; i++ ) {
-		brelse (ubh->bh[i]);
-		ubh->bh[i] = NULL;
+	for ( i = 0; i < USPI_UBH->count; i++ ) {
+		brelse (USPI_UBH->bh[i]);
+		USPI_UBH->bh[i] = NULL;
 	}
 }
 
@@ -138,8 +138,6 @@
 	for ( i = 0; i < ubh->count; i++ ) 
 		if ( ubh->bh[i]->b_count > max )
 			max = ubh->bh[i]->b_count;
-	if (max == 0)
-		printk("Je cosi shnileho v kralovstvi Danskem!\n");
 	return max;
 }
 
diff -u --recursive --new-file v2.1.125/linux/fs/ufs/util.h linux/fs/ufs/util.h
--- v2.1.125/linux/fs/ufs/util.h	Sat Sep  5 16:46:41 1998
+++ linux/fs/ufs/util.h	Tue Oct 20 14:37:01 1998
@@ -19,73 +19,166 @@
 #define max(x,y)		((x)>(y)?(x):(y))
 
 
+
 /*
- * current filesystem state; method depends on flags
+ * macros used for retyping
  */
-#define ufs_state(usb3) \
-	(((flags & UFS_ST_MASK) == UFS_ST_OLD) \
-	? (usb3)->fs_u.fs_sun.fs_state /* old normal way */ \
-	: (usb3)->fs_u.fs_44.fs_state /* 4.4BSD way */)
+#define UCPI_UBH ((struct ufs_buffer_head *)ucpi)
+#define USPI_UBH ((struct ufs_buffer_head *)uspi)
+
+
 
 /*
- * namlen, its format depends of flags
+ * macros used for accesing structures
  */
-#define ufs_namlen(de) _ufs_namlen_(de,flags,swab)
-static inline __u16 _ufs_namlen_(struct ufs_dir_entry * de, unsigned flags, unsigned swab) {
-	if ((flags & UFS_DE_MASK) == UFS_DE_OLD) {
-		return SWAB16(de->d_u.d_namlen);
-	} else /* UFS_DE_44BSD */ {
-		return de->d_u.d_44.d_namlen;
+#define ufs_get_fs_state(usb3) _ufs_get_fs_state_(usb3,flags,swab)
+static inline __s32 _ufs_get_fs_state_(struct ufs_super_block_third * usb3,
+	unsigned flags, unsigned swab)
+{
+	if ((flags & UFS_ST_MASK) == UFS_ST_SUN)
+		return SWAB32((usb3)->fs_u.fs_sun.fs_state);
+	else 
+		return SWAB32((usb3)->fs_u.fs_44.fs_state);
+}
+
+#define ufs_set_fs_state(usb3,value) _ufs_set_fs_state_(usb3,value,flags,swab)
+static inline void _ufs_set_fs_state_(struct ufs_super_block_third * usb3,
+	__s32 value, unsigned flags, unsigned swab)
+{
+	if ((flags & UFS_ST_MASK) == UFS_ST_SUN)
+		(usb3)->fs_u.fs_sun.fs_state = SWAB32(value);
+	else 
+		(usb3)->fs_u.fs_44.fs_state = SWAB32(value);
+}
+
+#define ufs_get_fs_qbmask(usb3) _ufs_get_fs_qbmask_(usb3,flags,swab)
+static inline __u64 _ufs_get_fs_qbmask_(struct ufs_super_block_third * usb3,
+	unsigned flags, unsigned swab)
+{
+	__u64 tmp;
+	if ((flags & UFS_ST_MASK) == UFS_ST_SUN) {
+		((u32 *)&tmp)[0] = usb3->fs_u.fs_sun.fs_qbmask[0];
+		((u32 *)&tmp)[1] = usb3->fs_u.fs_sun.fs_qbmask[1];
 	}
+	else {
+		((u32 *)&tmp)[0] = usb3->fs_u.fs_44.fs_qbmask[0];
+		((u32 *)&tmp)[1] = usb3->fs_u.fs_44.fs_qbmask[1];
+	}
+	return SWAB64(tmp);
 }
 
-/*
- * Here is how the uid is computed:
- * if the file system is 4.2BSD, get it from oldids.
- * if it has sun extension and oldids is USEEFT, get it from ui_sun.
- * if it is 4.4 or Hurd, get it from ui_44 (which is the same as from ui_hurd).
- */
-#define ufs_uid(inode) _ufs_uid_(inode,flags,swab)
-static inline __u32 _ufs_uid_(struct ufs_inode * inode, unsigned flags, unsigned swab) {
+#define ufs_get_fs_qfmask(usb3) _ufs_get_fs_qfmask_(usb3,flags,swab)
+static inline __u64 _ufs_get_fs_qfmask_(struct ufs_super_block_third * usb3,
+	unsigned flags, unsigned swab)
+{
+	__u64 tmp;
+	if ((flags & UFS_ST_MASK) == UFS_ST_SUN) {
+		((u32 *)&tmp)[0] = usb3->fs_u.fs_sun.fs_qfmask[0];
+		((u32 *)&tmp)[1] = usb3->fs_u.fs_sun.fs_qfmask[1];
+	}
+	else {
+		((u32 *)&tmp)[0] = usb3->fs_u.fs_44.fs_qfmask[0];
+		((u32 *)&tmp)[1] = usb3->fs_u.fs_44.fs_qfmask[1];
+	}
+	return SWAB64(tmp);
+}
+
+#define ufs_get_de_namlen(de) \
+	(((flags & UFS_DE_MASK) == UFS_DE_OLD) \
+	? SWAB16(de->d_u.d_namlen) \
+	: de->d_u.d_44.d_namlen)
+
+#define ufs_set_de_namlen(de,value) \
+	(((flags & UFS_DE_MASK) == UFS_DE_OLD) \
+	? (de->d_u.d_namlen = SWAB16(value)) \
+	: (de->d_u.d_44.d_namlen = value))
+
+#define ufs_set_de_type(de,mode) _ufs_set_de_type_(de,mode,flags,swab)
+static inline void _ufs_set_de_type_(struct ufs_dir_entry * de, int mode, 
+	unsigned flags, unsigned swab)
+{
+	if ((flags & UFS_DE_MASK) == UFS_DE_44BSD) {
+		switch (mode & S_IFMT) {
+			case S_IFSOCK: de->d_u.d_44.d_type = DT_SOCK; break;
+			case S_IFLNK: de->d_u.d_44.d_type = DT_LNK; break;
+			case S_IFREG: de->d_u.d_44.d_type = DT_REG; break;
+			case S_IFBLK: de->d_u.d_44.d_type = DT_BLK; break;
+			case S_IFDIR: de->d_u.d_44.d_type = DT_DIR; break;
+			case S_IFCHR: de->d_u.d_44.d_type = DT_CHR; break;
+			case S_IFIFO: de->d_u.d_44.d_type = DT_FIFO; break;
+			default: de->d_u.d_44.d_type = DT_UNKNOWN;
+		}
+	}
+}
+
+#define ufs_get_inode_uid(inode) _ufs_get_inode_uid_(inode,flags,swab)
+static inline __u32 _ufs_get_inode_uid_(struct ufs_inode * inode,
+	unsigned flags, unsigned swab)
+{
 	switch (flags & UFS_UID_MASK) {
 		case UFS_UID_EFT:
 			return SWAB32(inode->ui_u3.ui_sun.ui_uid);
 		case UFS_UID_44BSD:
 			return SWAB32(inode->ui_u3.ui_44.ui_uid);
-		case UFS_UID_OLD:
 		default:
 			return SWAB16(inode->ui_u1.oldids.ui_suid);
 	}
 }
 
-#define ufs_gid(inode) _ufs_gid_(inode,flags,swab)
-static inline __u32 _ufs_gid_(struct ufs_inode * inode, unsigned flags, unsigned swab) {
+#define ufs_set_inode_uid(inode,value) _ufs_set_inode_uid_(inode,value,flags,swab)
+static inline void _ufs_set_inode_uid_(struct ufs_inode * inode, __u32 value,
+	unsigned flags, unsigned swab)
+{
+	inode->ui_u1.oldids.ui_suid = SWAB16(value); 
+	switch (flags & UFS_UID_MASK) {
+		case UFS_UID_EFT:
+			inode->ui_u3.ui_sun.ui_uid = SWAB32(value);
+			break;
+		case UFS_UID_44BSD:
+			inode->ui_u3.ui_44.ui_uid = SWAB32(value);
+			break;
+	}
+}
+
+#define ufs_get_inode_gid(inode) _ufs_get_inode_gid_(inode,flags,swab)
+static inline __u32 _ufs_get_inode_gid_(struct ufs_inode * inode, 
+	unsigned flags, unsigned swab)
+{
 	switch (flags & UFS_UID_MASK) {
 		case UFS_UID_EFT:
 			return SWAB32(inode->ui_u3.ui_sun.ui_gid);
 		case UFS_UID_44BSD:
 			return SWAB32(inode->ui_u3.ui_44.ui_gid);
-		case UFS_UID_OLD:
 		default:
 			return SWAB16(inode->ui_u1.oldids.ui_sgid);
 	}
 }
 
-/*
- * macros used to avoid needless retyping
- */
-#define UCPI_UBH ((struct ufs_buffer_head *)ucpi)
-#define USPI_UBH ((struct ufs_buffer_head *)uspi)
+#define ufs_set_inode_gid(inode,value) _ufs_set_inode_gid_(inode,value,flags,swab)
+static inline void _ufs_set_inode_gid_(struct ufs_inode * inode, __u32 value, 
+	unsigned flags, unsigned swab)
+{
+	inode->ui_u1.oldids.ui_sgid =  SWAB16(value);
+	switch (flags & UFS_UID_MASK) {
+		case UFS_UID_EFT:
+			inode->ui_u3.ui_sun.ui_gid = SWAB32(value);
+			break;
+		case UFS_UID_44BSD:
+			inode->ui_u3.ui_44.ui_gid = SWAB32(value);
+			break;
+	}
+}
+
+
 
 /*
  * These functions manipulate ufs buffers
  */
 #define ubh_bread(dev,fragment,size) _ubh_bread_(uspi,dev,fragment,size)  
 extern struct ufs_buffer_head * _ubh_bread_(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned);
-#define ubh_bread2(dev,fragment,size) _ubh_bread2_(uspi,dev,fragment,size)  
-extern struct ufs_buffer_head * _ubh_bread2_(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned);
+extern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned);
 extern void ubh_brelse (struct ufs_buffer_head *);
-extern void ubh_brelse2 (struct ufs_buffer_head *);
+extern void ubh_brelse_uspi (struct ufs_sb_private_info *);
 extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *, int);
 extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int);
 extern void ubh_ll_rw_block (int, unsigned, struct ufs_buffer_head **);
@@ -98,6 +191,8 @@
 #define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size)
 extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned);
 
+
+
 /*
  * macros to get important structures from ufs_buffer_head
  */
@@ -115,25 +210,29 @@
 #define ubh_get_ucg(ubh) \
 	((struct ufs_cylinder_group *)((ubh)->bh[0]->b_data))
 
+
 /*
  * Extract byte from ufs_buffer_head
  * Extract the bits for a block from a map inside ufs_buffer_head
  */
 #define ubh_get_addr8(ubh,begin) \
-	((u8*)(ubh)->bh[(begin) >> uspi->s_fshift]->b_data + ((begin) & ~uspi->s_fmask))
+	((u8*)(ubh)->bh[(begin) >> uspi->s_fshift]->b_data + \
+	((begin) & ~uspi->s_fmask))
 
 #define ubh_get_addr16(ubh,begin) \
-	(((u16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + ((begin) & (uspi->fsize>>1) - 1)))
+	(((u16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \
+	((begin) & (uspi->fsize>>1) - 1)))
 
 #define ubh_get_addr32(ubh,begin) \
-	(((u32*)((ubh)->bh[(begin) >> (BLOCK_SIZE_BITS-2)]->b_data)) + \
-	((begin) & ((BLOCK_SIZE>>2) - 1)))
+	(((u32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \
+	((begin) & ((uspi->s_fsize>>2) - 1)))
 
 #define ubh_get_addr ubh_get_addr8
 
 #define ubh_blkmap(ubh,begin,bit) \
 	((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb)))
 
+
 /*
  * Macros for access to superblock array structures
  */
@@ -188,45 +287,90 @@
 
 #define ubh_isclr(ubh,begin,bit) (!ubh_isset(ubh,begin,bit))
 
-#define ubh_find_first_zero_bit(ubh,begin,size) \
-	_ubh_find_next_zero_bit_(uspi,ubh,begin,size,0)
-#define ubh_find_next_zero_bit(ubh,begin,size,offset) \
-	_ubh_find_next_zero_bit_(uspi,ubh,begin,size,offset)
+#define ubh_find_first_zero_bit(ubh,begin,size) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,0)
 
+#define ubh_find_next_zero_bit(ubh,begin,size,offset) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,offset)
 static inline unsigned _ubh_find_next_zero_bit_(
 	struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
 	unsigned begin, unsigned size, unsigned offset)
 {
-	unsigned base, rest;
+	unsigned base, count, pos;
 
+	size -= offset;
 	begin <<= 3;
-	size += begin;
 	offset += begin;
-	base = offset >> (uspi->s_fshift + 3);
-	offset &= ((uspi->s_fsize << 3) - 1);
+	base = offset >> uspi->s_bpfshift;
+	offset &= uspi->s_bpfmask;
 	for (;;) {
-		rest = min (size, uspi->s_fsize << 3);
-		size -= rest;
-		offset = ext2_find_next_zero_bit (ubh->bh[base]->b_data, rest, offset);
-		if (offset < rest || !size)
+		count = min (size + offset, uspi->s_bpf);
+		size -= count - offset;
+		pos = ext2_find_next_zero_bit (ubh->bh[base]->b_data, count, offset);
+		if (pos < count + offset || !size)
 			break;
 		base++;
 		offset = 0;
 	}
-	return (base << (uspi->s_fshift + 3)) + offset - begin;
+	return (base << uspi->s_bpfshift) + pos - begin;
 } 	
 
-#define ubh_isblockclear(ubh,begin,block) \
-	(!_ubh_isblockset_(uspi,ubh,begin,block))
-#define ubh_isblockset(ubh,begin,block) \
-	_ubh_isblockset_(uspi,ubh,begin,block)
+static inline unsigned find_last_zero_bit (unsigned char * bitmap,
+	unsigned size, unsigned offset)
+{
+	unsigned bit, i;
+	unsigned char * mapp;
+	unsigned char map;
+
+	mapp = bitmap + (size >> 3);
+	map = *mapp--;
+	bit = 1 << (size & 7);
+	for (i = size; i > offset; i--) {
+		if ((map & bit) == 0)
+			break;
+		if ((i & 7) != 0) {
+			bit >>= 1;
+		} else {
+			map = *mapp--;
+			bit = 1 << 7;
+		}
+	}
+	return i;
+}
+
+#define ubh_find_last_zero_bit(ubh,begin,size,offset) _ubh_find_last_zero_bit_(uspi,ubh,begin,size,offset)
+static inline unsigned _ubh_find_last_zero_bit_(
+	struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
+	unsigned begin, unsigned start, unsigned end)
+{
+	unsigned base, count, pos, size;
 
+	size = start - end;
+	begin <<= 3;
+	start += begin;
+	base = start >> uspi->s_bpfshift;
+	start &= uspi->s_bpfmask;
+	for (;;) {
+		count = min (size + (uspi->s_bpf - start), uspi->s_bpf)
+			- (uspi->s_bpf - start);
+		size -= count;
+		pos = find_last_zero_bit (ubh->bh[base]->b_data,
+			start, start - count);
+		if (pos > start - count || !size)
+			break;
+		base--;
+		start = uspi->s_bpf;
+	}
+	return (base << uspi->s_bpfshift) + pos - begin;
+} 	
+
+#define ubh_isblockclear(ubh,begin,block) (!_ubh_isblockset_(uspi,ubh,begin,block))
+
+#define ubh_isblockset(ubh,begin,block) _ubh_isblockset_(uspi,ubh,begin,block)
 static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
 	struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
 {
 	switch (uspi->s_fpb) {
 	case 8:
-		return (*ubh_get_addr (ubh, begin + block) == 0xff);
+	    	return (*ubh_get_addr (ubh, begin + block) == 0xff);
 	case 4:
 		return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2)));
 	case 2:
@@ -243,8 +387,8 @@
 {
 	switch (uspi->s_fpb) {
 	case 8:
-		*ubh_get_addr (ubh, begin + block) = 0x00;
-		return; 
+	    	*ubh_get_addr (ubh, begin + block) = 0x00;
+	    	return; 
 	case 4:
 		*ubh_get_addr (ubh, begin + (block >> 1)) &= ~(0x0f << ((block & 0x01) << 2));
 		return;
@@ -263,8 +407,8 @@
 {
 	switch (uspi->s_fpb) {
 	case 8:
-		*ubh_get_addr(ubh, begin + block) = 0xff;
-		return;
+	    	*ubh_get_addr(ubh, begin + block) = 0xff;
+	    	return;
 	case 4:
 		*ubh_get_addr(ubh, begin + (block >> 1)) |= (0x0f << ((block & 0x01) << 2));
 		return;
@@ -301,8 +445,7 @@
 		ADD_SWAB32(fraglist[fragsize], cnt);
 }
 
-#define ubh_scanc(ubh,begin,size,table,mask) \
-	_ubh_scanc_(uspi,ubh,begin,size,table,mask)
+#define ubh_scanc(ubh,begin,size,table,mask) _ubh_scanc_(uspi,ubh,begin,size,table,mask)
 static inline unsigned _ubh_scanc_(struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh, 
 	unsigned begin, unsigned size, unsigned char * table, unsigned char mask)
 {
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/asm_offsets.h linux/include/asm-alpha/asm_offsets.h
--- v2.1.125/linux/include/asm-alpha/asm_offsets.h	Wed Sep  9 14:51:09 1998
+++ linux/include/asm-alpha/asm_offsets.h	Mon Oct 12 11:40:12 1998
@@ -6,7 +6,7 @@
 #define TASK_ADDR_LIMIT 24
 #define TASK_EXEC_DOMAIN 32
 #define TASK_NEED_RESCHED 40
-#define TASK_SIZE 1120
+#define TASK_SIZE 1096
 #define STACK_SIZE 16384
 #define HAE_CACHE 0
 #define HAE_REG 8
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/console.h linux/include/asm-alpha/console.h
--- v2.1.125/linux/include/asm-alpha/console.h	Wed Sep  9 14:51:09 1998
+++ linux/include/asm-alpha/console.h	Mon Oct 12 11:40:13 1998
@@ -41,4 +41,15 @@
 #define ENV_LANGUAGE		0x0E
 #define ENV_TTY_DEV		0x0F
 
-#endif
+#ifdef __KERNEL__
+extern long srm_dispatch(long code, ...);
+extern void srm_puts(const char *);
+extern long srm_printk(const char *, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+struct crb_struct;
+struct hwrpb_struct;
+extern long srm_fixup(struct crb_struct *, struct hwrpb_struct *);
+#endif /* __KERNEL__ */
+
+#endif /* __AXP_CONSOLE_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/dma.h linux/include/asm-alpha/dma.h
--- v2.1.125/linux/include/asm-alpha/dma.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/dma.h	Tue Oct 20 09:43:21 1998
@@ -20,6 +20,7 @@
 
 #include <linux/config.h>
 #include <asm/io.h>
+#include <asm/spinlock.h>
 
 #define dma_outb	outb
 #define dma_inb		inb
@@ -171,6 +172,20 @@
 #define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
 #define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
 #define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+extern spinlock_t  dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
 
 /* enable/disable a specific DMA channel */
 static __inline__ void enable_dma(unsigned int dmanr)
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/fcntl.h linux/include/asm-alpha/fcntl.h
--- v2.1.125/linux/include/asm-alpha/fcntl.h	Wed Aug 26 11:37:44 1998
+++ linux/include/asm-alpha/fcntl.h	Wed Oct 21 10:02:48 1998
@@ -18,6 +18,8 @@
 #define O_SYNC		040000
 #define FASYNC		020000	/* fcntl, for BSD compatibility */
 #define O_DIRECT	040000	/* direct disk access - should check with OSF/1 */
+#define O_DIRECTORY	0100000	/* must be a directory */
+#define O_NOFOLLOW	0200000 /* don't follow links */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/hardirq.h linux/include/asm-alpha/hardirq.h
--- v2.1.125/linux/include/asm-alpha/hardirq.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/hardirq.h	Mon Oct 12 11:40:13 1998
@@ -6,6 +6,7 @@
 #include <linux/tasks.h>
 
 extern unsigned int local_irq_count[NR_CPUS];
+extern unsigned long hardirq_no[NR_CPUS];
 
 /*
  * Are we in an interrupt context? Either doing bottom half
@@ -32,6 +33,7 @@
 
 #include <asm/atomic.h>
 #include <asm/spinlock.h>
+#include <asm/smp.h>
 
 extern int global_irq_holder;
 extern spinlock_t global_irq_lock;
@@ -50,10 +52,12 @@
 {
 	++local_irq_count[cpu];
         atomic_inc(&global_irq_count);
+	hardirq_no[cpu] |= 1L << irq;		/* debugging only */
 }
 
 static inline void hardirq_exit(int cpu, int irq)
 {
+	hardirq_no[cpu] &= ~(1L << irq);	/* debugging only */
 	atomic_dec(&global_irq_count);
         --local_irq_count[cpu];
 }
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/hwrpb.h linux/include/asm-alpha/hwrpb.h
--- v2.1.125/linux/include/asm-alpha/hwrpb.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/hwrpb.h	Mon Oct 12 11:40:13 1998
@@ -185,6 +185,19 @@
 	unsigned long dsr_offset;	/* "Dynamic System Recognition Data Block Table" */
 };
 
+#ifdef __KERNEL__
+
 extern struct hwrpb_struct *hwrpb;
+
+static inline void
+hwrpb_update_checksum(struct hwrpb_struct *h)
+{
+	unsigned long sum = 0, *l;
+        for (l = (unsigned long *) h; l < (unsigned long *) &h->chksum; ++l)
+                sum += *l;
+        h->chksum = sum;
+}
+
+#endif /* __KERNEL__ */
 
 #endif /* __ALPHA_HWRPB_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h
--- v2.1.125/linux/include/asm-alpha/io.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/io.h	Mon Oct 12 11:40:13 1998
@@ -323,23 +323,14 @@
 
 #ifdef CONFIG_ALPHA_GENERIC
 # define RTC_PORT(x)	((x) + alpha_mv.rtc_port)
-# define RTC_ADDR(x)	((x) | alpha_mv.rtc_addr)
-# define RTC_ALWAYS_BCD	(alpha_mv.rtc_bcd)
 #else
 # ifdef CONFIG_ALPHA_JENSEN
 #  define RTC_PORT(x)	(0x170+(x))
-#  define RTC_ADDR(x)	(x)
 # else
 #  define RTC_PORT(x)	(0x70 + (x))
-#  define RTC_ADDR(x)	(0x80 | (x))
-# endif
-# ifdef CONFIG_ALPHA_RUFFIAN
-#  define RTC_ALWAYS_BCD	1
-# else
-#  define RTC_ALWAYS_BCD	0
 # endif
 #endif
-
+#define RTC_ALWAYS_BCD	0
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/machvec.h linux/include/asm-alpha/machvec.h
--- v2.1.125/linux/include/asm-alpha/machvec.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/machvec.h	Mon Oct 12 11:40:13 1998
@@ -22,11 +22,9 @@
 	unsigned long hae_cache;
 	unsigned long *hae_register;
 
-	unsigned int nr_irqs  : 16;
-	unsigned int rtc_port : 16;
-	unsigned int rtc_addr : 15;
-	unsigned int rtc_bcd  : 1;
-	unsigned int max_asn  : 16;
+	int nr_irqs;
+	int rtc_port;
+	int max_asn;
 	unsigned long max_dma_address;
 	unsigned long mmu_context_mask;
 	unsigned long irq_probe_mask;
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
--- v2.1.125/linux/include/asm-alpha/processor.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/processor.h	Mon Oct 12 11:40:13 1998
@@ -59,7 +59,9 @@
 	mm_segment_t fs;
 
 	/* Breakpoint handling for ptrace.  */
-	long debugreg[8];
+	unsigned long bpt_addr[2];
+	unsigned int bpt_insn[2];
+	int bpt_nsaved;
 };
 
 #define INIT_MMAP { &init_mm, PAGE_OFFSET,  PAGE_OFFSET+0x10000000, \
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h
--- v2.1.125/linux/include/asm-alpha/spinlock.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/spinlock.h	Mon Oct 12 11:40:13 1998
@@ -63,15 +63,24 @@
  */
 
 typedef struct {
-	volatile unsigned long lock;
+	volatile unsigned int lock;
+#if DEBUG_SPINLOCK
+	char debug_state, target_ipl, saved_ipl, on_cpu;
 	void *previous;
 	struct task_struct * task;
+#endif
 } spinlock_t;
 
-#define SPIN_LOCK_UNLOCKED { 0, 0, 0 }
+#if DEBUG_SPINLOCK
+#define SPIN_LOCK_UNLOCKED {0, 1, 0, 0, 0, 0}
+#define spin_lock_init(x)						\
+	((x)->lock = 0, (x)->target_ipl = 0, (x)->debug_state = 1,	\
+	 (x)->previous = 0, (x)->task = 0)
+#else
+#define SPIN_LOCK_UNLOCKED	{ 0 }
+#define spin_lock_init(x)	((x)->lock = 0)
+#endif
 
-#define spin_lock_init(x) \
-	((x)->lock = 0, (x)->previous = 0, (x)->task = 0)
 #define spin_unlock_wait(x) \
 	({ do { barrier(); } while(((volatile spinlock_t *)x)->lock); })
 
@@ -79,8 +88,25 @@
 #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
 
 #if DEBUG_SPINLOCK
+extern void spin_unlock(spinlock_t * lock);
 extern void spin_lock(spinlock_t * lock);
+extern int spin_trylock(spinlock_t * lock);
+
+#define spin_lock_own(LOCK, LOCATION)					\
+do {									\
+	if (!((LOCK)->lock && (LOCK)->on_cpu == smp_processor_id()))	\
+		printk("%s: called on %d from %p but lock %s on %d\n",	\
+		       LOCATION, smp_processor_id(),			\
+		       __builtin_return_address(0),			\
+		       (LOCK)->lock ? "taken" : "freed", (LOCK)->on_cpu); \
+} while (0)
 #else
+static inline void spin_unlock(spinlock_t * lock)
+{
+	mb();
+	lock->lock = 0;
+}
+
 static inline void spin_lock(spinlock_t * lock)
 {
 	long tmp;
@@ -89,29 +115,24 @@
 	   of this object file's text section so as to perfect
 	   branch prediction.  */
 	__asm__ __volatile__(
-	"1:	ldq_l	%0,%1\n"
+	"1:	ldl_l	%0,%1\n"
 	"	blbs	%0,2f\n"
 	"	or	%0,1,%0\n"
-	"	stq_c	%0,%1\n"
+	"	stl_c	%0,%1\n"
 	"	beq	%0,2f\n"
 	"	mb\n"
 	".section .text2,\"ax\"\n"
-	"2:	ldq	%0,%1\n"
+	"2:	ldl	%0,%1\n"
 	"	blbs	%0,2b\n"
 	"	br	1b\n"
 	".previous"
 	: "=r" (tmp), "=m" (__dummy_lock(lock))
 	: "m"(__dummy_lock(lock)));
 }
-#endif /* DEBUG_SPINLOCK */
-
-static inline void spin_unlock(spinlock_t * lock)
-{
-	mb();
-	lock->lock = 0;
-}
 
 #define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
+#define spin_lock_own(LOCK, LOCATION)	((void)0)
+#endif /* DEBUG_SPINLOCK */
 
 #define spin_lock_irq(lock) \
   (__cli(), spin_lock(lock))
diff -u --recursive --new-file v2.1.125/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v2.1.125/linux/include/asm-alpha/system.h	Wed Sep  9 14:51:10 1998
+++ linux/include/asm-alpha/system.h	Mon Oct 12 11:40:13 1998
@@ -95,8 +95,7 @@
 extern unsigned long whami(void);
 extern void wripir(unsigned long);
 
-#define halt() \
-__asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt) : "memory")
+extern void halt(void) __attribute__((noreturn));
 
 #define switch_to(prev,next) do {					\
 	current = next;							\
diff -u --recursive --new-file v2.1.125/linux/include/asm-arm/fcntl.h linux/include/asm-arm/fcntl.h
--- v2.1.125/linux/include/asm-arm/fcntl.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-arm/fcntl.h	Wed Oct 21 13:30:46 1998
@@ -16,6 +16,8 @@
 #define O_NDELAY	O_NONBLOCK
 #define O_SYNC		010000
 #define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
diff -u --recursive --new-file v2.1.125/linux/include/asm-i386/fcntl.h linux/include/asm-i386/fcntl.h
--- v2.1.125/linux/include/asm-i386/fcntl.h	Wed Aug 26 11:37:44 1998
+++ linux/include/asm-i386/fcntl.h	Wed Oct 21 10:02:48 1998
@@ -18,6 +18,8 @@
 #define FASYNC		 020000	/* fcntl, for BSD compatibility */
 #define O_DIRECT	 040000	/* direct disk access hint - currently ignored */
 #define O_LARGEFILE	0100000
+#define O_DIRECTORY	0200000	/* must be a directory */
+#define O_NOFOLLOW	0400000 /* don't follow links */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
diff -u --recursive --new-file v2.1.125/linux/include/asm-m68k/fcntl.h linux/include/asm-m68k/fcntl.h
--- v2.1.125/linux/include/asm-m68k/fcntl.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-m68k/fcntl.h	Wed Oct 21 13:30:56 1998
@@ -16,6 +16,8 @@
 #define O_NDELAY	O_NONBLOCK
 #define O_SYNC		010000
 #define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/bootinfo.h linux/include/asm-mips/bootinfo.h
--- v2.1.125/linux/include/asm-mips/bootinfo.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/bootinfo.h	Tue Oct 20 13:52:53 1998
@@ -1,4 +1,5 @@
-/*
+/* $Id: bootinfo.h,v 1.5 1998/08/19 21:58:10 ralf Exp $
+ *
  * bootinfo.h -- Definition of the Linux/MIPS boot information structure
  *
  * Copyright (C) 1995, 1996 by Ralf Baechle, Andreas Busse,
@@ -7,8 +8,6 @@
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
- *
- * $Id: bootinfo.h,v 1.7 1998/05/01 01:35:46 ralf Exp $
  */
 #ifndef __ASM_MIPS_BOOTINFO_H
 #define __ASM_MIPS_BOOTINFO_H
@@ -126,7 +125,7 @@
 
 #define CL_SIZE      (80)
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 
 /*
  * Some machine parameters passed by the bootloaders. 
@@ -266,20 +265,18 @@
 
 
 #ifdef CONFIG_SGI
-
 /* screen info will dissapear... soon */
-#define DEFAULT_SCREEN_INFO {0, 0, {0, 0, }, 0, 0, 158, 0, 0, 0, 62, 0, 16}
+//#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 158, 0, 0, 0, 62, 0, 16}
+#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 160, 0, 0, 0, 64, 0, 16}
 #define DEFAULT_DRIVE_INFO { {0,}}
-
 #else
-
 /* default values for screen_info variable */
-#define DEFAULT_SCREEN_INFO {0, 0, {0, }, 52, 3, 80, 4626, 3, 9, 50}
+#define DEFAULT_SCREEN_INFO {0, 0, 0, 52, 3, 80, 4626, 3, 9, 50}
+#endif
+
 /* default values for drive info */
 #define DEFAULT_DRIVE_INFO { {0,}}
 
-#endif
-
 
 /*
  * These are the kernel variables initialized from
@@ -296,6 +293,6 @@
 extern unsigned long mips_dma_cache_size;
 extern unsigned long mips_dma_cache_base;
 
-#endif /* __LANGUAGE_ASSEMBLY__ */
+#endif /* _LANGUAGE_ASSEMBLY */
 
 #endif /* __ASM_MIPS_BOOTINFO_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/checksum.h linux/include/asm-mips/checksum.h
--- v2.1.125/linux/include/asm-mips/checksum.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/checksum.h	Tue Oct 20 13:52:53 1998
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.8 1998/05/07 00:39:59 ralf Exp $
+/* $Id: checksum.h,v 1.6 1998/09/16 13:30:51 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -27,8 +27,7 @@
  * this is a new version of the above that records errors it finds in *errp,
  * but continues and zeros the rest of the buffer.
  */
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len,
-                                       unsigned int sum);
+#define csum_partial_copy_nocheck csum_partial_copy
 
 /*
  * this is a new version of the above that records errors it finds in *errp,
@@ -36,6 +35,10 @@
  */
 unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
                                          unsigned int sum, int *errp);
+
+#define HAVE_CSUM_COPY_USER
+unsigned int csum_and_copy_to_user (const char *src, char *dst,
+                                    int len, int sum, int *err_ptr);
 
 /*
  * the same as csum_partial, but copies from user space (but on MIPS
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/current.h linux/include/asm-mips/current.h
--- v2.1.125/linux/include/asm-mips/current.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/current.h	Tue Oct 20 13:52:53 1998
@@ -1,13 +1,21 @@
+/* $Id: current.h,v 1.4 1998/07/20 17:52:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Ralf Baechle
+ */
 #ifndef __ASM_MIPS_CURRENT_H
 #define __ASM_MIPS_CURRENT_H
 
-#ifdef __LANGUAGE_C__
+#ifdef _LANGUAGE_C
 
 /* MIPS rules... */
 register struct task_struct *current asm("$28");
 
-#endif /* __LANGUAGE_C__ */
-#ifdef __LANGUAGE_ASSEMBLY__
+#endif /* _LANGUAGE_C */
+#ifdef _LANGUAGE_ASSEMBLY
 
 /*
  * Special variant for use by exception handlers when the stack pointer
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/dma.h linux/include/asm-mips/dma.h
--- v2.1.125/linux/include/asm-mips/dma.h	Wed Dec 10 10:31:10 1997
+++ linux/include/asm-mips/dma.h	Tue Oct 20 13:52:53 1998
@@ -1,4 +1,4 @@
-/* $Id: dma.h,v 1.1.1.1 1997/06/01 03:17:12 ralf Exp $
+/* $Id: dma.h,v 1.2 1998/10/19 21:29:10 ralf Exp $
  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
  * Written by Hennus Bergman, 1992.
  * High DMA channel support & info by Hannu Savolainen
@@ -14,6 +14,8 @@
 
 #include <linux/config.h>
 #include <asm/io.h>			/* need byte IO */
+#include <asm/spinlock.h>		/* And spinlocks */
+#include <linux/delay.h>
 
 
 #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
@@ -143,6 +145,21 @@
 #define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
 #define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
 
+
+extern spinlock_t  dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
 /* enable/disable a specific DMA channel */
 static __inline__ void enable_dma(unsigned int dmanr)
 {
@@ -158,6 +175,8 @@
 		dma_outb(dmanr | 4,  DMA1_MASK_REG);
 	else
 		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
+	/* I hate voodoo programming but .. */
+	udelay(20);
 }
 
 /* Clear the 'DMA Pointer Flip Flop'.
@@ -165,7 +184,7 @@
  * Use this once to initialize the FF to a known state.
  * After that, keep track of it. :-)
  * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
+ * --- only be used while holding the DMA lock ! ---
  */
 static __inline__ void clear_dma_ff(unsigned int dmanr)
 {
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/ds1286.h linux/include/asm-mips/ds1286.h
--- v2.1.125/linux/include/asm-mips/ds1286.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/ds1286.h	Tue Oct 20 13:52:53 1998
@@ -0,0 +1,69 @@
+/* $Id: ds1286.h,v 1.1 1998/07/09 20:01:30 ralf Exp $
+ *
+ * mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
+ * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
+ * derived from Data Sheet, Copyright Motorola 1984 (!).
+ * It was written to be part of the Linux operating system.
+ */
+/* permission is hereby granted to copy, modify and redistribute this code
+ * in terms of the GNU Library General Public License, Version 2 or later,
+ * at your option.
+ */
+#ifndef _MC146818RTC_H
+#define _MC146818RTC_H
+
+#include <asm/mc146818rtc.h>
+
+/**********************************************************************
+ * register summary
+ **********************************************************************/
+#define RTC_HUNDREDTH_SECOND	0
+#define RTC_SECONDS		1
+#define RTC_MINUTES		2
+#define RTC_MINUTES_ALARM	3
+#define RTC_HOURS		4
+#define RTC_HOURS_ALARM		5
+#define RTC_DAY			6
+#define RTC_DAY_ALARM		7
+#define RTC_DATE		8
+#define RTC_MONTH		9
+#define RTC_YEAR		10
+#define RTC_CMD			11
+#define RTC_WHSEC		12
+#define RTC_WSEC		13
+#define RTC_UNUSED		14
+
+/* RTC_*_alarm is always true if 2 MSBs are set */
+# define RTC_ALARM_DONT_CARE 	0xC0
+
+
+/*
+ * Bits in the month register
+ */
+#define RTC_EOSC		0x80
+#define RTC_ESQW		0x40
+
+/*
+ * Bits in the Command register
+ */
+#define RTC_TDF			0x01
+#define RTC_WAF			0x02
+#define RTC_TDM			0x04
+#define RTC_WAM			0x08
+#define RTC_PU_LVL		0x10
+#define RTC_IBH_LO		0x20
+#define RTC_IPSW		0x40
+#define RTC_TE			0x80
+
+/*
+ * Conversion between binary and BCD.
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+#endif /* _MC146818RTC_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/fcntl.h linux/include/asm-mips/fcntl.h
--- v2.1.125/linux/include/asm-mips/fcntl.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-mips/fcntl.h	Wed Oct 21 10:04:28 1998
@@ -1,3 +1,11 @@
+/* $Id: fcntl.h,v 1.3 1998/08/29 20:41:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
+ */
 #ifndef __ASM_MIPS_FCNTL_H
 #define __ASM_MIPS_FCNTL_H
 
@@ -15,6 +23,10 @@
 #define O_EXCL		0x0400	/* not fcntl */
 #define O_NOCTTY	0x0800	/* not fcntl */
 #define FASYNC		0x1000	/* fcntl, for BSD compatibility */
+#define O_LARGEFILE	0x2000	/* allow large file opens - currently ignored */
+#define O_NOFOLLOW	0x4000	/* Don't follow symbolic links */
+#define O_DIRECT	0x8000	/* direct disk access hint - currently ignored */
+#define O_DIRECTORY	0x10000	/* must be a directory */
 
 #define O_NDELAY	O_NONBLOCK
 
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/floppy.h linux/include/asm-mips/floppy.h
--- v2.1.125/linux/include/asm-mips/floppy.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/floppy.h	Tue Oct 20 13:52:53 1998
@@ -1,13 +1,12 @@
-/*
+/* $Id: floppy.h,v 1.4 1998/05/07 18:38:41 ralf Exp $
+ *
  * Architecture specific parts of the Floppy driver
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997 Ralf Baechle
- *
- * $Id: floppy.h,v 1.14 1998/05/01 01:35:52 ralf Exp $
+ * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle
  */
 #ifndef __ASM_MIPS_FLOPPY_H
 #define __ASM_MIPS_FLOPPY_H
@@ -17,72 +16,60 @@
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
 #include <asm/mipsconfig.h>
-#include <asm/vector.h>
 
-#define fd_inb(port)			feature->fd_inb(port)
-#define fd_outb(value,port)		feature->fd_outb(value,port)
-
-#define fd_enable_dma(channel)		feature->fd_enable_dma(channel)
-#define fd_disable_dma(channel)		feature->fd_disable_dma(channel)
-#define fd_request_dma(channel)		feature->fd_request_dma(channel)
-#define fd_free_dma(channel)		feature->fd_free_dma(channel)
-#define fd_clear_dma_ff(channel)	feature->fd_clear_dma_ff(channel)
-#define fd_set_dma_mode(channel, mode)	feature->fd_set_dma_mode(channel, mode)
-#define fd_set_dma_addr(channel, addr)	feature->fd_set_dma_addr(channel, \
+struct fd_ops {
+	unsigned char (*fd_inb)(unsigned int port);
+	void (*fd_outb)(unsigned char value, unsigned int port);
+
+	/*
+	 * How to access the floppy DMA functions.
+	 */
+	void (*fd_enable_dma)(int channel);
+	void (*fd_disable_dma)(int channel);
+	int (*fd_request_dma)(int channel);
+	void (*fd_free_dma)(int channel);
+	void (*fd_clear_dma_ff)(int channel);
+	void (*fd_set_dma_mode)(int channel, char mode);
+	void (*fd_set_dma_addr)(int channel, unsigned int a);
+	void (*fd_set_dma_count)(int channel, unsigned int count);
+	int (*fd_get_dma_residue)(int channel);
+	void (*fd_enable_irq)(int irq);
+	void (*fd_disable_irq)(int irq);
+	unsigned long (*fd_getfdaddr1)(void);
+	unsigned long (*fd_dma_mem_alloc)(unsigned long size);
+	void (*fd_dma_mem_free)(unsigned long addr, unsigned long size);
+	unsigned long (*fd_drive_type)(unsigned long);
+};
+
+extern struct fd_ops *fd_ops;
+
+#define fd_inb(port)			fd_ops->fd_inb(port)
+#define fd_outb(value,port)		fd_ops->fd_outb(value,port)
+
+#define fd_enable_dma(channel)		fd_ops->fd_enable_dma(channel)
+#define fd_disable_dma(channel)		fd_ops->fd_disable_dma(channel)
+#define fd_request_dma(channel)		fd_ops->fd_request_dma(channel)
+#define fd_free_dma(channel)		fd_ops->fd_free_dma(channel)
+#define fd_clear_dma_ff(channel)	fd_ops->fd_clear_dma_ff(channel)
+#define fd_set_dma_mode(channel, mode)	fd_ops->fd_set_dma_mode(channel, mode)
+#define fd_set_dma_addr(channel, addr)	fd_ops->fd_set_dma_addr(channel, \
 					         virt_to_bus(addr))
-#define fd_set_dma_count(channel,count)	feature->fd_set_dma_count(channel,count)
-#define fd_get_dma_residue(channel)	feature->fd_get_dma_residue(channel)
+#define fd_set_dma_count(channel,count)	fd_ops->fd_set_dma_count(channel,count)
+#define fd_get_dma_residue(channel)	fd_ops->fd_get_dma_residue(channel)
 
-#define fd_enable_irq(irq)		feature->fd_enable_irq(irq)
-#define fd_disable_irq(irq)		feature->fd_disable_irq(irq)
+#define fd_enable_irq(irq)		fd_ops->fd_enable_irq(irq)
+#define fd_disable_irq(irq)		fd_ops->fd_disable_irq(irq)
 #define fd_request_irq(irq)		request_irq(irq, floppy_interrupt, \
 						    SA_INTERRUPT \
 					            | SA_SAMPLE_RANDOM, \
 				                    "floppy", NULL)
 #define fd_free_irq(irq)		free_irq(irq, NULL);
+#define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size)
+#define fd_dma_mem_free(mem,size) fd_ops->fd_dma_mem_free(mem,size)
+#define fd_drive_type(n)		fd_ops->fd_drive_type(n)
 
 #define MAX_BUFFER_SECTORS 24
 
-/* Pure 2^n version of get_order */
-extern inline int __get_order(unsigned long size)
-{
-	int order;
-
-	size = (size-1) >> (PAGE_SHIFT-1);
-	order = -1;
-	do {
-		size >>= 1;
-		order++;
-	} while (size);
-	return order;
-}
-
-extern inline unsigned long mips_dma_mem_alloc(unsigned long size)
-{
-	int order = __get_order(size);
-	unsigned long mem;
-
-	mem = __get_dma_pages(GFP_KERNEL,order);
-	if(!mem)
-		return 0;
-#ifdef CONFIG_MIPS_JAZZ
-        if (mips_machgroup == MACH_GROUP_JAZZ)
-		vdma_alloc(PHYSADDR(mem), size);
-#endif
-	return mem;
-}
-
-extern inline void mips_dma_mem_free(unsigned long addr, unsigned long size)
-{       
-#ifdef CONFIG_MIPS_JAZZ
-        if (mips_machgroup == MACH_GROUP_JAZZ)
-		vdma_free(PHYSADDR(addr));
-#endif
-	free_pages(addr, __get_order(size));	
-}
-
-#define fd_dma_mem_alloc(size) mips_dma_mem_alloc(size)
-#define fd_dma_mem_free(mem,size) mips_dma_mem_free(mem,size)
 
 /*
  * And on Mips's the CMOS info fails also ...
@@ -90,11 +77,10 @@
  * FIXME: This information should come from the ARC configuration tree
  *        or whereever a particular machine has stored this ...
  */
-#define FLOPPY0_TYPE 4		/* this is wrong for the Olli M700, but who cares... */
-#define FLOPPY1_TYPE 0
+#define FLOPPY0_TYPE 			fd_drive_type(0)
+#define FLOPPY1_TYPE			fd_drive_type(1)
 
-#define FDC1			((mips_machgroup == MACH_GROUP_JAZZ) ? \
-				JAZZ_FDC_BASE : 0x3f0)
+#define FDC1			fd_ops->fd_getfdaddr1();
 static int FDC2=-1;
 
 #define N_FDC 1			/* do you *really* want a second controller? */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/fp.h linux/include/asm-mips/fp.h
--- v2.1.125/linux/include/asm-mips/fp.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/fp.h	Tue Oct 20 13:52:53 1998
@@ -0,0 +1,30 @@
+/* $Id: fp.h,v 1.1 1998/07/16 17:01:54 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+
+/*
+ * Activate and deactive the floatingpoint accelerator.
+ */
+#define enable_cp1()							\
+	__asm__ __volatile__(						\
+		".set\tnoat\n\t"					\
+		"mfc0\t$1,$12\n\t"					\
+		"or\t$1,%0\n\t"						\
+		"mtc0\t$1,$12\n\t"					\
+		".set\tat"						\
+		: : "r" (ST0_CU1));
+
+#define disable_cp1()							\
+	__asm__ __volatile__(						\
+		".set\tnoat\n\t"					\
+		"mfc0\t$1,$12\n\t"					\
+		"or\t$1,%0\n\t"						\
+		"xor\t$1,%0\n\t"					\
+		"mtc0\t$1,$12\n\t"					\
+		".set\tat"						\
+		: : "r" (ST0_CU1));
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/gdb-stub.h linux/include/asm-mips/gdb-stub.h
--- v2.1.125/linux/include/asm-mips/gdb-stub.h	Tue Dec 16 12:46:04 1997
+++ linux/include/asm-mips/gdb-stub.h	Tue Oct 20 13:52:53 1998
@@ -1,9 +1,11 @@
-/*
- *  include/asm-mips/gdb-stub.h
+/* $Id: gdb-stub.h,v 1.3 1998/07/20 17:52:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *  Copyright (C) 1995 Andreas Busse
+ * Copyright (C) 1995 Andreas Busse
  */
-
 #ifndef __ASM_MIPS_GDB_STUB_H
 #define __ASM_MIPS_GDB_STUB_H
 
@@ -131,7 +133,7 @@
 
 #define GDB_FR_SIZE		((((GDB_FR_CP0_PRID) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1))
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 
 /*
  * This is the same as above, but for the high-level
@@ -207,5 +209,5 @@
 
 void set_debug_traps(void);
 
-#endif /* __LANGUAGE_ASSEMBLY */
+#endif /* _LANGUAGE_ASSEMBLY */
 #endif /* __ASM_MIPS_GDB_STUB_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/hardirq.h linux/include/asm-mips/hardirq.h
--- v2.1.125/linux/include/asm-mips/hardirq.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/hardirq.h	Tue Oct 20 13:52:53 1998
@@ -1,3 +1,11 @@
+/* $Id: hardirq.h,v 1.5 1998/08/29 21:20:21 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998 by Ralf Baechle
+ */
 #ifndef __ASM_MIPS_HARDIRQ_H
 #define __ASM_MIPS_HARDIRQ_H
 
@@ -5,6 +13,13 @@
 
 extern unsigned int local_irq_count[NR_CPUS];
 
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+	(local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
+
 #ifndef __SMP__
 
 #define hardirq_trylock(cpu)	(local_irq_count[cpu] == 0)
@@ -13,7 +28,7 @@
 #define hardirq_enter(cpu)	(local_irq_count[cpu]++)
 #define hardirq_exit(cpu)	(local_irq_count[cpu]--)
 
-#define synchronize_irq()	do { } while (0)
+#define synchronize_irq()	barrier();
 
 #else
 
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/ioctls.h linux/include/asm-mips/ioctls.h
--- v2.1.125/linux/include/asm-mips/ioctls.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/ioctls.h	Tue Oct 20 13:52:53 1998
@@ -1,5 +1,4 @@
-/*
- * ioctls for Linux/MIPS.
+/* $Id: ioctls.h,v 1.5 1998/08/19 21:58:11 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -113,5 +112,7 @@
 #define TIOCSERSETMULTI 0x5490 /* Set multiport config */
 #define TIOCMIWAIT      0x5491 /* wait for a change on serial input line(s) */
 #define TIOCGICOUNT     0x5492 /* read serial port inline interrupt counts */
+#define TIOCGHAYESESP	0x5493 /* Get Hayes ESP configuration */
+#define TIOCSHAYESESP	0x5494 /* Set Hayes ESP configuration */
 
 #endif /* __ASM_MIPS_IOCTLS_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/irq.h linux/include/asm-mips/irq.h
--- v2.1.125/linux/include/asm-mips/irq.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/irq.h	Tue Oct 20 13:52:53 1998
@@ -1,13 +1,11 @@
-/*
- * include/asm-mips/irq.h
+/* $Id: irq.h,v 1.4 1998/05/28 03:18:13 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 by Waldorf GMBH
- * written by Ralf Baechle
- *
+ * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
 #ifndef __ASM_MIPS_IRQ_H
 #define __ASM_MIPS_IRQ_H
@@ -34,5 +32,8 @@
 #define irq_enter(cpu, irq)     (++local_irq_count[cpu])
 #define irq_exit(cpu, irq)      (--local_irq_count[cpu])
 #endif
+
+/* Machine specific interrupt initialization  */
+extern void (*irq_setup)(void);
 
 #endif /* __ASM_MIPS_IRQ_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/jazz.h linux/include/asm-mips/jazz.h
--- v2.1.125/linux/include/asm-mips/jazz.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/jazz.h	Tue Oct 20 13:52:53 1998
@@ -1,15 +1,10 @@
-/*
- * Hardware info about Mips JAZZ and similar systems
+/* $Id: jazz.h,v 1.8 1998/09/16 22:52:41 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995 by Andreas Busse and Ralf Baechle
- *
- * This file is a mess. It really needs some reorganisation!
- *
- * $Id: jazz.h,v 1.6 1998/05/01 01:35:56 ralf Exp $
+ * Copyright (C) 1995 - 1998 by Andreas Busse and Ralf Baechle
  */
 #ifndef __ASM_MIPS_JAZZ_H 
 #define __ASM_MIPS_JAZZ_H 
@@ -76,7 +71,7 @@
 #define LED_E                   0x9e
 #define LED_F                   0x8e
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 
 extern __inline__ void pica_set_led(unsigned int bits)
 {
@@ -106,7 +101,7 @@
 #define JAZZ_KEYBOARD_DATA      0xe0005000
 #define JAZZ_KEYBOARD_COMMAND   0xe0005001
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 
 typedef struct {
 	unsigned char data;
@@ -158,7 +153,7 @@
 /*
  * DRAM configuration register
  */
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 #ifdef __MIPSEL__
 typedef struct {
 	unsigned int bank2 : 3;
@@ -178,7 +173,7 @@
 	unsigned int bank2 : 3;
 } dram_configuration;
 #endif
-#endif /* __LANGUAGE_ASSEMBLY__ */
+#endif /* _LANGUAGE_ASSEMBLY */
 
 #define PICA_DRAM_CONFIG        0xe00fffe0
 
@@ -204,6 +199,9 @@
 
 /*
  * JAZZ Interrupt Level definitions
+ *
+ * This is somewhat broken.  For reasons which nobody can remember anymore
+ * we remap the Jazz interrupts to the usual ISA style interrupt numbers.
  */
 #define JAZZ_TIMER_IRQ          0
 #define JAZZ_KEYBOARD_IRQ       1
@@ -213,6 +211,7 @@
 #define JAZZ_SERIAL1_IRQ        18
 #define JAZZ_SERIAL2_IRQ        19
 #define JAZZ_PARALLEL_IRQ       20
+#define JAZZ_MOUSE_IRQ          21
 
 /*
  * JAZZ DMA Channels
@@ -268,7 +267,7 @@
 /*
  * Access the R4030 DMA and I/O Controller
  */
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 
 extern inline void r4030_delay(void)
 {
@@ -301,7 +300,7 @@
 	r4030_delay();
 }
 
-extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val)
+extern inline void r4030_write_reg32(unsigned addr, unsigned val)
 {
 	*((volatile unsigned int *)addr) = val;
 	r4030_delay();
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/keyboard.h linux/include/asm-mips/keyboard.h
--- v2.1.125/linux/include/asm-mips/keyboard.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/keyboard.h	Tue Oct 20 13:52:53 1998
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * $Id: keyboard.h,v 1.8 1998/05/07 00:40:03 ralf Exp $
+ * $Id: keyboard.h,v 1.12 1998/09/16 22:52:41 ralf Exp $
  */
 #ifndef __ASM_MIPS_KEYBOARD_H
 #define __ASM_MIPS_KEYBOARD_H
@@ -51,12 +51,11 @@
 
 #ifdef CONFIG_MIPS_JAZZ
 
-/* Not true for Jazz machines, we cheat a bit for 'em. */
-#define KEYBOARD_IRQ 1
+extern int jazz_ps2_request_irq(void);
+extern void jazz_ps2_free_irq(void);
 
-/*
- * No PS/2 style mouse support for Jazz machines
- */
+#define ps2_request_irq()      jazz_ps2_request_irq()
+#define ps2_free_irq(inode)    jazz_ps2_free_irq()
 
 #endif /* CONFIG_MIPS_JAZZ */
 
@@ -64,13 +63,10 @@
 
 #define DISABLE_KBD_DURING_INTERRUPTS 1
 
-#define KEYBOARD_IRQ 20
-
 /*
  * Machine specific bits for the PS/2 driver.
  * Aux device and keyboard share the interrupt on the Indy.
  */
-
 #define ps2_request_irq() 0
 #define ps2_free_irq(void) do { } while(0);
 
@@ -86,8 +82,6 @@
  * memory mapped I/O ports.
  */
 #include <asm/io.h>
-
-#define KEYBOARD_IRQ 1
 
 /*
  * Machine specific bits for the PS/2 driver
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/mc146818rtc.h linux/include/asm-mips/mc146818rtc.h
--- v2.1.125/linux/include/asm-mips/mc146818rtc.h	Thu Jun 26 12:33:39 1997
+++ linux/include/asm-mips/mc146818rtc.h	Tue Oct 20 13:52:53 1998
@@ -1,15 +1,20 @@
-/*
+/* $Id: mc146818rtc.h,v 1.3 1998/06/25 20:19:26 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * Machine dependent access functions for RTC registers.
+ *
+ * Copyright (C) 1996, 1997, 1998 Ralf Baechle
  */
 #ifndef __ASM_MIPS_MC146818RTC_H
 #define __ASM_MIPS_MC146818RTC_H
 
 #include <asm/io.h>
-#include <asm/vector.h>
 
 #ifndef RTC_PORT
 #define RTC_PORT(x)	(0x70 + (x))
-#define RTC_ALWAYS_BCD	0	/* RTC operates in binary mode */
 #endif
 
 /*
@@ -17,10 +22,25 @@
  * an ISA port access but the way to access the date register differs ...
  */
 #define CMOS_READ(addr) ({ \
-feature->rtc_read_data(addr); \
+rtc_ops->rtc_read_data(addr); \
 })
 #define CMOS_WRITE(val, addr) ({ \
-feature->rtc_write_data(val, addr); \
+rtc_ops->rtc_write_data(val, addr); \
 })
+#define RTC_ALWAYS_BCD \
+rtc_ops->rtc_bcd_mode()
+
+/*
+ * This structure defines how to access various features of
+ * different machine types and how to access them.
+ */
+struct rtc_ops {
+	/* How to access the RTC register in a DS1287.  */
+	unsigned char (*rtc_read_data)(unsigned long addr);
+	void (*rtc_write_data)(unsigned char data, unsigned long addr);
+	int (*rtc_bcd_mode)(void);
+};
+
+extern struct rtc_ops *rtc_ops;
 
 #endif /* __ASM_MIPS_MC146818RTC_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/md.h linux/include/asm-mips/md.h
--- v2.1.125/linux/include/asm-mips/md.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/md.h	Tue Oct 20 13:52:53 1998
@@ -1,8 +1,9 @@
-/* $Id: md.h,v 1.1 1997/12/15 15:12:09 jj Exp $
- * md.h: High speed xor_block operation for RAID4/5 
+/* $Id: md.h,v 1.1 1998/08/17 10:20:14 ralf Exp $
  *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  */
- 
 #ifndef __ASM_MD_H
 #define __ASM_MD_H
 
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/mipsregs.h linux/include/asm-mips/mipsregs.h
--- v2.1.125/linux/include/asm-mips/mipsregs.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/mipsregs.h	Tue Oct 20 13:52:53 1998
@@ -1,5 +1,4 @@
-/*
- * include/asm-mips/mipsregs.h
+/* $Id: mipsregs.h,v 1.6 1998/08/17 11:27:08 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -7,8 +6,6 @@
  *
  * Copyright (C) 1994, 1995, 1996, 1997 by Ralf Baechle
  * Modified for further R[236]000 support by Paul M. Antoine, 1996.
- *
- * $Id: mipsregs.h,v 1.7 1998/05/21 07:37:31 davem Exp $
  */
 #ifndef __ASM_MIPS_MIPSREGS_H
 #define __ASM_MIPS_MIPSREGS_H
@@ -157,7 +154,7 @@
 #define C_IRQ4          (1<<14)
 #define C_IRQ5          (1<<15)
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 /*
  * Manipulate the status register.
  * Mostly used to access the interrupt bits.
@@ -181,7 +178,7 @@
 __BUILD_SET_CP0(cause,CP0_CAUSE)
 __BUILD_SET_CP0(config,CP0_CONFIG)
 
-#endif /* defined (__LANGUAGE_ASSEMBLY__) */
+#endif /* defined (_LANGUAGE_ASSEMBLY) */
 
 /*
  * Inline code for use of the ll and sc instructions
@@ -317,20 +314,20 @@
 #define  CAUSEF_BD		(1   << 31)
 
 /*
- * Bits in the coprocessor 0 config register.
+ * Bits in the coprozessor 0 config register.
  */
-#define CONF_REG_CM_CACHABLE_NO_WA	0
-#define CONF_REG_CM_CACHABLE_WA		1
-#define CONF_REG_CM_UNCACHED		2
-#define CONF_REG_CM_CACHABLE_NONCOHERENT	3
-#define CONF_REG_CM_CACHABLE_CE		4
-#define CONF_REG_CM_CACHABLE_COW		5
-#define CONF_REG_CM_CACHABLE_CUW		6
-#define CONF_REG_CM_CACHABLE_ACCELERATED	7
-#define CONF_REG_CM_CMASK			7
-#define CONF_REG_DB			(1 <<  4)
-#define CONF_REG_IB			(1 <<  5)
-#define CONF_REG_SC			(1 << 17)
+#define CONF_CM_CACHABLE_NO_WA		0
+#define CONF_CM_CACHABLE_WA		1
+#define CONF_CM_UNCACHED		2
+#define CONF_CM_CACHABLE_NONCOHERENT	3
+#define CONF_CM_CACHABLE_CE		4
+#define CONF_CM_CACHABLE_COW		5
+#define CONF_CM_CACHABLE_CUW		6
+#define CONF_CM_CACHABLE_ACCELERATED	7
+#define CONF_CM_CMASK			7
+#define CONF_DB				(1 <<  4)
+#define CONF_IB				(1 <<  5)
+#define CONF_SC				(1 << 17)
 
 /*
  * R10000 performance counter definitions.
@@ -388,7 +385,7 @@
 #define CEB_KERNEL	2	/* Count events in kernel mode EXL = ERL = 0 */
 #define CEB_EXL		1	/* Count events with EXL = 1, ERL = 0 */
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 /*
  * Functions to access the performance counter and control registers
  */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/mmu_context.h linux/include/asm-mips/mmu_context.h
--- v2.1.125/linux/include/asm-mips/mmu_context.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/mmu_context.h	Tue Oct 20 13:52:53 1998
@@ -1,4 +1,4 @@
-/* $Id: mmu_context.h,v 1.4 1998/05/07 00:40:04 ralf Exp $
+/* $Id: mmu_context.h,v 1.3 1998/10/16 19:22:54 ralf Exp $
  *
  * Switch a MMU context.
  *
@@ -11,29 +11,61 @@
 #ifndef __ASM_MIPS_MMU_CONTEXT_H
 #define __ASM_MIPS_MMU_CONTEXT_H
 
-#define MAX_ASID 255
-
+/* Fuck.  The f-word is here so you can grep for it :-)  */
 extern unsigned long asid_cache;
 
-#define ASID_VERSION_SHIFT 16
-#define ASID_VERSION_MASK  ((~0UL) << ASID_VERSION_SHIFT)
-#define ASID_FIRST_VERSION (1UL << ASID_VERSION_SHIFT)
-
-extern inline void get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
-{
-	/* check if it's legal.. */
-	if ((asid & ~ASID_VERSION_MASK) > MAX_ASID) {
-		/* start a new version, invalidate all old asid's */
-		flush_tlb_all();
-		asid = (asid & ASID_VERSION_MASK) + ASID_FIRST_VERSION;
-		if (!asid)
+/* I patch, therefore I am ...  */
+#define ASID_INC(asid)						\
+ ({ unsigned long __asid = asid;				\
+   __asm__("1:\taddiu\t%0,0\t\t\t\t# patched\n\t"		\
+           ".section\t__asid_inc,\"a\"\n\t"			\
+           ".word\t1b\n\t"					\
+           ".previous"						\
+           :"=r" (__asid)					\
+           :"0" (__asid));					\
+   __asid; })
+#define ASID_MASK(asid)						\
+ ({ unsigned long __asid = asid;				\
+   __asm__("1:\tandi\t%0,%1,0\t\t\t# patched\n\t"			\
+           ".section\t__asid_mask,\"a\"\n\t"			\
+           ".word\t1b\n\t"					\
+           ".previous"						\
+           :"=r" (__asid)					\
+           :"r" (__asid));					\
+   __asid; })
+#define ASID_VERSION_MASK					\
+ ({ unsigned long __asid;					\
+   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
+           ".section\t__asid_version_mask,\"a\"\n\t"		\
+           ".word\t1b\n\t"					\
+           ".previous"						\
+           :"=r" (__asid));					\
+   __asid; })
+#define ASID_FIRST_VERSION					\
+ ({ unsigned long __asid = asid;				\
+   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
+           ".section\t__asid_first_version,\"a\"\n\t"		\
+           ".word\t1b\n\t"					\
+           ".previous"						\
+           :"=r" (__asid));					\
+   __asid; })
+
+#define ASID_FIRST_VERSION_R3000 0x1000
+#define ASID_FIRST_VERSION_R4000 0x100
+
+extern inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
+{
+	if (!ASID_MASK((asid = ASID_INC(asid)))) {
+		flush_tlb_all(); /* start new asid cycle */
+		if (!asid)      /* fix version if needed */
 			asid = ASID_FIRST_VERSION;
 	}
-	asid_cache = asid + 1;
-	mm->context = asid;			 /* full version + asid */
+	mm->context = asid_cache = asid;
 }
 
-extern inline void get_mmu_context(struct task_struct *p)
+extern inline void
+get_mmu_context(struct task_struct *p)
 {
 	struct mm_struct *mm = p->mm;
 
@@ -72,5 +104,31 @@
 	get_mmu_context(tsk);
 	set_entryhi(tsk->mm->context);
 }
+
+extern void __asid_setup(unsigned int inc, unsigned int mask,
+                         unsigned int version_mask, unsigned int first_version);
+
+extern inline void r3000_asid_setup(void)
+{
+	__asid_setup(0x40, 0xfc0, 0xf000, ASID_FIRST_VERSION_R3000);
+}
+
+extern inline void r6000_asid_setup(void)
+{
+	panic("r6000_asid_setup: implement me");	/* No idea ...  */
+}
+
+extern inline void tfp_asid_setup(void)
+{
+	panic("tfp_asid_setup: implement me");	/* No idea ...  */
+}
+
+extern inline void r4xx0_asid_setup(void)
+{
+	__asid_setup(1, 0xff, 0xff00, ASID_FIRST_VERSION_R4000);
+}
+
+/* R10000 has the same ASID mechanism as the R4000.  */
+#define andes_asid_setup r4xx0_asid_setup
 
 #endif /* __ASM_MIPS_MMU_CONTEXT_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/offset.h linux/include/asm-mips/offset.h
--- v2.1.125/linux/include/asm-mips/offset.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/offset.h	Tue Oct 20 13:52:53 1998
@@ -46,35 +46,36 @@
 
 /* MIPS task_struct offsets. */
 #define TASK_STATE         0
-#define TASK_COUNTER       52
-#define TASK_PRIORITY      56
 #define TASK_FLAGS         4
 #define TASK_SIGPENDING    8
-#define TASK_MM            936
+#define TASK_NEED_RESCHED  20
+#define TASK_COUNTER       24
+#define TASK_PRIORITY      28
+#define TASK_MM            928
 
 /* MIPS specific thread_struct offsets. */
-#define THREAD_REG16   576
-#define THREAD_REG17   580
-#define THREAD_REG18   584
-#define THREAD_REG19   588
-#define THREAD_REG20   592
-#define THREAD_REG21   596
-#define THREAD_REG22   600
-#define THREAD_REG23   604
-#define THREAD_REG29   608
-#define THREAD_REG30   612
-#define THREAD_REG31   616
-#define THREAD_STATUS  620
-#define THREAD_FPU     624
-#define THREAD_BVADDR  888
-#define THREAD_BUADDR  892
-#define THREAD_ECODE   896
-#define THREAD_TRAPNO  900
-#define THREAD_PGDIR   904
-#define THREAD_MFLAGS  908
-#define THREAD_CURDS   912
-#define THREAD_TRAMP   916
-#define THREAD_OLDCTX  920
+#define THREAD_REG16   568
+#define THREAD_REG17   572
+#define THREAD_REG18   576
+#define THREAD_REG19   580
+#define THREAD_REG20   584
+#define THREAD_REG21   588
+#define THREAD_REG22   592
+#define THREAD_REG23   596
+#define THREAD_REG29   600
+#define THREAD_REG30   604
+#define THREAD_REG31   608
+#define THREAD_STATUS  612
+#define THREAD_FPU     616
+#define THREAD_BVADDR  880
+#define THREAD_BUADDR  884
+#define THREAD_ECODE   888
+#define THREAD_TRAPNO  892
+#define THREAD_PGDIR   896
+#define THREAD_MFLAGS  900
+#define THREAD_CURDS   904
+#define THREAD_TRAMP   908
+#define THREAD_OLDCTX  912
 
 /* Linux mm_struct offsets. */
 #define MM_COUNT      12
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/pgtable.h linux/include/asm-mips/pgtable.h
--- v2.1.125/linux/include/asm-mips/pgtable.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/pgtable.h	Tue Oct 20 13:52:53 1998
@@ -1,10 +1,18 @@
+/* $Id: pgtable.h,v 1.15 1998/08/20 14:40:57 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1998 by Ralf Baechle at alii
+ */
 #ifndef __ASM_MIPS_PGTABLE_H
 #define __ASM_MIPS_PGTABLE_H
 
 #include <asm/addrspace.h>
 #include <asm/mipsconfig.h>
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 
 #include <linux/linkage.h>
 #include <asm/cachectl.h>
@@ -53,7 +61,7 @@
  * works even with the cache aliasing problem the R4k and above have.
  */
 
-#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define PMD_SHIFT	22
@@ -71,10 +79,11 @@
 #define PTRS_PER_PTE	1024
 #define PTRS_PER_PMD	1
 #define PTRS_PER_PGD	1024
+#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 
 #define VMALLOC_START     KSEG2
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#error You need to define VMALLOC_END --DaveM
+#define VMALLOC_END       KSEG3
 
 /* Note that we shift the lower 32bits of each EntryLo[01] entry
  * 6 bits to the left. That way we can convert the PFN into the
@@ -122,7 +131,7 @@
 
 #define _PAGE_CHG_MASK  (PAGE_MASK | __READABLE | __WRITEABLE | _CACHE_MASK)
 
-#define PAGE_NONE	__pgprot(0)
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
 #define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
 			_CACHE_CACHABLE_NONCOHERENT)
 #define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_READ | \
@@ -159,7 +168,7 @@
 #define __S110	PAGE_SHARED
 #define __S111	PAGE_SHARED
 
-#if !defined (__LANGUAGE_ASSEMBLY__)
+#if !defined (_LANGUAGE_ASSEMBLY)
 
 /*
  * BAD_PAGETABLE is used when we need a bogus page-table, while
@@ -171,13 +180,13 @@
 extern pte_t __bad_page(void);
 extern pte_t *__bad_pagetable(void);
 
-extern unsigned long __zero_page(void);
-
-extern unsigned long empty_zero_page[1024];
+extern unsigned long empty_zero_page;
+extern unsigned long zero_page_mask;
 
 #define BAD_PAGETABLE __bad_pagetable()
 #define BAD_PAGE __bad_page()
-#define ZERO_PAGE ((unsigned long)empty_zero_page)
+#define ZERO_PAGE(__vaddr) \
+	(empty_zero_page + (((unsigned long)(__vaddr)) & zero_page_mask))
 
 /* number of bits that fit into a memory pointer */
 #define BITS_PER_PTR			(8*sizeof(unsigned long))
@@ -378,77 +387,141 @@
 }
 
 /*
+ * Initialize new page directory with pointers to invalid ptes
+ */
+extern void (*pgd_init)(unsigned long page);
+
+/*
  * Allocate and free page tables. The xxx_kernel() versions are
  * used to allocate a kernel page table - this turns on ASN bits
  * if any.
  */
-extern inline void pte_free_kernel(pte_t *pte)
+
+#define pgd_quicklist (current_cpu_data.pgd_quick)
+#define pmd_quicklist ((unsigned long *)0)
+#define pte_quicklist (current_cpu_data.pte_quick)
+#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
+
+extern __inline__ pgd_t *get_pgd_slow(void)
+{
+	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init;
+
+	if (ret) {
+		init = pgd_offset(&init_mm, 0);
+		pgd_init((unsigned long)ret);
+		memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+	}
+	return ret;
+}
+
+extern __inline__ pgd_t *get_pgd_fast(void)
 {
-	free_page((unsigned long) pte);
+	unsigned long *ret;
+
+	if((ret = pgd_quicklist) != NULL) {
+		pgd_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+	} else
+		ret = (unsigned long *)get_pgd_slow();
+	return (pgd_t *)ret;
 }
 
-extern const char bad_pmd_string[];
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
+{
+	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	pgtable_cache_size++;
+}
 
-extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
 {
-	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_set(pmd, page);
-				return page + address;
-			}
-			pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
-			return NULL;
-		}
-		free_page((unsigned long) page);
-	}
-	if (pmd_bad(*pmd)) {
-		printk(bad_pmd_string, pmd_val(*pmd));
-		pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
-		return NULL;
+	free_page((unsigned long)pgd);
+}
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
+extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);
+
+extern __inline__ pte_t *get_pte_fast(void)
+{
+	unsigned long *ret;
+
+	if((ret = (unsigned long *)pte_quicklist) != NULL) {
+		pte_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
 	}
-	return (pte_t *) pmd_page(*pmd) + address;
+	return (pte_t *)ret;
 }
 
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-extern inline void pmd_free_kernel(pmd_t *pmd)
+extern __inline__ void free_pte_fast(pte_t *pte)
 {
-	pmd_val(*pmd) = ((unsigned long) invalid_pte_table);
+	*(unsigned long *)pte = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pte;
+	pgtable_cache_size++;
 }
 
-extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
+extern __inline__ void free_pte_slow(pte_t *pte)
 {
-	return (pmd_t *) pgd;
+	free_page((unsigned long)pte);
 }
 
-extern inline void pte_free(pte_t *pte)
+/* We don't use pmd cache, so these are dummy routines */
+extern __inline__ pmd_t *get_pmd_fast(void)
 {
-	free_page((unsigned long) pte);
+	return (pmd_t *)0;
 }
 
-extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address)
+extern __inline__ void free_pmd_fast(pmd_t *pmd)
+{
+}
+
+extern __inline__ void free_pmd_slow(pmd_t *pmd)
+{
+}
+
+extern void __bad_pte(pmd_t *pmd);
+extern void __bad_pte_kernel(pmd_t *pmd);
+
+#define pte_free_kernel(pte)    free_pte_fast(pte)
+#define pte_free(pte)           free_pte_fast(pte)
+#define pgd_free(pgd)           free_pgd_fast(pgd)
+#define pgd_alloc()             get_pgd_fast()
+
+extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+	if (pmd_none(*pmd)) {
+		pte_t *page = get_pte_fast();
+		if (page) {
+			pmd_val(*pmd) = (unsigned long)page;
+			return page + address;
+		}
+		return get_pte_kernel_slow(pmd, address);
+	}
+	if (pmd_bad(*pmd)) {
+		__bad_pte_kernel(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+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_set(pmd, page);
-				return page + address;
-			}
-			pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
-			return NULL;
+		pte_t *page = get_pte_fast();
+		if (page) {
+			pmd_val(*pmd) = (unsigned long)page;
+			return page + address;
 		}
-		free_page((unsigned long) page);
+		return get_pte_slow(pmd, address);
 	}
 	if (pmd_bad(*pmd)) {
-		printk(bad_pmd_string, pmd_val(*pmd));
-		pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
+		__bad_pte(pmd);
 		return NULL;
 	}
 	return (pte_t *) pmd_page(*pmd) + address;
@@ -458,40 +531,47 @@
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
  * inside the pgd, so has no extra memory associated with it.
  */
-extern inline void pmd_free(pmd_t *pmd)
+extern inline void pmd_free(pmd_t * pmd)
 {
-	pmd_val(*pmd) = ((unsigned long) invalid_pte_table);
 }
 
-extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
+extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
 {
 	return (pmd_t *) pgd;
 }
 
-extern inline void pgd_free(pgd_t *pgd)
-{
-	free_page((unsigned long) pgd);
-}
+#define pmd_free_kernel		pmd_free
+#define pmd_alloc_kernel	pmd_alloc
 
-/*
- * Initialize new page directory with pointers to invalid ptes
- */
-extern void (*pgd_init)(unsigned long page);
+extern int do_check_pgt_cache(int, int);
 
-extern inline pgd_t *pgd_alloc(void)
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
 {
-	unsigned long page;
-
-	if(!(page = __get_free_page(GFP_KERNEL)))
-		return NULL;
-
-	pgd_init(page);
-
-	return (pgd_t *) page;
+	struct task_struct * p;
+	pgd_t *pgd;
+#ifdef __SMP__
+	int i;
+#endif	
+        
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		if (!p->mm)
+			continue;
+		*pgd_offset(p->mm,address) = entry;
+	}
+	read_unlock(&tasklist_lock);
+#ifndef __SMP__
+	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+		pgd[address >> PGDIR_SHIFT] = entry;
+#else
+	/* To pgd_alloc/pgd_free, one holds master kernel lock and so does our
+	   callee, so we can modify pgd caches of other CPUs as well. -jj */
+	for (i = 0; i < NR_CPUS; i++)
+		for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+			pgd[address >> PGDIR_SHIFT] = entry;
+#endif
 }
 
-extern int do_check_pgt_cache(int, int);
-
 extern pgd_t swapper_pg_dir[1024];
 
 extern void (*update_mmu_cache)(struct vm_area_struct *vma,
@@ -507,6 +587,9 @@
 #define module_map      vmalloc
 #define module_unmap    vfree
 
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)		(0)
+
 /* TLB operations. */
 extern inline void tlb_probe(void)
 {
@@ -776,6 +859,6 @@
 		: : "r" (val));
 }
 
-#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 #endif /* __ASM_MIPS_PGTABLE_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/pica.h linux/include/asm-mips/pica.h
--- v2.1.125/linux/include/asm-mips/pica.h	Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/pica.h	Wed Dec 31 16:00:00 1969
@@ -1,181 +0,0 @@
-/*
- * Hardware info about Acer PICA 61 and similar
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995 by Andreas Busse and Ralf Baechle
- */
-#ifndef __ASM_MIPS_PICA_H 
-#define __ASM_MIPS_PICA_H 
-
-/*
- * The addresses below are virtual address. The mappings are
- * created on startup via wired entries in the tlb. The Mips
- * Magnum R3000 and R4000 machines are similar in many aspects,
- * but many hardware register are accessible at 0xb9000000 in
- * instead of 0xe0000000.
- */
-
-/*
- * Revision numbers in PICA_ASIC_REVISION
- *
- * 0xf0000000 - Rev1
- * 0xf0000001 - Rev2
- * 0xf0000002 - Rev3
- */
-#define PICA_ASIC_REVISION      0xe0000008
-
-/*
- * The segments of the seven segment LED are mapped
- * to the control bits as follows:
- *
- *         (7)
- *      ---------
- *      |       |
- *  (2) |       | (6)
- *      |  (1)  |
- *      ---------
- *      |       |
- *  (3) |       | (5)
- *      |  (4)  |
- *      --------- . (0)
- */
-#define PICA_LED                0xe000f000
-
-/*
- * Some characters for the LED control registers
- * The original Mips machines seem to have a LED display
- * with integrated decoder while the Acer machines can
- * control each of the seven segments and the dot independently.
- * It only a toy, anyway...
- */
-#define LED_DOT                 0x01
-#define LED_SPACE               0x00
-#define LED_0                   0xfc
-#define LED_1                   0x60
-#define LED_2                   0xda
-#define LED_3                   0xf2
-#define LED_4                   0x66
-#define LED_5                   0xb6
-#define LED_6                   0xbe
-#define LED_7                   0xe0
-#define LED_8                   0xfe
-#define LED_9                   0xf6
-#define LED_A                   0xee
-#define LED_b                   0x3e
-#define LED_C                   0x9c
-#define LED_d                   0x7a
-#define LED_E                   0x9e
-#define LED_F                   0x8e
-
-#ifndef __LANGUAGE_ASSEMBLY__
-
-extern __inline__ void pica_set_led(unsigned int bits)
-{
-	volatile unsigned int *led_register = (unsigned int *) PICA_LED;
-
-	*led_register = bits;
-}
-
-#endif
-
-/*
- * i8042 keyboard controller for PICA chipset.
- * This address is just a guess and seems to differ
- * from the other mips machines...
- */
-#define PICA_KEYBOARD_ADDRESS   0xe0005000
-#define PICA_KEYBOARD_DATA      0xe0005000
-#define PICA_KEYBOARD_COMMAND   0xe0005001
-
-#ifndef __LANGUAGE_ASSEMBLY__
-
-typedef struct {
-	unsigned char data;
-	unsigned char command;
-} pica_keyboard_hardware;
-
-typedef struct {
-	unsigned char pad0[3];
-	unsigned char data;
-	unsigned char pad1[3];
-	unsigned char command;
-} mips_keyboard_hardware;
-
-/*
- * For now
- */
-#define keyboard_hardware       pica_keyboard_hardware
-
-#endif
-
-/*
- * i8042 keyboard controller for most other Mips machines.
- */
-#define MIPS_KEYBOARD_ADDRESS   0xb9005000
-#define MIPS_KEYBOARD_DATA      0xb9005003
-#define MIPS_KEYBOARD_COMMAND   0xb9005007
-
-#ifndef __LANGUAGE_ASSEMBLY__
-
-#endif
-
-/*
- * PICA timer registers and interrupt no.
- * Note that the hardware timer interrupt is actually on
- * cpu level 6, but to keep compatibility with PC stuff
- * it is remapped to vector 0. See arch/mips/kernel/entry.S.
- */
-#define PICA_TIMER_INTERVAL     0xe0000228
-#define PICA_TIMER_REGISTER     0xe0000230
-
-/*
- * DRAM configuration register
- */
-#ifndef __LANGUAGE_ASSEMBLY__
-#ifdef __MIPSEL__
-typedef struct {
-	unsigned int bank2 : 3;
-	unsigned int bank1 : 3;
-	unsigned int mem_bus_width : 1;
-	unsigned int reserved2 : 1;
-	unsigned int page_mode : 1;
-	unsigned int reserved1 : 23;
-} dram_configuration;
-#else /* defined (__MIPSEB__) */
-typedef struct {
-	unsigned int reserved1 : 23;
-	unsigned int page_mode : 1;
-	unsigned int reserved2 : 1;
-	unsigned int mem_bus_width : 1;
-	unsigned int bank1 : 3;
-	unsigned int bank2 : 3;
-} dram_configuration;
-#endif
-#endif /* __LANGUAGE_ASSEMBLY__ */
-
-#define PICA_DRAM_CONFIG        0xe00fffe0
-
-/*
- * PICA interrupt control registers
- */
-#define PICA_IO_IRQ_SOURCE      0xe0100000
-#define PICA_IO_IRQ_ENABLE      0xe0100002
-
-/*
- * Pica interrupt enable bits
- */
-#define PIE_PARALLEL            (1<<0)
-#define PIE_FLOPPY              (1<<1)
-#define PIE_SOUND               (1<<2)
-#define PIE_VIDEO               (1<<3)
-#define PIE_ETHERNET            (1<<4)
-#define PIE_SCSI                (1<<5)
-#define PIE_KEYBOARD            (1<<6)
-#define PIE_MOUSE               (1<<7)
-#define PIE_SERIAL1             (1<<8)
-#define PIE_SERIAL2             (1<<9)
-
-#endif /* __ASM_MIPS_PICA_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/posix_types.h linux/include/asm-mips/posix_types.h
--- v2.1.125/linux/include/asm-mips/posix_types.h	Tue Dec 16 12:46:11 1997
+++ linux/include/asm-mips/posix_types.h	Tue Oct 20 13:52:53 1998
@@ -1,11 +1,10 @@
-/*
- * POSIX types
+/* $Id: posix_types.h,v 1.5 1998/08/17 13:59:34 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
  */
 #ifndef __ARCH_MIPS_POSIX_TYPES_H
 #define __ARCH_MIPS_POSIX_TYPES_H
@@ -46,6 +45,8 @@
         long    val[2];
 } __kernel_fsid_t;
 
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
 #undef __FD_SET
 static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
 {
@@ -113,5 +114,7 @@
 		__tmp++;
 	}
 }
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
 
 #endif /* __ARCH_MIPS_POSIX_TYPES_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/prctl.h linux/include/asm-mips/prctl.h
--- v2.1.125/linux/include/asm-mips/prctl.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/prctl.h	Tue Oct 20 13:52:53 1998
@@ -3,7 +3,7 @@
  *
  * The IRIX kernel maps a page at PRDA_ADDRESS with the
  * contents of prda and fills it the bits on prda_sys.
- * $Id: prctl.h,v 1.2 1998/05/01 01:36:02 ralf Exp $
+ * $Id: prctl.h,v 1.1 1997/12/02 02:28:28 ralf Exp $
  */
 
 #ifndef __PRCTL_H__
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/processor.h linux/include/asm-mips/processor.h
--- v2.1.125/linux/include/asm-mips/processor.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/processor.h	Tue Oct 20 13:52:53 1998
@@ -1,27 +1,47 @@
-/*
- * include/asm-mips/processor.h
+/* $Id: processor.h,v 1.18 1998/10/14 20:31:12 ralf Exp $
  *
- * Copyright (C) 1994  Waldorf Electronics
- * written by Ralf Baechle
- * Modified further for R[236]000 compatibility by Paul M. Antoine
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * $Id: processor.h,v 1.22 1998/05/11 08:40:07 davem Exp $
+ * Copyright (C) 1994 Waldorf GMBH
+ * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle
+ * Modified further for R[236]000 compatibility by Paul M. Antoine
  */
 #ifndef __ASM_MIPS_PROCESSOR_H
 #define __ASM_MIPS_PROCESSOR_H
 
-#if !defined (__LANGUAGE_ASSEMBLY__)
+#if !defined (_LANGUAGE_ASSEMBLY)
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
 #include <asm/reg.h>
 #include <asm/system.h>
 
+struct mips_cpuinfo {
+	unsigned long *pgd_quick;
+	unsigned long *pte_quick;
+	unsigned long pgtable_cache_sz;
+};
+
 /*
  * System setup and hardware flags..
+ * XXX: Should go into mips_cpuinfo.
  */
 extern char wait_available;		/* only available on R4[26]00 */
 extern char cyclecounter_available;	/* only available from R4000 upwards. */
 extern char dedicated_iv_available;	/* some embedded MIPS like Nevada */
+extern char vce_available;		/* Supports VCED / VCEI exceptions */
+
+extern struct mips_cpuinfo boot_cpu_data;
+extern unsigned int vced_count, vcei_count;
+
+#ifdef __SMP__
+extern struct mips_cpuinfo cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#else
+#define cpu_data &boot_cpu_data
+#define current_cpu_data boot_cpu_data
+#endif
 
 /*
  * Bus types (default is ISA, but people can check others with these..)
@@ -40,6 +60,9 @@
 #define wp_works_ok 1
 #define wp_works_ok__is_a_macro /* for versions in ksyms.c */
 
+/* Lazy FPU handling on uni-processor */
+extern struct task_struct *last_task_used_math;
+
 /*
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.  TASK_SIZE
@@ -114,7 +137,7 @@
 	unsigned long irix_oldctx;
 };
 
-#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 #define INIT_MMAP { &init_mm, KSEG0, KSEG1, PAGE_SHARED, \
                     VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
@@ -147,7 +170,7 @@
 
 #define KERNEL_STACK_SIZE 8192
 
-#if !defined (__LANGUAGE_ASSEMBLY__)
+#if !defined (_LANGUAGE_ASSEMBLY)
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
@@ -188,7 +211,7 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
-#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
 #endif /* __KERNEL__ */
 
 /*
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/ptrace.h linux/include/asm-mips/ptrace.h
--- v2.1.125/linux/include/asm-mips/ptrace.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/ptrace.h	Tue Oct 20 13:52:54 1998
@@ -1,11 +1,10 @@
-/*
- * linux/include/asm-mips/ptrace.h
+/* $Id: ptrace.h,v 1.3 1998/07/09 21:45:21 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
  *
  * Machine dependent structs and defines to help the user use
  * the ptrace system call.
@@ -14,6 +13,15 @@
 #define __ASM_MIPS_PTRACE_H
 
 #include <linux/types.h>
+
+/* 0 - 31 are integer registers, 32 - 63 are fp registers.  */
+#define PC		64
+#define CAUSE		65
+#define MMLO		66
+#define MMHI		67
+#define FPC_CSR		68	/* XXX */
+#define FPC_EIR		69	/* XXX */
+#define FPR_BASE	70	/* XXX */
 
 #ifndef __ASSEMBLY__
 /*
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/r4kcache.h linux/include/asm-mips/r4kcache.h
--- v2.1.125/linux/include/asm-mips/r4kcache.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/r4kcache.h	Tue Oct 20 13:52:54 1998
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r4kcache.h,v 1.5 1998/05/01 01:36:03 ralf Exp $
+ * $Id: r4kcache.h,v 1.7 1997/12/18 13:00:45 ralf Exp $
  *
  * FIXME: Handle split L2 caches.
  */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/serial.h linux/include/asm-mips/serial.h
--- v2.1.125/linux/include/asm-mips/serial.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/serial.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: serial.h,v 1.2 1998/05/08 01:44:31 ralf Exp $
+/* $Id: serial.h,v 1.3 1998/08/28 15:55:38 ralf Exp $
  *
  * include/asm-mips/serial.h
  */
@@ -15,9 +15,14 @@
  */
 #define BASE_BAUD ( 1843200 / 16 )
 
+#ifndef CONFIG_OLIVETTI_M700
 /* Some Jazz machines seem to have an 8MHz crystal clock but I don't know
    exactly which ones ... XXX */
 #define JAZZ_BASE_BAUD ( 8000000 / 16 ) /* ( 3072000 / 16) */
+#else
+/* but the M700 isn't such a strange beast */
+#define JAZZ_BASE_BAUD BASE_BAUD
+#endif
 
 /* Standard COM flags (except for COM4, because of the 8514 problem) */
 #ifdef CONFIG_SERIAL_DETECT_IRQ
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sgi.h linux/include/asm-mips/sgi.h
--- v2.1.125/linux/include/asm-mips/sgi.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/sgi.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: sgi.h,v 1.2 1998/05/01 01:36:05 ralf Exp $
+/* $Id: sgi.h,v 1.1.1.1 1997/06/01 03:17:12 ralf Exp $
  * sgi.h: Definitions specific to SGI machines.
  *
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sgialib.h linux/include/asm-mips/sgialib.h
--- v2.1.125/linux/include/asm-mips/sgialib.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/sgialib.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: sgialib.h,v 1.2 1998/05/01 01:36:06 ralf Exp $
+/* $Id: sgialib.h,v 1.2 1998/07/08 16:01:13 ralf Exp $
  * sgialib.h: SGI ARCS firmware interface library for the Linux kernel.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -106,11 +106,11 @@
 extern long prom_exec(char *name, long argc, char **argv, char **envp);
 
 /* Misc. routines. */
-extern void prom_halt(void);
-extern void prom_powerdown(void);
-extern void prom_restart(void);
-extern void prom_reboot(void);
-extern void prom_imode(void);
+extern void prom_halt(void) __attribute__((noreturn));
+extern void prom_powerdown(void) __attribute__((noreturn));
+extern void prom_restart(void) __attribute__((noreturn));
+extern void prom_reboot(void) __attribute__((noreturn));
+extern void prom_imode(void) __attribute__((noreturn));
 extern long prom_cfgsave(void);
 extern struct linux_sysid *prom_getsysid(void);
 extern void prom_cacheflush(void);
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sgiarcs.h linux/include/asm-mips/sgiarcs.h
--- v2.1.125/linux/include/asm-mips/sgiarcs.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/sgiarcs.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,5 @@
-/* $Id: sgiarcs.h,v 1.2 1998/05/01 01:36:07 ralf Exp $
+/* $Id: sgiarcs.h,v 1.2 1998/07/08 16:01:57 ralf Exp $
+ *
  * SGI ARCS firmware interface defines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -170,11 +171,11 @@
 	/* Load and begin execution of a standalong image. */
 	long (*exec)(char *file, long argc, char **argv, char **envp);
 
-	void (*halt)(void); 	/* Halt the machine. */
-	void (*pdown)(void);    /* Power down the machine. */
-	void (*restart)(void);  /* XXX soft reset??? */
-	void (*reboot)(void);   /* Reboot the machine. */
-	void (*imode)(void);    /* Enter PROM interactive mode. */
+	void (*halt)(void) __attribute__((noreturn)); 	/* Halt the machine. */
+	void (*pdown)(void) __attribute__((noreturn));    /* Power down the machine. */
+	void (*restart)(void) __attribute__((noreturn));  /* XXX soft reset??? */
+	void (*reboot)(void) __attribute__((noreturn));   /* Reboot the machine. */
+	void (*imode)(void) __attribute__((noreturn));    /* Enter PROM interactive mode. */
 	int _unused1; /* padding */
 
 	/* PROM device tree interface. */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sgihpc.h linux/include/asm-mips/sgihpc.h
--- v2.1.125/linux/include/asm-mips/sgihpc.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/sgihpc.h	Tue Oct 20 13:52:54 1998
@@ -1,9 +1,11 @@
-/* $Id: sgihpc.h,v 1.2 1998/05/01 01:36:07 ralf Exp $
+/* $Id: sgihpc.h,v 1.4 1998/09/16 22:52:42 ralf Exp $
+ *
  * sgihpc.h: Various HPC I/O controller defines.  The HPC is basically
  *           the approximate functional equivalent of the Sun SYSIO
  *           on SGI INDY machines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _MIPS_SGIHPC_H
 #define _MIPS_SGIHPC_H
@@ -321,6 +323,11 @@
 extern struct hpc3_miscregs *hpc3mregs;
 #define HPC3_MREGS_PBASE   0x1fbd9800 /* physical */
 
+/* We need software copies of these because they are write only. */
+extern unsigned long sgi_hpc_write1, sgi_hpc_write2;
+
+#define SGI_KEYBOARD_IRQ 20
+
 struct hpc_keyb {
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
@@ -334,6 +341,29 @@
 	unsigned char _unused1[3];
 #endif
 };
+
+/* Indy RTC  */
+
+/* The layout of registers for the INDY Dallas 1286 clock chipset. */
+struct indy_clock {
+	volatile unsigned int hsec;
+	volatile unsigned int sec;
+	volatile unsigned int min;
+	volatile unsigned int malarm;
+	volatile unsigned int hr;
+	volatile unsigned int halarm;
+	volatile unsigned int day;
+	volatile unsigned int dalarm;
+	volatile unsigned int date;
+	volatile unsigned int month;
+	volatile unsigned int year;
+	volatile unsigned int cmd;
+	volatile unsigned int whsec;
+	volatile unsigned int wsec;
+	volatile unsigned int _unused0[50];
+};
+
+#define INDY_CLOCK_REGS (KSEG1ADDR(0x1fbe0000))
 
 extern void sgihpc_init(void);
 
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sgimc.h linux/include/asm-mips/sgimc.h
--- v2.1.125/linux/include/asm-mips/sgimc.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/sgimc.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: sgimc.h,v 1.2 1998/05/01 01:36:08 ralf Exp $
+/* $Id: sgimc.h,v 1.1.1.1 1997/06/01 03:17:13 ralf Exp $
  * sgimc.h: Definitions for memory controller hardware found on
  *          SGI IP20, IP22, IP26, and IP28 machines.
  *
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sgint23.h linux/include/asm-mips/sgint23.h
--- v2.1.125/linux/include/asm-mips/sgint23.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/sgint23.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,4 @@
-/* $Id: sgint23.h,v 1.2 1998/05/01 01:36:09 ralf Exp $
+/* $Id: sgint23.h,v 1.2 1998/03/11 11:58:36 ralf Exp $
  * sgint23.h: Defines for the SGI INT2 and INT3 chipsets.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sigcontext.h linux/include/asm-mips/sigcontext.h
--- v2.1.125/linux/include/asm-mips/sigcontext.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/sigcontext.h	Tue Oct 20 13:52:54 1998
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1996, 1997 by Ralf Baechle
  *
- * $Id: sigcontext.h,v 1.6 1998/05/01 01:36:10 ralf Exp $
+ * $Id: sigcontext.h,v 1.5 1997/12/14 18:57:19 ralf Exp $
  */
 #ifndef __ASM_MIPS_SIGCONTEXT_H
 #define __ASM_MIPS_SIGCONTEXT_H
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/siginfo.h linux/include/asm-mips/siginfo.h
--- v2.1.125/linux/include/asm-mips/siginfo.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-mips/siginfo.h	Tue Oct 20 13:52:54 1998
@@ -1,3 +1,11 @@
+/* $Id: siginfo.h,v 1.4 1998/08/28 16:23:06 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
 #ifndef __ASM_MIPS_SIGINFO_H
 #define __ASM_MIPS_SIGINFO_H
 
@@ -84,9 +92,9 @@
 #define SI_USER		0	/* sent by kill, sigsend, raise */
 #define SI_KERNEL	0x80	/* sent by the kernel from somewhere */
 #define SI_QUEUE	-1	/* sent by sigqueue */
-#define SI_TIMER	-2	/* sent by timer expiration */
-#define SI_MESGQ	-3	/* sent by real time mesq state change */
-#define SI_ASYNCIO	-4	/* sent by AIO completion */
+#define SI_ASYNCIO	-2	/* sent by AIO completion */
+#define SI_TIMER	-3	/* sent by timer expiration */
+#define SI_MESGQ	-4	/* sent by real time mesq state change */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/signal.h linux/include/asm-mips/signal.h
--- v2.1.125/linux/include/asm-mips/signal.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/signal.h	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,10 @@
-/*
- * Linux/MIPS specific definitions for signals.
+/* $Id: signal.h,v 1.4 1998/08/18 20:46:42 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
- *
- * $Id: signal.h,v 1.8 1998/05/01 01:36:11 ralf Exp $
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
 #ifndef __ASM_MIPS_SIGNAL_H
 #define __ASM_MIPS_SIGNAL_H
@@ -66,7 +63,7 @@
 /*
  * SA_FLAGS values:
  *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
+ * SA_ONSTACK indicates that a registered stack_t will be used.
  * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
  * SA_RESTART flag to get restarting signals (which were the default long ago)
  * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
@@ -85,8 +82,17 @@
 #define SA_NOCLDWAIT	0x00010000	/* Not supported yet */
 #define SA_NOCLDSTOP	0x00020000
 
-#define SA_NOMASK	SA_NODEFER	/* DANGER: was 0x02000000 */
-#define SA_ONESHOT	SA_RESETHAND	/* DANGER: was 0x04000000 */
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
 
 #ifdef __KERNEL__
 /*
@@ -129,6 +135,13 @@
 	struct sigaction sa;
 	void (*ka_restorer)(void);
 };
+
+/* IRIX compatible stack_t  */
+typedef struct sigaltstack {
+	void *ss_sp;
+	size_t ss_size;
+	int ss_flags;
+} stack_t;
 
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/smp.h linux/include/asm-mips/smp.h
--- v2.1.125/linux/include/asm-mips/smp.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/smp.h	Tue Oct 20 13:52:54 1998
@@ -1,4 +1,6 @@
 #ifndef __ASM_MIPS_SMP_H
 #define __ASM_MIPS_SMP_H
 
+#define cpu_logical_map(cpu)	(cpu)
+
 #endif /* __ASM_MIPS_SMP_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/smplock.h linux/include/asm-mips/smplock.h
--- v2.1.125/linux/include/asm-mips/smplock.h	Mon Aug  3 17:48:28 1998
+++ linux/include/asm-mips/smplock.h	Tue Oct 20 13:52:54 1998
@@ -1,5 +1,8 @@
-/*
- * <asm/smplock.h>
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
  * Default SMP lock implementation
  */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/sni.h linux/include/asm-mips/sni.h
--- v2.1.125/linux/include/asm-mips/sni.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/sni.h	Tue Oct 20 13:52:54 1998
@@ -1,11 +1,12 @@
-/*
+/* $Id: sni.h,v 1.2 1998/09/16 22:52:43 ralf Exp $
+ *
  * SNI specific definitions
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997 by Ralf Baechle
+ * Copyright (C) 1997, 1998 by Ralf Baechle
  */
 #ifndef __ASM_MIPS_SNI_H 
 #define __ASM_MIPS_SNI_H 
@@ -87,5 +88,10 @@
  * Base address for the mapped 16mb EISA bus segment.
  */
 #define PCIMT_EISA_BASE		0xb0000000
+
+/*
+ * The keyboard interrupt is an ISA interrupt
+ */
+#define SNI_KEYBOARD_IRQ 1
 
 #endif /* __ASM_MIPS_SNI_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/socket.h linux/include/asm-mips/socket.h
--- v2.1.125/linux/include/asm-mips/socket.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/socket.h	Tue Oct 20 13:52:54 1998
@@ -1,5 +1,5 @@
 /*
- * $Id: socket.h,v 1.10 1998/05/01 01:36:12 ralf Exp $
+ * $Id: socket.h,v 1.5 1998/03/15 09:52:54 ralf Exp $
  */
 #ifndef __ASM_MIPS_SOCKET_H
 #define __ASM_MIPS_SOCKET_H
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/softirq.h linux/include/asm-mips/softirq.h
--- v2.1.125/linux/include/asm-mips/softirq.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/softirq.h	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,10 @@
-/*
- * include/asm-mips/softirq.h
+/* $Id: softirq.h,v 1.5 1998/08/29 21:20:22 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1997, 1998 by Ralf Baechle
- *
- * $Id: softirq.h,v 1.2 1998/05/01 01:36:13 ralf Exp $
  */
 #ifndef __ASM_MIPS_SOFTIRQ_H
 #define __ASM_MIPS_SOFTIRQ_H
@@ -86,6 +83,6 @@
 /* These are for the irq's testing the lock */
 #define softirq_trylock(cpu)	(local_bh_count[cpu] ? 0 : (local_bh_count[cpu] = 1))
 #define softirq_endlock(cpu)	(local_bh_count[cpu] = 0)
-#define synchronize_bh()	do { } while (0)
+#define synchronize_bh()	barrier()
 
 #endif /* __ASM_MIPS_SOFTIRQ_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/spinlock.h linux/include/asm-mips/spinlock.h
--- v2.1.125/linux/include/asm-mips/spinlock.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/spinlock.h	Tue Oct 20 13:52:54 1998
@@ -1,16 +1,24 @@
+/* $Id: spinlock.h,v 1.3 1998/08/28 15:55:39 ralf Exp $
+ */
 #ifndef __ASM_MIPS_SPINLOCK_H
 #define __ASM_MIPS_SPINLOCK_H
 
 #ifndef __SMP__
 
-/* gcc 2.7.2 can crash initializing an empty structure.  For now we
-   try to do though ...  */
-typedef struct { } spinlock_t;
-#define SPIN_LOCK_UNLOCKED { }
+/*
+ * Gcc-2.7.x has a nasty bug with empty initializers.
+ */
+#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
+  typedef struct { } spinlock_t;
+  #define SPIN_LOCK_UNLOCKED { }
+#else
+  typedef struct { int gcc_is_buggy; } spinlock_t;
+  #define SPIN_LOCK_UNLOCKED { 0 }
+#endif
 
 #define spin_lock_init(lock)	do { } while(0)
 #define spin_lock(lock)		do { } while(0)
-#define spin_trylock(lock)	do { } while(0)
+#define spin_trylock(lock)	(1)
 #define spin_unlock_wait(lock)	do { } while(0)
 #define spin_unlock(lock)	do { } while(0)
 #define spin_lock_irq(lock)	cli()
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/stackframe.h linux/include/asm-mips/stackframe.h
--- v2.1.125/linux/include/asm-mips/stackframe.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/stackframe.h	Tue Oct 20 13:52:54 1998
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine.
  *
- * $Id: stackframe.h,v 1.6 1998/05/04 09:19:00 ralf Exp $
+ * $Id: stackframe.h,v 1.7 1998/04/28 19:39:15 ralf Exp $
  */
 #ifndef __ASM_MIPS_STACKFRAME_H
 #define __ASM_MIPS_STACKFRAME_H
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/string.h linux/include/asm-mips/string.h
--- v2.1.125/linux/include/asm-mips/string.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/string.h	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,10 @@
-/*
- * include/asm-mips/string.h
+/* $Id: string.h,v 1.6 1998/07/20 17:52:21 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1994, 1995, 1996, 1997 by Ralf Baechle
- *
- * $Id: string.h,v 1.7 1998/05/04 09:19:02 ralf Exp $
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
  */
 #ifndef __ASM_MIPS_STRING_H
 #define __ASM_MIPS_STRING_H
@@ -127,11 +124,8 @@
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
 
+/* Don't build bcopy at all ...  */
 #define __HAVE_ARCH_BCOPY
-extern __inline__ char * bcopy(const char * src, char * dest, int count)
-{
-	memmove(dest, src, count);
-}
 
 #define __HAVE_ARCH_MEMSCAN
 extern __inline__ void *memscan(void *__addr, int __c, size_t __size)
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/system.h linux/include/asm-mips/system.h
--- v2.1.125/linux/include/asm-mips/system.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/system.h	Tue Oct 20 13:52:54 1998
@@ -1,10 +1,10 @@
-/* $Id: system.h,v 1.8 1998/05/07 00:40:09 ralf Exp $
+/* $Id: system.h,v 1.8 1998/07/20 17:52:21 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994, 1995 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
  * Modified further for R[236]000 by Paul M. Antoine, 1996
  */
 #ifndef __ASM_MIPS_SYSTEM_H
@@ -118,13 +118,13 @@
 	: /* no input */				\
 	: "memory")
 
-#if !defined (__LANGUAGE_ASSEMBLY__)
+#if !defined (_LANGUAGE_ASSEMBLY)
 /*
  * switch_to(n) should switch tasks to task nr n, first
  * checking that n isn't the current task, in which case it does nothing.
  */
 extern asmlinkage void (*resume)(void *tsk);
-#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 #define switch_to(prev,next) \
 do { \
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/termios.h linux/include/asm-mips/termios.h
--- v2.1.125/linux/include/asm-mips/termios.h	Mon Oct  5 13:13:43 1998
+++ linux/include/asm-mips/termios.h	Tue Oct 20 13:52:54 1998
@@ -93,7 +93,7 @@
 #define N_AX25		5
 #define N_X25		6		/* X.25 async */
 #define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_MASC		8	/* Reserved fo Mobitex module <kaz@cafe.net> */
 #define N_R3964		9	/* Reserved for Simatic R3964 module */
 #define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
 
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/timex.h linux/include/asm-mips/timex.h
--- v2.1.125/linux/include/asm-mips/timex.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/timex.h	Tue Oct 20 13:52:54 1998
@@ -1,10 +1,15 @@
-/*
- * linux/include/asm-mips/timex.h
+/* $Id: timex.h,v 1.1 1998/08/17 10:20:18 ralf Exp $
  *
- * mips architecture timex specifications
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ *
+ * FIXME: For some of the supported machines this is dead wrong.
  */
-#ifndef _ASMmips_TIMEX_H
-#define _ASMmips_TIMEX_H
+#ifndef __ASM_MIPS_TIMEX_H
+#define __ASM_MIPS_TIMEX_H
 
 #define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
 #define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
@@ -12,4 +17,4 @@
 	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
 		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
 
-#endif
+#endif /*  __ASM_MIPS_TIMEX_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/uaccess.h linux/include/asm-mips/uaccess.h
--- v2.1.125/linux/include/asm-mips/uaccess.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/uaccess.h	Tue Oct 20 13:52:54 1998
@@ -5,16 +5,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
  *
- * $Id: uaccess.h,v 1.9 1998/05/04 09:19:05 ralf Exp $
+ * $Id: uaccess.h,v 1.15 1998/05/03 11:13:54 ralf Exp $
  */
 #ifndef __ASM_MIPS_UACCESS_H
 #define __ASM_MIPS_UACCESS_H
 
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <asm/asm.h>
 
 #define STR(x)  __STR(x)
 #define __STR(x)  #x
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h
--- v2.1.125/linux/include/asm-mips/unistd.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-mips/unistd.h	Tue Oct 20 13:52:54 1998
@@ -1,11 +1,10 @@
-/*
- * This file contains the system call numbers.
+/* $Id: unistd.h,v 1.21 1998/10/19 21:29:15 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  *
  * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
  * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
@@ -1039,7 +1038,7 @@
 #define __NR_geteuid			(__NR_Linux +  49)
 #define __NR_getegid			(__NR_Linux +  50)
 #define __NR_acct			(__NR_Linux +  51)
-#define __NR_phys			(__NR_Linux +  52)
+#define __NR_umount2			(__NR_Linux +  52)
 #define __NR_lock			(__NR_Linux +  53)
 #define __NR_ioctl			(__NR_Linux +  54)
 #define __NR_fcntl			(__NR_Linux +  55)
@@ -1137,7 +1136,7 @@
 #define __NR_cacheflush			(__NR_Linux + 147)
 #define __NR_cachectl			(__NR_Linux + 148)
 #define __NR_sysmips			(__NR_Linux + 149)
-#define __NR_setup			(__NR_Linux + 150)	/* used only by init, to get system going */
+#define __NR_unused150			(__NR_Linux + 150)
 #define __NR_getsid			(__NR_Linux + 151)
 #define __NR_fdatasync			(__NR_Linux + 152)
 #define __NR__sysctl			(__NR_Linux + 153)
@@ -1191,13 +1190,19 @@
 #define __NR_pwrite			(__NR_Linux + 201)
 #define __NR_chown			(__NR_Linux + 202)
 #define __NR_getcwd			(__NR_Linux + 203)
+#define __NR_capget			(__NR_Linux + 204)
+#define __NR_capset			(__NR_Linux + 205)
+#define __NR_sigaltstack		(__NR_Linux + 206)
+#define __NR_sendfile			(__NR_Linux + 207)
+#define __NR_getpmsg			(__NR_Linux + 208)
+#define __NR_putpmsg			(__NR_Linux + 209)
 
 /*
  * Offset of the last Linux flavoured syscall
  */
-#define __NR_Linux_syscalls		203
+#define __NR_Linux_syscalls		209
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef _LANGUAGE_ASSEMBLY
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
@@ -1416,7 +1421,6 @@
 #define __NR__exit __NR_exit
 static inline _syscall0(int,idle)
 static inline _syscall0(int,pause)
-static inline _syscall1(int,setup,int,magic)
 static inline _syscall0(int,sync)
 static inline _syscall0(pid_t,setsid)
 static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
@@ -1476,6 +1480,6 @@
 }
 
 #endif /* !defined (__KERNEL_SYSCALLS__) */
-#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 #endif /* __ASM_MIPS_UNISTD_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/vector.h linux/include/asm-mips/vector.h
--- v2.1.125/linux/include/asm-mips/vector.h	Wed Dec 10 10:31:11 1997
+++ linux/include/asm-mips/vector.h	Wed Dec 31 16:00:00 1969
@@ -1,54 +0,0 @@
-/*
- * include/asm-mips/vector.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
- */
-#ifndef __ASM_MIPS_VECTOR_H
-#define __ASM_MIPS_VECTOR_H
-
-/*
- * These vector structures are not very good to maintain - they'd probably
- * grow to at leat three times the size - so I'll remove 'em and replace
- * the with lots of ordinary variables.
- */
-extern void (*irq_setup)(void);
-extern asmlinkage void (*fd_cacheflush)(const void *addr, size_t size);
-
-/*
- * This structure defines how to access various features of
- * different machine types and how to access them.
- */
-struct feature {
-	/*
-	 * How to access the floppy controller's ports.
-	 */
-	unsigned char (*fd_inb)(unsigned int port);
-	void (*fd_outb)(unsigned char value, unsigned int port);
-	/*
-	 * How to access the floppy DMA functions.
-	 */
-	void (*fd_enable_dma)(int channel);
-	void (*fd_disable_dma)(int channel);
-	int (*fd_request_dma)(int channel);
-	void (*fd_free_dma)(int channel);
-	void (*fd_clear_dma_ff)(int channel);
-	void (*fd_set_dma_mode)(int channel, char mode);
-	void (*fd_set_dma_addr)(int channel, unsigned int a);
-	void (*fd_set_dma_count)(int channel, unsigned int count);
-	int (*fd_get_dma_residue)(int channel);
-	void (*fd_enable_irq)(int irq);
-	void (*fd_disable_irq)(int irq);
-	/*
-	 * How to access the RTC register of the DS1287?
-	 */
-	unsigned char (*rtc_read_data)(unsigned long addr);
-	void (*rtc_write_data)(unsigned char data, unsigned long addr);
-};
-
-extern struct feature *feature;
-
-#endif /* __ASM_MIPS_VECTOR_H */
diff -u --recursive --new-file v2.1.125/linux/include/asm-mips/watch.h linux/include/asm-mips/watch.h
--- v2.1.125/linux/include/asm-mips/watch.h	Fri May  8 23:14:55 1998
+++ linux/include/asm-mips/watch.h	Tue Oct 20 13:52:54 1998
@@ -1,13 +1,10 @@
-/*
- * Functions to use the watch register debugging functionality.
+/* $Id: watch.h,v 1.3 1998/08/19 21:58:15 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997 by Ralf Baechle
- *
- * $Id: watch.h,v 1.3 1998/05/01 01:36:18 ralf Exp $
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
  */
 #ifndef __ASM_WATCH_H
 #define __ASM_WATCH_H
@@ -24,9 +21,9 @@
 
 extern char watch_available;
 
-extern asmlinkage __watch_set(unsigned long addr, enum wref_type ref);
-extern asmlinkage __watch_clear(void);
-extern asmlinkage __watch_reenable(void);
+extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref);
+extern asmlinkage void __watch_clear(void);
+extern asmlinkage void __watch_reenable(void);
 
 #define watch_set(addr, ref)					\
 	if (watch_available)					\
diff -u --recursive --new-file v2.1.125/linux/include/asm-ppc/fcntl.h linux/include/asm-ppc/fcntl.h
--- v2.1.125/linux/include/asm-ppc/fcntl.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-ppc/fcntl.h	Wed Oct 21 13:31:06 1998
@@ -16,6 +16,8 @@
 #define O_NDELAY	O_NONBLOCK
 #define O_SYNC		010000
 #define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
diff -u --recursive --new-file v2.1.125/linux/include/asm-sparc/fcntl.h linux/include/asm-sparc/fcntl.h
--- v2.1.125/linux/include/asm-sparc/fcntl.h	Mon Oct  5 13:13:43 1998
+++ linux/include/asm-sparc/fcntl.h	Wed Oct 21 10:02:49 1998
@@ -17,6 +17,8 @@
 #define O_NONBLOCK	0x4000
 #define O_NDELAY	(0x0004 | O_NONBLOCK)
 #define O_NOCTTY	0x8000	/* not fcntl */
+#define O_DIRECTORY	0x10000	/* must be a directory */
+#define O_NOFOLLOW	0x20000	/* don't follow links */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
diff -u --recursive --new-file v2.1.125/linux/include/asm-sparc64/fcntl.h linux/include/asm-sparc64/fcntl.h
--- v2.1.125/linux/include/asm-sparc64/fcntl.h	Mon Oct  5 13:13:44 1998
+++ linux/include/asm-sparc64/fcntl.h	Wed Oct 21 10:02:49 1998
@@ -17,6 +17,8 @@
 #define O_SYNC		0x2000
 #define O_NONBLOCK	0x4000
 #define O_NOCTTY	0x8000	/* not fcntl */
+#define O_DIRECTORY	0x10000	/* must be a directory */
+#define O_NOFOLLOW	0x20000	/* don't follow links */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
diff -u --recursive --new-file v2.1.125/linux/include/linux/blk.h linux/include/linux/blk.h
--- v2.1.125/linux/include/linux/blk.h	Fri Jul 31 17:06:37 1998
+++ linux/include/linux/blk.h	Fri Oct 23 10:15:50 1998
@@ -147,13 +147,13 @@
 #define DEVICE_ON(device)
 #define DEVICE_OFF(device)
 
-#elif (MAJOR_NR == SCSI_DISK_MAJOR)
+#elif (SCSI_DISK_MAJOR(MAJOR_NR))
 
 #define DEVICE_NAME "scsidisk"
 #define DEVICE_INTR do_sd  
 #define TIMEOUT_VALUE (2*HZ)
 #define DEVICE_REQUEST do_sd_request
-#define DEVICE_NR(device) (MINOR(device) >> 4)
+#define DEVICE_NR(device) (((MAJOR(device) & SD_MAJOR_MASK) << (8 - 4)) + (MINOR(device) >> 4))
 #define DEVICE_ON(device)
 #define DEVICE_OFF(device)
 
diff -u --recursive --new-file v2.1.125/linux/include/linux/capability.h linux/include/linux/capability.h
--- v2.1.125/linux/include/linux/capability.h	Fri Jul 31 17:05:53 1998
+++ linux/include/linux/capability.h	Fri Oct 23 10:14:47 1998
@@ -38,9 +38,19 @@
   
 #ifdef __KERNEL__
 
+/* #define STRICT_CAP_T_TYPECHECKS */
+
+#ifdef STRICT_CAP_T_TYPECHECKS
+
 typedef struct kernel_cap_struct {
 	__u32 cap;
 } kernel_cap_t;
+
+#else
+
+typedef __u32 kernel_cap_t;
+
+#endif
   
 #define _USER_CAP_HEADER_SIZE  (2*sizeof(__u32))
 #define _KERNEL_CAP_T_SIZE     (sizeof(kernel_cap_t))
@@ -259,51 +269,63 @@
 /*
  * Internal kernel functions only
  */
+ 
+#ifdef STRICT_CAP_T_TYPECHECKS
+
+#define to_cap_t(x) { x }
+#define cap_t(x) (x).cap
+
+#else
+
+#define to_cap_t(x) (x)
+#define cap_t(x) (x)
+
+#endif
 
-#define CAP_EMPTY_SET       {  0 }
-#define CAP_FULL_SET        { ~0 }
-#define CAP_INIT_EFF_SET    { ~0 & ~CAP_TO_MASK(CAP_SETPCAP) }
-#define CAP_INIT_INH_SET    { ~0 & ~CAP_TO_MASK(CAP_SETPCAP) }
+#define CAP_EMPTY_SET       to_cap_t(0)
+#define CAP_FULL_SET        to_cap_t(~0)
+#define CAP_INIT_EFF_SET    to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP))
+#define CAP_INIT_INH_SET    to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP))
 
 #define CAP_TO_MASK(x) (1 << (x))
-#define cap_raise(c, flag)   ((c).cap |=  CAP_TO_MASK(flag))
-#define cap_lower(c, flag)   ((c).cap &= ~CAP_TO_MASK(flag))
-#define cap_raised(c, flag)  ((c).cap &   CAP_TO_MASK(flag))
+#define cap_raise(c, flag)   (cap_t(c) |=  CAP_TO_MASK(flag))
+#define cap_lower(c, flag)   (cap_t(c) &= ~CAP_TO_MASK(flag))
+#define cap_raised(c, flag)  (cap_t(c) &   CAP_TO_MASK(flag))
 
 static inline kernel_cap_t cap_combine(kernel_cap_t a, kernel_cap_t b)
 {
      kernel_cap_t dest;
-     dest.cap = a.cap | b.cap;
+     cap_t(dest) = cap_t(a) | cap_t(b);
      return dest;
 }
 
 static inline kernel_cap_t cap_intersect(kernel_cap_t a, kernel_cap_t b)
 {
      kernel_cap_t dest;
-     dest.cap = a.cap & b.cap;
+     cap_t(dest) = cap_t(a) & cap_t(b);
      return dest;
 }
 
 static inline kernel_cap_t cap_drop(kernel_cap_t a, kernel_cap_t drop)
 {
      kernel_cap_t dest;
-     dest.cap = a.cap & ~drop.cap;
+     cap_t(dest) = cap_t(a) & ~cap_t(drop);
      return dest;
 }
 
 static inline kernel_cap_t cap_invert(kernel_cap_t c)
 {
      kernel_cap_t dest;
-     dest.cap = ~c.cap;
+     cap_t(dest) = ~cap_t(c);
      return dest;
 }
 
-#define cap_isclear(c)       (!(c).cap)
-#define cap_issubset(a,set)  (!((a).cap & ~(set).cap))
+#define cap_isclear(c)       (!cap_t(c))
+#define cap_issubset(a,set)  (!(cap_t(a) & ~cap_t(set)))
 
-#define cap_clear(c)         do { (c).cap =  0; } while(0)
-#define cap_set_full(c)      do { (c).cap = ~0; } while(0)
-#define cap_mask(c,mask)     do { (c).cap &= (mask).cap; } while(0)
+#define cap_clear(c)         do { cap_t(c) =  0; } while(0)
+#define cap_set_full(c)      do { cap_t(c) = ~0; } while(0)
+#define cap_mask(c,mask)     do { cap_t(c) &= cap_t(mask); } while(0)
 
 #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
 
diff -u --recursive --new-file v2.1.125/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.1.125/linux/include/linux/fs.h	Mon Sep 28 10:51:35 1998
+++ linux/include/linux/fs.h	Fri Oct 23 10:14:46 1998
@@ -114,19 +114,27 @@
  * ioctl() that is not currently implemented.
  *
  * Exception: MS_RDONLY is always applied to the entire file system.
+ *
+ * Unfortunately, it is possible to change a filesystems flags with it mounted
+ * with files in use.  This means that all of the inodes will not have their
+ * i_flags updated.  Hence, i_flags no longer inherit the superblock mount
+ * flags, so these have to be checked separately. -- rmk@arm.uk.linux.org
  */
+#define __IS_FLG(inode,flg) (((inode)->i_sb && (inode)->i_sb->s_flags & (flg)) \
+				|| (inode)->i_flags & (flg))
+
 #define IS_RDONLY(inode) (((inode)->i_sb) && ((inode)->i_sb->s_flags & MS_RDONLY))
-#define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID)
-#define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV)
-#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC)
-#define IS_SYNC(inode) ((inode)->i_flags & MS_SYNCHRONOUS)
-#define IS_MANDLOCK(inode) ((inode)->i_flags & MS_MANDLOCK)
-
-#define IS_QUOTAINIT(inode) ((inode)->i_flags & S_QUOTA)
-#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
-#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
-#define IS_NOATIME(inode) ((inode)->i_flags & MS_NOATIME)
-#define IS_NODIRATIME(inode) ((inode)->i_flags & MS_NODIRATIME)
+#define IS_NOSUID(inode)	__IS_FLG(inode, MS_NOSUID)
+#define IS_NODEV(inode)		__IS_FLG(inode, MS_NODEV)
+#define IS_NOEXEC(inode)	__IS_FLG(inode, MS_NOEXEC)
+#define IS_SYNC(inode)		__IS_FLG(inode, MS_SYNCHRONOUS)
+#define IS_MANDLOCK(inode)	__IS_FLG(inode, MS_MANDLOCK)
+
+#define IS_QUOTAINIT(inode)	((inode)->i_flags & S_QUOTA)
+#define IS_APPEND(inode)	((inode)->i_flags & S_APPEND)
+#define IS_IMMUTABLE(inode)	((inode)->i_flags & S_IMMUTABLE)
+#define IS_NOATIME(inode)	__IS_FLG(inode, MS_NOATIME)
+#define IS_NODIRATIME(inode)	__IS_FLG(inode, MS_NODIRATIME)
 
 /* the read-only stuff doesn't really belong here, but any other place is
    probably as bad and I don't want to create yet another include file. */
@@ -479,39 +487,6 @@
 
 #include <linux/stat.h>
 
-#define FLOCK_VERIFY_READ  1
-#define FLOCK_VERIFY_WRITE 2
-
-extern int locks_mandatory_locked(struct inode *inode);
-extern int locks_mandatory_area(int read_write, struct inode *inode,
-				struct file *filp, loff_t offset,
-				size_t count);
-
-extern inline int locks_verify_locked(struct inode *inode)
-{
-	/* Candidates for mandatory locking have the setgid bit set
-	 * but no group execute bit -  an otherwise meaningless combination.
-	 */
-	if (IS_MANDLOCK(inode) &&
-	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
-		return (locks_mandatory_locked(inode));
-	return (0);
-}
-
-extern inline int locks_verify_area(int read_write, struct inode *inode,
-				    struct file *filp, loff_t offset,
-				    size_t count)
-{
-	/* Candidates for mandatory locking have the setgid bit set
-	 * but no group execute bit -  an otherwise meaningless combination.
-	 */
-	if (IS_MANDLOCK(inode) &&
-	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
-		return (locks_mandatory_area(read_write, inode, filp, offset,
-					     count));
-	return (0);
-}
-
 struct fasync_struct {
 	int    magic;
 	int    fa_fd;
@@ -668,6 +643,41 @@
 
 extern int register_filesystem(struct file_system_type *);
 extern int unregister_filesystem(struct file_system_type *);
+
+
+#define FLOCK_VERIFY_READ  1
+#define FLOCK_VERIFY_WRITE 2
+
+extern int locks_mandatory_locked(struct inode *inode);
+extern int locks_mandatory_area(int read_write, struct inode *inode,
+				struct file *filp, loff_t offset,
+				size_t count);
+
+extern inline int locks_verify_locked(struct inode *inode)
+{
+	/* Candidates for mandatory locking have the setgid bit set
+	 * but no group execute bit -  an otherwise meaningless combination.
+	 */
+	if (IS_MANDLOCK(inode) &&
+	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+		return (locks_mandatory_locked(inode));
+	return (0);
+}
+
+extern inline int locks_verify_area(int read_write, struct inode *inode,
+				    struct file *filp, loff_t offset,
+				    size_t count)
+{
+	/* Candidates for mandatory locking have the setgid bit set
+	 * but no group execute bit -  an otherwise meaningless combination.
+	 */
+	if (IS_MANDLOCK(inode) &&
+	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+		return (locks_mandatory_area(read_write, inode, filp, offset,
+					     count));
+	return (0);
+}
+
 
 /* fs/open.c */
 
diff -u --recursive --new-file v2.1.125/linux/include/linux/genhd.h linux/include/linux/genhd.h
--- v2.1.125/linux/include/linux/genhd.h	Sat Sep  5 16:46:41 1998
+++ linux/include/linux/genhd.h	Fri Oct 23 10:14:44 1998
@@ -21,6 +21,10 @@
 #define CONFIG_SUN_PARTITION 1
 #endif
 
+#if defined(CONFIG_SGI)
+#define CONFIG_SGI_PARTITION 1
+#endif
+
 /* These three have identical behaviour; use the second one if DOS fdisk gets
    confused about extended/logical partitions starting past cylinder 1023. */
 #define DOS_EXTENDED_PARTITION 5
diff -u --recursive --new-file v2.1.125/linux/include/linux/joystick.h linux/include/linux/joystick.h
--- v2.1.125/linux/include/linux/joystick.h	Fri Oct  9 13:27:16 1998
+++ linux/include/linux/joystick.h	Fri Oct 23 10:16:44 1998
@@ -34,7 +34,7 @@
  * Version
  */
 
-#define JS_VERSION		0x01020b
+#define JS_VERSION		0x01020c
 
 /*
  * Types and constants for reading from /dev/js
@@ -158,7 +158,7 @@
 #define __cli cli
 #define __save_flags(flags) save_flags(flags)
 #define __restore_flags(flags)	restore_flags(flags)
-#define spin_lock_irqsave(x, flags) do { cli(); save_flags(flags); } while (0)
+#define spin_lock_irqsave(x, flags) do { save_flags(flags); cli(); } while (0)
 #define spin_unlock_irqrestore(x, flags) restore_flags(flags)
 #define spin_lock_init(x) do { } while (0)
 typedef struct { int something; } spinlock_t;
diff -u --recursive --new-file v2.1.125/linux/include/linux/loop.h linux/include/linux/loop.h
--- v2.1.125/linux/include/linux/loop.h	Thu Sep 17 17:53:38 1998
+++ linux/include/linux/loop.h	Sat Oct 17 15:34:26 1998
@@ -85,10 +85,14 @@
  * Loop filter types
  */
 
-#define LO_CRYPT_NONE	0
-#define LO_CRYPT_XOR	1
-#define LO_CRYPT_DES	2
-#define LO_CRYPT_DUMMY     9
+#define LO_CRYPT_NONE	  0
+#define LO_CRYPT_XOR	  1
+#define LO_CRYPT_DES	  2
+#define LO_CRYPT_FISH2    3    /* Brand new Twofish encryption */
+#define LO_CRYPT_BLOW     4
+#define LO_CRYPT_CAST128  5
+#define LO_CRYPT_IDEA     6
+#define LO_CRYPT_DUMMY    9
 #define LO_CRYPT_SKIPJACK 10
 #define MAX_LO_CRYPT	20
 
@@ -99,8 +103,12 @@
 	int (*transfer)(struct loop_device *lo, int cmd, 
 			char *raw_buf, char *loop_buf, int size);
 	int (*init)(struct loop_device *, struct loop_info *); 
-	int (*release)(struct loop_device *);  
+	/* release is called from loop_unregister_transfer or clr_fd */
+	int (*release)(struct loop_device *); 
 	int (*ioctl)(struct loop_device *, int cmd, unsigned long arg);
+	/* lock and unlock manage the module use counts */ 
+	void (*lock)(struct loop_device *);
+	void (*unlock)(struct loop_device *);
 }; 
 
 int  loop_register_transfer(struct loop_func_table *funcs);
diff -u --recursive --new-file v2.1.125/linux/include/linux/lp.h linux/include/linux/lp.h
--- v2.1.125/linux/include/linux/lp.h	Sun Jun  7 11:16:39 1998
+++ linux/include/linux/lp.h	Fri Oct  9 12:20:27 1998
@@ -43,11 +43,11 @@
 /* The parallel port specs apparently say that there needs to be
  * a .5usec wait before and after the strobe.  Since there are wildly
  * different computers running linux, I can't come up with a perfect
- * value, but since it worked well on most printers before without,
- * I'll initialize it to 0.
+ * value so if 20 is not good for you use `tunelp /dev/lp? -w ?`.
+ * You can also set it to 0 if your printer handle that.
  */
 
-#define LP_INIT_WAIT 0
+#define LP_INIT_WAIT 20
 
 /* This is the amount of time that the driver waits for the printer to
  * catch up when the printer's buffer appears to be filled.  If you
diff -u --recursive --new-file v2.1.125/linux/include/linux/major.h linux/include/linux/major.h
--- v2.1.125/linux/include/linux/major.h	Thu Aug  6 14:06:34 1998
+++ linux/include/linux/major.h	Wed Oct 14 11:43:14 1998
@@ -28,7 +28,7 @@
 #define LP_MAJOR	6
 #define VCS_MAJOR	7
 #define LOOP_MAJOR	7
-#define SCSI_DISK_MAJOR	8
+#define SCSI_DISK0_MAJOR 8
 #define SCSI_TAPE_MAJOR	9
 #define MD_MAJOR        9
 #define MISC_MAJOR	10
@@ -81,6 +81,14 @@
 #define IDE4_MAJOR	56
 #define IDE5_MAJOR	57
 
+#define SCSI_DISK1_MAJOR	65
+#define SCSI_DISK2_MAJOR	66
+#define SCSI_DISK3_MAJOR	67
+#define SCSI_DISK4_MAJOR	68
+#define SCSI_DISK5_MAJOR	69
+#define SCSI_DISK6_MAJOR	70
+#define SCSI_DISK7_MAJOR	71
+
 #define SPECIALIX_NORMAL_MAJOR 75
 #define SPECIALIX_CALLOUT_MAJOR 76
 
@@ -92,8 +100,11 @@
  * Tests for SCSI devices.
  */
 
+#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
+  ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR))
+  
 #define SCSI_BLK_MAJOR(M) \
-  ((M) == SCSI_DISK_MAJOR	\
+  (SCSI_DISK_MAJOR(M)	\
    || (M) == SCSI_CDROM_MAJOR)
 
 static __inline__ int scsi_blk_major(int m) {
diff -u --recursive --new-file v2.1.125/linux/include/linux/mca.h linux/include/linux/mca.h
--- v2.1.125/linux/include/linux/mca.h	Thu Dec 12 06:54:20 1996
+++ linux/include/linux/mca.h	Sat Oct 17 15:34:26 1998
@@ -27,7 +27,7 @@
 	See Documentation/mca.txt or one of the existing drivers for
 	more information.
 */
-#define MCA_NOTFOUND	-1
+#define MCA_NOTFOUND	(-1)
 #define MCA_INTEGSCSI	(MCA_MAX_SLOT_NR)
 #define MCA_INTEGVIDEO	(MCA_MAX_SLOT_NR+1)
 
@@ -40,11 +40,16 @@
 devices.  Returns MCA_NOTFOUND if id not found.  Also checks the
 integrated adapters. */
 extern int mca_find_adapter( int id, int start );
+extern int mca_find_unused_adapter( int id, int start );
 
 /* adapter state info - returns 0 if no */
 extern int mca_isadapter( int slot );
 extern int mca_isenabled( int slot );
 
+extern int mca_is_adapter_used( int slot );
+extern int mca_mark_as_used( int slot );
+extern void mca_mark_as_unused( int slot );
+
 /* gets a byte out of POS register (stored in memory) */
 extern unsigned char mca_read_stored_pos( int slot, int reg );
 
@@ -87,5 +92,9 @@
 
 /* write a byte to the specified POS register. */
 extern void mca_write_pos( int slot, int reg, unsigned char byte );
+
+/* Should only be called by the NMI interrupt handler, this will do some
+fancy stuff to figure out what might have generated a NMI. */
+extern void mca_handle_nmi( void );
 
 #endif /* _LINUX_MCA_H */
diff -u --recursive --new-file v2.1.125/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.1.125/linux/include/linux/mm.h	Tue Aug 18 22:02:07 1998
+++ linux/include/linux/mm.h	Fri Oct 23 10:14:48 1998
@@ -380,6 +380,36 @@
 	return vma;
 }
 
+extern __inline__ void kswapd_wakeup(void)
+{
+	wake_up(&kswapd_wait);
+}
+
+#define buffer_under_min()	((buffermem >> PAGE_SHIFT) * 100 < \
+				buffer_mem.min_percent * num_physpages)
+#define buffer_under_borrow()	((buffermem >> PAGE_SHIFT) * 100 < \
+				buffer_mem.borrow_percent * num_physpages)
+#define buffer_under_max()	((buffermem >> PAGE_SHIFT) * 100 < \
+				buffer_mem.max_percent * num_physpages)
+#define buffer_over_min()	((buffermem >> PAGE_SHIFT) * 100 > \
+				buffer_mem.min_percent * num_physpages)
+#define buffer_over_borrow()	((buffermem >> PAGE_SHIFT) * 100 > \
+				buffer_mem.borrow_percent * num_physpages)
+#define buffer_over_max()	((buffermem >> PAGE_SHIFT) * 100 > \
+				buffer_mem.max_percent * num_physpages)
+#define pgcache_under_min()	(page_cache_size * 100 < \
+				page_cache.min_percent * num_physpages)
+#define pgcache_under_borrow()	(page_cache_size * 100 < \
+				page_cache.borrow_percent * num_physpages)
+#define pgcache_under_max()	(page_cache_size * 100 < \
+				page_cache.max_percent * num_physpages)
+#define pgcache_over_min()	(page_cache_size * 100 > \
+				page_cache.min_percent * num_physpages)
+#define pgcache_over_borrow()	(page_cache_size * 100 > \
+				page_cache.borrow_percent * num_physpages)
+#define pgcache_over_max()	(page_cache_size * 100 > \
+				page_cache.max_percent * num_physpages)
+
 #endif /* __KERNEL__ */
 
 #endif
diff -u --recursive --new-file v2.1.125/linux/include/linux/nfsd/export.h linux/include/linux/nfsd/export.h
--- v2.1.125/linux/include/linux/nfsd/export.h	Fri Jul 31 17:10:04 1998
+++ linux/include/linux/nfsd/export.h	Fri Oct 23 10:15:38 1998
@@ -86,7 +86,7 @@
 void			exp_putclient(struct svc_client *clp);
 struct svc_export *	exp_get(struct svc_client *clp, kdev_t dev, ino_t ino);
 int			exp_rootfh(struct svc_client *, kdev_t, ino_t,
-					struct knfs_fh *);
+					char *path, struct knfs_fh *);
 int			nfserrno(int errno);
 void			exp_nlmdetach(void);
 
diff -u --recursive --new-file v2.1.125/linux/include/linux/nfsd/syscall.h linux/include/linux/nfsd/syscall.h
--- v2.1.125/linux/include/linux/nfsd/syscall.h	Fri Jul 31 17:10:04 1998
+++ linux/include/linux/nfsd/syscall.h	Fri Oct 23 10:15:44 1998
@@ -32,8 +32,8 @@
 #define NFSCTL_EXPORT		3	/* export a file system. */
 #define NFSCTL_UNEXPORT		4	/* unexport a file system. */
 #define NFSCTL_UGIDUPDATE	5	/* update a client's uid/gid map. */
-#define NFSCTL_GETFH		6	/* get an fh (used by mountd) */
-
+#define NFSCTL_GETFH		6	/* get an fh by ino (used by mountd) */
+#define NFSCTL_GETFD		7	/* get an fh by path (used by mountd) */
 
 /* SVC */
 struct nfsctl_svc {
@@ -81,6 +81,13 @@
 	int			gf_version;
 };
 
+/* GETFD */
+struct nfsctl_fdparm {
+	struct sockaddr		gd_addr;
+	char			gd_path[NFS_MAXPATHLEN+1];
+	int			gd_version;
+};
+
 /*
  * This is the argument union.
  */
@@ -92,6 +99,7 @@
 		struct nfsctl_export	u_export;
 		struct nfsctl_uidmap	u_umap;
 		struct nfsctl_fhparm	u_getfh;
+		struct nfsctl_fdparm	u_getfd;
 		unsigned int		u_debug;
 	} u;
 #define ca_svc		u.u_svc
@@ -99,6 +107,7 @@
 #define ca_export	u.u_export
 #define ca_umap		u.u_umap
 #define ca_getfh	u.u_getfh
+#define ca_getfd	u.u_getfd
 #define ca_authd	u.u_authd
 #define ca_debug	u.u_debug
 };
diff -u --recursive --new-file v2.1.125/linux/include/linux/parport.h linux/include/linux/parport.h
--- v2.1.125/linux/include/linux/parport.h	Mon Oct  5 13:13:44 1998
+++ linux/include/linux/parport.h	Fri Oct 23 10:16:41 1998
@@ -123,7 +123,7 @@
 
 	void (*enable_irq)(struct parport *);
 	void (*disable_irq)(struct parport *);
-	int (*examine_irq)(struct parport *);
+	void (*interrupt)(int, void *, struct pt_regs *);
 
 	void (*inc_use_count)(void);
 	void (*dec_use_count)(void);
@@ -206,7 +206,9 @@
 	void *private_data;     /* for lowlevel driver */
 
 	int number;		/* port index - the `n' in `parportn' */
-	spinlock_t lock;
+	spinlock_t pardevice_lock;
+	spinlock_t waitlist_lock;
+	spinlock_t cad_lock;
 };
 
 /* parport_register_port registers a new parallel port at the given address (if
@@ -234,10 +236,9 @@
 
 /* parport_register_device declares that a device is connected to a port, and 
  * tells the kernel all it needs to know.  
- * pf is the preemption function (may be NULL for a transient driver)
- * kf is the wake-up function (may be NULL for a transient driver)
+ * pf is the preemption function (may be NULL for no callback)
+ * kf is the wake-up function (may be NULL for no callback)
  * irq_func is the interrupt handler (may be NULL for no interrupts)
- * Only one lurking driver can be used on a given port. 
  * handle is a user pointer that gets handed to callback functions. 
  */
 struct pardevice *parport_register_device(struct parport *port, 
@@ -294,11 +295,31 @@
 	return parport_claim_or_block(dev);
 }
 
+/*
+ * Lowlevel drivers _can_ call this support function to handle irqs.
+ */
+extern __inline__ void parport_generic_irq(int irq, struct parport *port,
+					   struct pt_regs *regs)
+{
+	read_lock(&port->cad_lock);
+	if (!port->cad)
+		goto out_unlock;
+	if (port->cad->irq_func)
+		port->cad->irq_func(irq, port->cad->private, regs);
+	else
+		printk(KERN_ERR "%s: irq%d happened with irq_func NULL "
+		       "with %s as cad!\n", port->name, irq, port->cad->name);
+ out_unlock:
+	read_unlock(&port->cad_lock);
+}
+
 /* Flags used to identify what a device does. */
-#define PARPORT_DEV_TRAN	        0x0000  /* We're transient. */
-#define PARPORT_DEV_LURK	        0x0001  /* We lurk. */
+#define PARPORT_DEV_TRAN		0	/* WARNING !! DEPRECATED !! */
+#define PARPORT_DEV_LURK		(1<<0)	/* WARNING !! DEPRECATED !! */
+#define PARPORT_DEV_EXCL		(1<<1)	/* Need exclusive access. */
 
-#define PARPORT_FLAG_COMA		1
+#define PARPORT_FLAG_COMA		(1<<0)
+#define PARPORT_FLAG_EXCL		(1<<1)	/* EXCL driver registered. */
 
 extern void parport_parse_irqs(int, const char *[], int irqval[]);
 extern int parport_ieee1284_nibble_mode_ok(struct parport *, unsigned char);
diff -u --recursive --new-file v2.1.125/linux/include/linux/parport_pc.h linux/include/linux/parport_pc.h
--- v2.1.125/linux/include/linux/parport_pc.h	Tue Jun 23 10:01:29 1998
+++ linux/include/linux/parport_pc.h	Fri Oct 23 10:16:03 1998
@@ -132,8 +132,6 @@
 
 extern int parport_pc_ecp_write_block(struct parport *p, void *buf, size_t length, void (*fn)(struct parport *, void *, size_t), void *handle);
 
-extern int parport_pc_examine_irq(struct parport *p);
-
 extern void parport_pc_inc_use_count(void);
 
 extern void parport_pc_dec_use_count(void);
diff -u --recursive --new-file v2.1.125/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.1.125/linux/include/linux/pci.h	Fri Oct  9 13:27:16 1998
+++ linux/include/linux/pci.h	Fri Oct 23 10:14:44 1998
@@ -1,5 +1,5 @@
 /*
- *	$Id: pci.h,v 1.84 1998/08/17 23:06:43 cort Exp $
+ *	$Id: pci.h,v 1.87 1998/10/11 15:13:12 mj Exp $
  *
  *	PCI defines and function prototypes
  *	Copyright 1994, Drew Eckhardt
@@ -1037,12 +1037,11 @@
 #define PCI_DEVICE_ID_ADAPTEC_7884	0x8478
 #define PCI_DEVICE_ID_ADAPTEC_1030	0x8b78
 
-#define PCI_VENDOR_ID_ADAPTEC2  0x9005
-#define PCI_DEVICE_ID_ADAPTEC2_2940U2  0x0010
-#define PCI_DEVICE_ID_ADAPTEC2_7890  0x001f
-#define PCI_DEVICE_ID_ADAPTEC2_3940U2  0x0050
-#define PCI_DEVICE_ID_ADAPTEC2_7896  0x005f
-
+#define PCI_VENDOR_ID_ADAPTEC2		0x9005
+#define PCI_DEVICE_ID_ADAPTEC2_2940U2	0x0010
+#define PCI_DEVICE_ID_ADAPTEC2_7890	0x001f
+#define PCI_DEVICE_ID_ADAPTEC2_3940U2	0x0050
+#define PCI_DEVICE_ID_ADAPTEC2_7896	0x005f
 
 #define PCI_VENDOR_ID_ATRONICS		0x907f
 #define PCI_DEVICE_ID_ATRONICS_2015	0x2015
diff -u --recursive --new-file v2.1.125/linux/include/linux/sdladrv.h linux/include/linux/sdladrv.h
--- v2.1.125/linux/include/linux/sdladrv.h	Sun Feb  2 05:18:47 1997
+++ linux/include/linux/sdladrv.h	Fri Oct  9 11:56:59 1998
@@ -33,7 +33,7 @@
 	unsigned fwid;			/* firmware ID */
 	unsigned port;			/* adapter I/O port base */
 	int irq;			/* interrupt request level */
-	unsigned long dpmbase;		/* dual-port memory base */
+	void * dpmbase;			/* dual-port memory base */
 	unsigned dpmsize;		/* dual-port memory size */
 	unsigned pclk;			/* CPU clock rate, kHz */
 	unsigned long memory;		/* memory size */
diff -u --recursive --new-file v2.1.125/linux/include/linux/shm.h linux/include/linux/shm.h
--- v2.1.125/linux/include/linux/shm.h	Wed Aug 26 11:37:44 1998
+++ linux/include/linux/shm.h	Sat Oct 17 15:52:18 1998
@@ -14,8 +14,13 @@
 	__kernel_ipc_pid_t	shm_cpid;	/* pid of creator */
 	__kernel_ipc_pid_t	shm_lpid;	/* pid of last operator */
 	unsigned short		shm_nattch;	/* no. of current attaches */
+};
+
+struct shmid_kernel
+{	
+	struct shmid_ds		u;
 	/* the following are private */
-	unsigned short		shm_npages;	/* size of segment (pages) */
+	unsigned long		shm_npages;	/* size of segment (pages) */
 	unsigned long		*shm_pages;	/* array of ptrs to frames -> SHMMAX */ 
 	struct vm_area_struct	*attaches;	/* descriptors for attaches */
 };
diff -u --recursive --new-file v2.1.125/linux/include/linux/tqueue.h linux/include/linux/tqueue.h
--- v2.1.125/linux/include/linux/tqueue.h	Fri Jul 31 17:05:52 1998
+++ linux/include/linux/tqueue.h	Tue Oct 20 15:29:49 1998
@@ -97,19 +97,27 @@
  */
 extern __inline__ void run_task_queue(task_queue *list)
 {
-	struct tq_struct *p;
+	if (*list) {
+		unsigned long flags;
+		struct tq_struct *p;
 
-	p = xchg(list,NULL);
-	while (p) {
-		void *arg;
-		void (*f) (void *);
-		struct tq_struct *save_p;
-		arg    = p -> data;
-		f      = p -> routine;
-		save_p = p;
-		p      = p -> next;
-		save_p -> sync = 0;
-		(*f)(arg);
+		spin_lock_irqsave(&tqueue_lock, flags);
+		p = *list;
+		*list = NULL;
+		spin_unlock_irqrestore(&tqueue_lock, flags);
+		
+		while (p) {
+			void *arg;
+			void (*f) (void *);
+			struct tq_struct *save_p;
+			arg    = p -> data;
+			f      = p -> routine;
+			save_p = p;
+			p      = p -> next;
+			mb();
+			save_p -> sync = 0;
+			(*f)(arg);
+		}
 	}
 }
 
diff -u --recursive --new-file v2.1.125/linux/include/linux/ufs_fs.h linux/include/linux/ufs_fs.h
--- v2.1.125/linux/include/linux/ufs_fs.h	Sat Sep  5 16:46:41 1998
+++ linux/include/linux/ufs_fs.h	Fri Oct 16 11:53:20 1998
@@ -16,6 +16,8 @@
  *
  * NeXTstep support added on February 5th 1998 by
  * Niels Kristian Bech Jensen <nkbj@image.dk>.
+ *
+ * Write support by Daniel Pirkl <daniel.pirkl@email.cz>
  */
 
 #ifndef __LINUX_UFS_FS_H
@@ -67,7 +69,7 @@
 
 /* From here to next blank line, s_flags for ufs_sb_info */
 /* endianness */
-#define UFS_BYTESEX		0x00000001	/* mask; leave room to 0xF */
+#define UFS_BYTESEX             0x00000001      /* mask; leave room to 0xF */
 #if defined(__LITTLE_ENDIAN) || defined(__BIG_ENDIAN)
 /* these are for sane architectures */
 #define UFS_NATIVE_ENDIAN	0x00000000
@@ -91,20 +93,34 @@
 #define UFS_ST_OLD		0x00000000
 #define UFS_ST_44BSD		0x00000100
 #define UFS_ST_SUN		0x00000200
-#define UFS_ST_NEXT		0x00000400
-/* filesystem flavors (combo of features) */
-#define UFS_FEATURES		0x00FFFFF0	/* room for extension */
-#define UFS_VANILLA		0x00000000
-#define UFS_OLD			0x00000000	/* 4.2BSD */
-#define UFS_44BSD		0x00000130
-#define UFS_HURD		0x00000130
-#define UFS_SUN			0x00000200
-#define UFS_NEXT		0x00000400
+/*cylinder group encoding */
+#define UFS_CG_MASK		0x00003000	/* mask for the following */
+#define UFS_CG_OLD		0x00000000
+#define UFS_CG_44BSD		0x00002000
+#define UFS_CG_SUN		0x00001000
 
 /* fs_inodefmt options */
 #define UFS_42INODEFMT	-1
 #define UFS_44INODEFMT	2
 
+/* mount options */
+#define UFS_MOUNT_ONERROR		0x0000000F
+#define UFS_MOUNT_ONERROR_PANIC		0x00000001
+#define UFS_MOUNT_ONERROR_LOCK		0x00000002
+#define UFS_MOUNT_ONERROR_UMOUNT	0x00000004
+#define UFS_MOUNT_ONERROR_REPAIR	0x00000008
+
+#define UFS_MOUNT_UFSTYPE		0x000000F0
+#define UFS_MOUNT_UFSTYPE_OLD		0x00000010
+#define UFS_MOUNT_UFSTYPE_44BSD		0x00000020
+#define UFS_MOUNT_UFSTYPE_SUN		0x00000040
+#define UFS_MOUNT_UFSTYPE_NEXT		0x00000080
+
+
+#define ufs_clear_opt(o,opt)	o &= ~UFS_MOUNT_##opt
+#define ufs_set_opt(o,opt)	o |= UFS_MOUNT_##opt
+#define ufs_test_opt(o,opt)	((o) & UFS_MOUNT_##opt)
+
 /*
  * MINFREE gives the minimum acceptable percentage of file system
  * blocks which may be free. If the freelist drops below this level
@@ -202,6 +218,19 @@
 	__s32	tv_usec;
 };
 
+/*
+ * File types
+ */
+#define DT_UNKNOWN	0
+#define DT_FIFO		1
+#define DT_CHR		2
+#define DT_DIR		4
+#define DT_BLK		6
+#define DT_REG		8
+#define DT_LNK		10
+#define DT_SOCK		12
+#define DT_WHT		14
+   
 struct ufs_dir_entry {
 	__u32  d_ino;			/* inode number of this entry */
 	__u16  d_reclen;		/* length of this entry */
@@ -377,7 +406,15 @@
 	__u32	cg_iusedoff;		/* (char) used inode map */
 	__u32	cg_freeoff;		/* (u_char) free block map */
 	__u32	cg_nextfreeoff;		/* (u_char) next available space */
-	__u32	cg_sparecon[16];	/* reserved for future use */
+	union {
+		struct {
+			__u32	cg_clustersumoff;	/* (u_int32) counts of avail clusters */
+			__u32	cg_clusteroff;		/* (u_int8) free cluster map */
+			__u32	cg_nclusterblks;	/* number of clusters this cg */
+			__u32	cg_sparecon[13];	/* reserved for future use */
+		} cg_44;
+		__u32	cg_sparecon[16];	/* reserved for future use */
+	} cg_u;
 	__u8	cg_space[1];		/* space for cylinder group maps */
 /* actually longer */
 };
@@ -393,7 +430,7 @@
 			__u16	ui_suid;	/*  0x4 */
 			__u16	ui_sgid;	/*  0x6 */
 		} oldids;
-		__u32	ui_inumber;	/*  0x4 lsf: inode number */
+		__u32	ui_inumber;		/*  0x4 lsf: inode number */
 		__u32	ui_author;		/*  0x4 GNU HURD: author */
 	} ui_u1;
 	__u64	ui_size;		/*  0x8 */
@@ -412,22 +449,22 @@
 	__u32	ui_gen;			/* 0x6c like ext2 i_version, for NFS support */
 	union {
 		struct {
-			__u32	ui_shadow;/* 0x70 shadow inode with security data */
-			__u32	ui_uid;	/* 0x74 long EFT version of uid */
-			__u32	ui_gid;	/* 0x78 long EFT version of gid */
-			__u32	ui_oeftflag;/* 0x7c reserved */
+			__u32	ui_shadow;	/* 0x70 shadow inode with security data */
+			__u32	ui_uid;		/* 0x74 long EFT version of uid */
+			__u32	ui_gid;		/* 0x78 long EFT version of gid */
+			__u32	ui_oeftflag;	/* 0x7c reserved */
 		} ui_sun;
 		struct {
-			__u32	ui_uid;	/* 0x70 File owner */
-			__u32	ui_gid;	/* 0x74 File group */
-			__s32	ui_spare[2];/* 0x78 reserved */
+			__u32	ui_uid;		/* 0x70 File owner */
+			__u32	ui_gid;		/* 0x74 File group */
+			__s32	ui_spare[2];	/* 0x78 reserved */
 		} ui_44;
 		struct {
-			__u32	ui_uid;	/* 0x70 */
-			__u32	ui_gid;	/* 0x74 */
-			__u16	ui_modeh;/* 0x78 mode high bits */
-			__u16	ui_spare;/* 0x7A unused */
-			__u32	ui_trans;/* 0x7c filesystem translator */
+			__u32	ui_uid;		/* 0x70 */
+			__u32	ui_gid;		/* 0x74 */
+			__u16	ui_modeh;	/* 0x78 mode high bits */
+			__u16	ui_spare;	/* 0x7A unused */
+			__u32	ui_trans;	/* 0x7c filesystem translator */
 		} ui_hurd;
 	} ui_u3;
 };
@@ -480,7 +517,6 @@
 extern void ufs_put_inode (struct inode *);
 extern void ufs_write_inode (struct inode *);
 extern int ufs_sync_inode (struct inode *);
-extern void ufs_print_inode (struct inode *);
 extern void ufs_write_inode (struct inode *);
 extern void ufs_delete_inode (struct inode *);
 extern struct buffer_head * ufs_getfrag (struct inode *, unsigned, int, int *);
@@ -503,10 +539,8 @@
 extern void ufs_warning (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
 extern void ufs_error (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
 extern void ufs_panic (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
-        
 extern int init_ufs_fs(void);
 extern void ufs_write_super (struct super_block *);
-extern void ufs_print_cylinder_stuff(struct ufs_cylinder_group *, __u32);
 
 /* symlink.c */
 extern struct inode_operations ufs_symlink_inode_operations;
diff -u --recursive --new-file v2.1.125/linux/include/linux/ufs_fs_i.h linux/include/linux/ufs_fs_i.h
--- v2.1.125/linux/include/linux/ufs_fs_i.h	Tue Jul 28 14:21:09 1998
+++ linux/include/linux/ufs_fs_i.h	Fri Oct 16 11:53:20 1998
@@ -8,8 +8,6 @@
  *
  * NeXTstep support added on February 5th 1998 by
  * Niels Kristian Bech Jensen <nkbj@image.dk>.
- *
- * write support by Daniel Pirkl <daniel.pirkl@email.cz>
  */
 
 #ifndef _LINUX_UFS_FS_I_H
diff -u --recursive --new-file v2.1.125/linux/include/linux/ufs_fs_sb.h linux/include/linux/ufs_fs_sb.h
--- v2.1.125/linux/include/linux/ufs_fs_sb.h	Fri Jul 31 17:05:52 1998
+++ linux/include/linux/ufs_fs_sb.h	Fri Oct 16 11:53:20 1998
@@ -8,8 +8,7 @@
  *
  * $Id: ufs_fs_sb.h,v 1.8 1998/05/06 12:04:40 jj Exp $
  *
- * Write support by Daniel Pirkl (daniel.pirkl@email.cz)
- * Charles University (Prague), Faculty of Mathematics and Physics
+ * Write support by Daniel Pirkl <daniel.pirkl@email.cz>
  */
 
 #ifndef __LINUX_UFS_FS_SB_H
@@ -41,8 +40,10 @@
 	__u32	c_iusedoff;	/* (char) used inode map */
 	__u32	c_freeoff;	/* (u_char) free block map */
 	__u32	c_nextfreeoff;	/* (u_char) next available space */
+	__u32	c_clustersumoff;/* (u_int32) counts of avail clusters */
+	__u32	c_clusteroff;	/* (u_int8) free cluster map */
+	__u32	c_nclusterblks;	/* number of clusters this cg */
 };	
-	
 
 struct ufs_sb_private_info {
 	struct ufs_buffer_head s_ubh; /* buffer containing super block */
@@ -83,6 +84,7 @@
 	__u32	s_ipg;		/* inodes per group */
 	__u32	s_fpg;		/* fragments per group */
 	__u32	s_cpc;		/* cyl per cycle in postbl */
+	__s32	s_contigsumsize;/* size of cluster summary array, 44bsd */
 	__s64	s_qbmask;	/* ~usb_bmask */
 	__s64	s_qfmask;	/* ~usb_fmask */
 	__s32	s_postblformat;	/* format of positional layout tables */
@@ -102,11 +104,14 @@
 	__u32	s_nspb;		/* number of sector per block */
 	__u32	s_inopf;	/* inodes per fragment */
 	__u32	s_sbbase;	/* offset of NeXTstep superblock */
+	__u32	s_bpf;		/* bits per fragment */
+	__u32	s_bpfshift;	/* bits per fragment shift*/
+	__u32	s_bpfmask;	/* bits per fragment mask */
 };
 
 
-#define UFS_MAX_GROUP_LOADED 1
-#define UFS_CGNO_EMPTY uspi->s_ncg
+#define UFS_MAX_GROUP_LOADED 8
+#define UFS_CGNO_EMPTY ((unsigned)-1)
 
 struct ufs_sb_info {
 	struct ufs_sb_private_info * s_uspi;	
@@ -119,6 +124,7 @@
 	struct ufs_cg_private_info * s_ucpi[UFS_MAX_GROUP_LOADED]; 
 	unsigned s_cgno[UFS_MAX_GROUP_LOADED];
 	unsigned short s_cg_loaded;
+	unsigned s_mount_opt;
 };
 
 /*
diff -u --recursive --new-file v2.1.125/linux/include/linux/videodev.h linux/include/linux/videodev.h
--- v2.1.125/linux/include/linux/videodev.h	Thu Sep 17 17:53:38 1998
+++ linux/include/linux/videodev.h	Sat Oct 17 15:52:18 1998
@@ -159,6 +159,9 @@
 	struct	video_clip *clips;	/* Set only */
 	int	clipcount;
 #define VIDEO_WINDOW_INTERLACE	1
+#define VIDEO_CLIP_BITMAP	-1
+/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
+#define VIDEO_CLIPMAP_SIZE	(128 * 625)
 };
 
 struct video_capture
@@ -257,6 +260,7 @@
 #define VID_HARDWARE_RTRACK2	13
 #define VID_HARDWARE_PERMEDIA2	14	/* Reserved for Permedia2 */
 #define VID_HARDWARE_RIVA128	15	/* Reserved for RIVA 128 */
+#define VID_HARDWARE_PLANB	16	/* PowerMac motherboard video-in */
 
 /*
  *	Initialiser list
diff -u --recursive --new-file v2.1.125/linux/include/linux/wanrouter.h linux/include/linux/wanrouter.h
--- v2.1.125/linux/include/linux/wanrouter.h	Fri Jul 31 17:14:06 1998
+++ linux/include/linux/wanrouter.h	Fri Oct 23 10:17:56 1998
@@ -319,7 +319,7 @@
 	void* private;			/* -> driver private data */
 					/****** hardware configuration ******/
 	unsigned ioport;		/* adapter I/O port base #1 */
-	unsigned long maddr;		/* dual-port memory address */
+	void * maddr;			/* dual-port memory address */
 	unsigned msize;			/* dual-port memory size */
 	int irq;			/* interrupt request level */
 	int dma;			/* DMA request level */
diff -u --recursive --new-file v2.1.125/linux/include/video/fbcon.h linux/include/video/fbcon.h
--- v2.1.125/linux/include/video/fbcon.h	Mon Oct  5 13:13:47 1998
+++ linux/include/video/fbcon.h	Thu Oct 15 15:24:18 1998
@@ -465,7 +465,30 @@
     fast_memmove(dst, src, size);
     return dst;
 }
+
+#else
+
+#ifdef CONFIG_SUN4
+/* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */
+static __inline__ void fast_memmove(void *d, const void *s, size_t count)
+{
+    int i;
+    if (d<s) {
+	for (i=0; i<count; i++)
+	    ((char *) d)[i] = ((char *) s)[i];
+    } else
+	for (i=0; i<count; i++)
+	    ((char *) d)[count-i-1] = ((char *) s)[count-i-1];
+}
+
+static __inline__ void *mymemmove(char *dst, const char *src, size_t size)
+{
+    fast_memmove(dst, src, size);
+    return dst;
+}
+
 #else
+
 static __inline__ void *mymemmove(void *d, const void *s, size_t count)
 {
     return(memmove(d, s, count));
@@ -475,7 +498,10 @@
 {
     memmove(dst, src, size);
 }
-#endif	/* !i386 */
+
+#endif /* !sun4 */
+
+#endif /* !i386 */
 
 #endif /* !m68k */
 
diff -u --recursive --new-file v2.1.125/linux/init/main.c linux/init/main.c
--- v2.1.125/linux/init/main.c	Fri Oct  9 13:27:16 1998
+++ linux/init/main.c	Tue Oct 20 22:21:26 1998
@@ -302,9 +302,8 @@
 #ifdef CONFIG_SOUNDMODEM
 extern void sm_setup(char *str, int *ints);
 #endif
-#ifdef CONFIG_PMAC_CONSOLE
-extern void pmac_cons_setup(char *str, int *ints);
-extern void pmac_vmode_setup(char *str, int *ints);
+#ifdef CONFIG_ADBMOUSE
+extern void adb_mouse_setup(char *str, int *ints);
 #endif
 #ifdef CONFIG_WDT
 extern void wdt_setup(char *str, int *ints);
@@ -1195,6 +1194,8 @@
 }
 #endif
 
+struct task_struct *child_reaper = &init_task;
+
 /*
  * Ok, the machine is now initialized. None of the devices
  * have been touched yet, but the CPU subsystem is up and
@@ -1207,6 +1208,16 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	int real_root_mountflags;
 #endif
+
+	/*
+	 * Tell the world that we're going to be the grim
+	 * reaper of innocent orphaned children.
+	 *
+	 * We don't want people to have to make incorrect
+	 * assumptions about where in the task array this
+	 * can be found.
+	 */
+	child_reaper = current;
 
 #if defined(CONFIG_MTRR)	/* Do this after SMP initialization */
 /*
diff -u --recursive --new-file v2.1.125/linux/ipc/shm.c linux/ipc/shm.c
--- v2.1.125/linux/ipc/shm.c	Fri Oct  9 13:27:16 1998
+++ linux/ipc/shm.c	Sat Oct 17 15:52:18 1998
@@ -38,7 +38,7 @@
 static int shm_swp = 0; /* number of shared memory pages that are in swap */
 static int max_shmid = 0; /* every used id is <= max_shmid */
 static struct wait_queue *shm_lock = NULL; /* calling findkey() may need to wait */
-static struct shmid_ds *shm_segs[SHMMNI];
+static struct shmid_kernel *shm_segs[SHMMNI];
 
 static unsigned short shm_seq = 0; /* incremented, for recognizing stale ids */
 
@@ -52,7 +52,7 @@
 	int id;
 
 	for (id = 0; id < SHMMNI; id++)
-		shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
+		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
 	shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
 	shm_lock = NULL;
 	return;
@@ -61,25 +61,25 @@
 static int findkey (key_t key)
 {
 	int id;
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 
 	for (id = 0; id <= max_shmid; id++) {
 		while ((shp = shm_segs[id]) == IPC_NOID)
 			sleep_on (&shm_lock);
 		if (shp == IPC_UNUSED)
 			continue;
-		if (key == shp->shm_perm.key)
+		if (key == shp->u.shm_perm.key)
 			return id;
 	}
 	return -1;
 }
 
 /*
- * allocate new shmid_ds and pgtable. protected by shm_segs[id] = NOID.
+ * allocate new shmid_kernel and pgtable. protected by shm_segs[id] = NOID.
  */
 static int newseg (key_t key, int shmflg, int size)
 {
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
 	int id, i;
 
@@ -89,22 +89,22 @@
 		return -ENOSPC;
 	for (id = 0; id < SHMMNI; id++)
 		if (shm_segs[id] == IPC_UNUSED) {
-			shm_segs[id] = (struct shmid_ds *) IPC_NOID;
+			shm_segs[id] = (struct shmid_kernel *) IPC_NOID;
 			goto found;
 		}
 	return -ENOSPC;
 
 found:
-	shp = (struct shmid_ds *) kmalloc (sizeof (*shp), GFP_KERNEL);
+	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_KERNEL);
 	if (!shp) {
-		shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
+		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
 		wake_up (&shm_lock);
 		return -ENOMEM;
 	}
 
 	shp->shm_pages = (ulong *) vmalloc (numpages*sizeof(ulong));
 	if (!shp->shm_pages) {
-		shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
+		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
 		wake_up (&shm_lock);
 		kfree(shp);
 		return -ENOMEM;
@@ -112,17 +112,17 @@
 
 	for (i = 0; i < numpages; shp->shm_pages[i++] = 0);
 	shm_tot += numpages;
-	shp->shm_perm.key = key;
-	shp->shm_perm.mode = (shmflg & S_IRWXUGO);
-	shp->shm_perm.cuid = shp->shm_perm.uid = current->euid;
-	shp->shm_perm.cgid = shp->shm_perm.gid = current->egid;
-	shp->shm_perm.seq = shm_seq;
-	shp->shm_segsz = size;
-	shp->shm_cpid = current->pid;
+	shp->u.shm_perm.key = key;
+	shp->u.shm_perm.mode = (shmflg & S_IRWXUGO);
+	shp->u.shm_perm.cuid = shp->u.shm_perm.uid = current->euid;
+	shp->u.shm_perm.cgid = shp->u.shm_perm.gid = current->egid;
+	shp->u.shm_perm.seq = shm_seq;
+	shp->u.shm_segsz = size;
+	shp->u.shm_cpid = current->pid;
 	shp->attaches = NULL;
-	shp->shm_lpid = shp->shm_nattch = 0;
-	shp->shm_atime = shp->shm_dtime = 0;
-	shp->shm_ctime = CURRENT_TIME;
+	shp->u.shm_lpid = shp->u.shm_nattch = 0;
+	shp->u.shm_atime = shp->u.shm_dtime = 0;
+	shp->u.shm_ctime = CURRENT_TIME;
 	shp->shm_npages = numpages;
 
 	if (id > max_shmid)
@@ -130,12 +130,12 @@
 	shm_segs[id] = shp;
 	used_segs++;
 	wake_up (&shm_lock);
-	return (unsigned int) shp->shm_perm.seq * SHMMNI + id;
+	return (unsigned int) shp->u.shm_perm.seq * SHMMNI + id;
 }
 
 asmlinkage int sys_shmget (key_t key, int size, int shmflg)
 {
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	int err, id = 0;
 
 	down(&current->mm->mmap_sem);
@@ -153,14 +153,14 @@
 		err = -EEXIST;
 	} else {
 		shp = shm_segs[id];
-		if (shp->shm_perm.mode & SHM_DEST)
+		if (shp->u.shm_perm.mode & SHM_DEST)
 			err = -EIDRM;
-		else if (size > shp->shm_segsz)
+		else if (size > shp->u.shm_segsz)
 			err = -EINVAL;
-		else if (ipcperms (&shp->shm_perm, shmflg))
+		else if (ipcperms (&shp->u.shm_perm, shmflg))
 			err = -EACCES;
 		else
-			err = (int) shp->shm_perm.seq * SHMMNI + id;
+			err = (int) shp->u.shm_perm.seq * SHMMNI + id;
 	}
 	unlock_kernel();
 	up(&current->mm->mmap_sem);
@@ -169,11 +169,11 @@
 
 /*
  * Only called after testing nattch and SHM_DEST.
- * Here pages, pgtable and shmid_ds are freed.
+ * Here pages, pgtable and shmid_kernel are freed.
  */
 static void killseg (int id)
 {
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	int i, numpages;
 
 	shp = shm_segs[id];
@@ -181,9 +181,9 @@
 		printk ("shm nono: killseg called on unused seg id=%d\n", id);
 		return;
 	}
-	shp->shm_perm.seq++;     /* for shmat */
+	shp->u.shm_perm.seq++;     /* for shmat */
 	shm_seq = (shm_seq+1) % ((unsigned)(1<<31)/SHMMNI); /* increment, but avoid overflow */
-	shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
+	shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
 	used_segs--;
 	if (id == max_shmid)
 		while (max_shmid && (shm_segs[--max_shmid] == IPC_UNUSED));
@@ -214,7 +214,7 @@
 asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
 {
 	struct shmid_ds tbuf;
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	struct ipc_perm *ipcp;
 	int id, err = -EINVAL;
 
@@ -223,12 +223,8 @@
 		goto out;
 	if (cmd == IPC_SET) {
 		err = -EFAULT;
-		if (!buf)
-			goto out;
-		err = verify_area (VERIFY_READ, buf, sizeof (*buf));
-		if (err)
+		if(copy_from_user (&tbuf, buf, sizeof (*buf)))
 			goto out;
-		copy_from_user (&tbuf, buf, sizeof (*buf));
 	}
 
 	switch (cmd) { /* replace with proc interface ? */
@@ -243,10 +239,8 @@
 		shminfo.shmmin = SHMMIN;
 		shminfo.shmall = SHMALL;
 		shminfo.shmseg = SHMSEG;
-		err = verify_area (VERIFY_WRITE, buf, sizeof (struct shminfo));
-		if (err)
+		if(copy_to_user (buf, &shminfo, sizeof(struct shminfo)))
 			goto out;
-		copy_to_user (buf, &shminfo, sizeof(struct shminfo));
 		err = max_shmid;
 		goto out;
 	}
@@ -254,46 +248,30 @@
 	{
 		struct shm_info shm_info;
 		err = -EFAULT;
-		if (!buf)
-			goto out;
-		err = verify_area (VERIFY_WRITE, buf, sizeof (shm_info));
-		if (err)
-			goto out;
 		shm_info.used_ids = used_segs;
 		shm_info.shm_rss = shm_rss;
 		shm_info.shm_tot = shm_tot;
 		shm_info.shm_swp = shm_swp;
 		shm_info.swap_attempts = swap_attempts;
 		shm_info.swap_successes = swap_successes;
-		copy_to_user (buf, &shm_info, sizeof(shm_info));
+		if(copy_to_user (buf, &shm_info, sizeof(shm_info)))
+			goto out;
 		err = max_shmid;
 		goto out;
 	}
 	case SHM_STAT:
-		err = -EFAULT;
-		if (!buf)
-			goto out;
-		err = verify_area (VERIFY_WRITE, buf, sizeof (*buf));
-		if (err)
-			goto out;
 		err = -EINVAL;
 		if (shmid > max_shmid)
 			goto out;
 		shp = shm_segs[shmid];
 		if (shp == IPC_UNUSED || shp == IPC_NOID)
 			goto out;
-		if (ipcperms (&shp->shm_perm, S_IRUGO))
+		if (ipcperms (&shp->u.shm_perm, S_IRUGO))
+			goto out;
+		id = (unsigned int) shp->u.shm_perm.seq * SHMMNI + shmid;
+		err = -EFAULT;
+		if(copy_to_user (buf, &shp->u, sizeof(*buf)))
 			goto out;
-		id = (unsigned int) shp->shm_perm.seq * SHMMNI + shmid;
-		tbuf.shm_perm   = shp->shm_perm;
-		tbuf.shm_segsz  = shp->shm_segsz;
-		tbuf.shm_atime  = shp->shm_atime;
-		tbuf.shm_dtime  = shp->shm_dtime;
-		tbuf.shm_ctime  = shp->shm_ctime;
-		tbuf.shm_cpid   = shp->shm_cpid;
-		tbuf.shm_lpid   = shp->shm_lpid;
-		tbuf.shm_nattch = shp->shm_nattch;
-		copy_to_user (buf, &tbuf, sizeof(*buf));
 		err = id;
 		goto out;
 	}
@@ -303,9 +281,9 @@
 	if (shp == IPC_UNUSED || shp == IPC_NOID)
 		goto out;
 	err = -EIDRM;
-	if (shp->shm_perm.seq != (unsigned int) shmid / SHMMNI)
+	if (shp->u.shm_perm.seq != (unsigned int) shmid / SHMMNI)
 		goto out;
-	ipcp = &shp->shm_perm;
+	ipcp = &shp->u.shm_perm;
 
 	switch (cmd) {
 	case SHM_UNLOCK:
@@ -334,40 +312,28 @@
 		if (ipcperms (ipcp, S_IRUGO))
 			goto out;
 		err = -EFAULT;
-		if (!buf)
-			goto out;
-		err = verify_area (VERIFY_WRITE, buf, sizeof (*buf));
-		if (err)
+		if(copy_to_user (buf, &shp->u, sizeof(shp->u)))
 			goto out;
-		tbuf.shm_perm   = shp->shm_perm;
-		tbuf.shm_segsz  = shp->shm_segsz;
-		tbuf.shm_atime  = shp->shm_atime;
-		tbuf.shm_dtime  = shp->shm_dtime;
-		tbuf.shm_ctime  = shp->shm_ctime;
-		tbuf.shm_cpid   = shp->shm_cpid;
-		tbuf.shm_lpid   = shp->shm_lpid;
-		tbuf.shm_nattch = shp->shm_nattch;
-		copy_to_user (buf, &tbuf, sizeof(*buf));
 		break;
 	case IPC_SET:
-		if (current->euid == shp->shm_perm.uid ||
-		    current->euid == shp->shm_perm.cuid || 
+		if (current->euid == shp->u.shm_perm.uid ||
+		    current->euid == shp->u.shm_perm.cuid || 
 		    capable(CAP_SYS_ADMIN)) {
 			ipcp->uid = tbuf.shm_perm.uid;
 			ipcp->gid = tbuf.shm_perm.gid;
 			ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
 				| (tbuf.shm_perm.mode & S_IRWXUGO);
-			shp->shm_ctime = CURRENT_TIME;
+			shp->u.shm_ctime = CURRENT_TIME;
 			break;
 		}
 		err = -EPERM;
 		goto out;
 	case IPC_RMID:
-		if (current->euid == shp->shm_perm.uid ||
-		    current->euid == shp->shm_perm.cuid || 
+		if (current->euid == shp->u.shm_perm.uid ||
+		    current->euid == shp->u.shm_perm.cuid || 
 		    capable(CAP_SYS_ADMIN)) {
-			shp->shm_perm.mode |= SHM_DEST;
-			if (shp->shm_nattch <= 0)
+			shp->u.shm_perm.mode |= SHM_DEST;
+			if (shp->u.shm_nattch <= 0)
 				killseg (id);
 			break;
 		}
@@ -410,7 +376,7 @@
 };
 
 /* Insert shmd into the list shp->attaches */
-static inline void insert_attach (struct shmid_ds * shp, struct vm_area_struct * shmd)
+static inline void insert_attach (struct shmid_kernel * shp, struct vm_area_struct * shmd)
 {
 	if((shmd->vm_next_share = shp->attaches) != NULL)
 		shp->attaches->vm_pprev_share = &shmd->vm_next_share;
@@ -419,7 +385,7 @@
 }
 
 /* Remove shmd from list shp->attaches */
-static inline void remove_attach (struct shmid_ds * shp, struct vm_area_struct * shmd)
+static inline void remove_attach (struct shmid_kernel * shp, struct vm_area_struct * shmd)
 {
 	if(shmd->vm_next_share)
 		shmd->vm_next_share->vm_pprev_share = shmd->vm_pprev_share;
@@ -481,7 +447,7 @@
  */
 asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
 {
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	struct vm_area_struct *shmd;
 	int err = -EINVAL;
 	unsigned int id;
@@ -507,7 +473,7 @@
 		err = -ENOMEM;
 		addr = 0;
 	again:
-		if (!(addr = get_unmapped_area(addr, shp->shm_segsz)))
+		if (!(addr = get_unmapped_area(addr, shp->u.shm_segsz)))
 			goto out;
 		if(addr & (SHMLBA - 1)) {
 			addr = (addr + (SHMLBA - 1)) & ~(SHMLBA - 1);
@@ -537,24 +503,24 @@
 		goto out;
 	}
 	if (!(shmflg & SHM_REMAP))
-		if ((shmd = find_vma_intersection(current->mm, addr, addr + shp->shm_segsz))) {
+		if ((shmd = find_vma_intersection(current->mm, addr, addr + shp->u.shm_segsz))) {
 			/* printk("shmat() -> EINVAL because the interval [0x%lx,0x%lx) intersects an already mapped interval [0x%lx,0x%lx).\n",
 				addr, addr + shp->shm_segsz, shmd->vm_start, shmd->vm_end); */
 			goto out;
 		}
 
 	err = -EACCES;
-	if (ipcperms(&shp->shm_perm, shmflg & SHM_RDONLY ? S_IRUGO : S_IRUGO|S_IWUGO))
+	if (ipcperms(&shp->u.shm_perm, shmflg & SHM_RDONLY ? S_IRUGO : S_IRUGO|S_IWUGO))
 		goto out;
 	err = -EIDRM;
-	if (shp->shm_perm.seq != (unsigned int) shmid / SHMMNI)
+	if (shp->u.shm_perm.seq != (unsigned int) shmid / SHMMNI)
 		goto out;
 
 	err = -ENOMEM;
 	shmd = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (!shmd)
 		goto out;
-	if ((shp != shm_segs[id]) || (shp->shm_perm.seq != (unsigned int) shmid / SHMMNI)) {
+	if ((shp != shm_segs[id]) || (shp->u.shm_perm.seq != (unsigned int) shmid / SHMMNI)) {
 		kmem_cache_free(vm_area_cachep, shmd);
 		err = -EIDRM;
 		goto out;
@@ -572,9 +538,9 @@
 	shmd->vm_offset = 0;
 	shmd->vm_ops = &shm_vm_ops;
 
-	shp->shm_nattch++;            /* prevent destruction */
+	shp->u.shm_nattch++;            /* prevent destruction */
 	if ((err = shm_map (shmd))) {
-		if (--shp->shm_nattch <= 0 && shp->shm_perm.mode & SHM_DEST)
+		if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
 			killseg(id);
 		kmem_cache_free(vm_area_cachep, shmd);
 		goto out;
@@ -582,8 +548,8 @@
 
 	insert_attach(shp,shmd);  /* insert shmd into shp->attaches */
 
-	shp->shm_lpid = current->pid;
-	shp->shm_atime = CURRENT_TIME;
+	shp->u.shm_lpid = current->pid;
+	shp->u.shm_atime = CURRENT_TIME;
 
 	*raddr = addr;
 	err = 0;
@@ -597,7 +563,7 @@
 static void shm_open (struct vm_area_struct *shmd)
 {
 	unsigned int id;
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 
 	id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
 	shp = shm_segs[id];
@@ -606,9 +572,9 @@
 		return;
 	}
 	insert_attach(shp,shmd);  /* insert shmd into shp->attaches */
-	shp->shm_nattch++;
-	shp->shm_atime = CURRENT_TIME;
-	shp->shm_lpid = current->pid;
+	shp->u.shm_nattch++;
+	shp->u.shm_atime = CURRENT_TIME;
+	shp->u.shm_lpid = current->pid;
 }
 
 /*
@@ -619,16 +585,16 @@
  */
 static void shm_close (struct vm_area_struct *shmd)
 {
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	int id;
 
 	/* remove from the list of attaches of the shm segment */
 	id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
 	shp = shm_segs[id];
 	remove_attach(shp,shmd);  /* remove from shp->attaches */
-  	shp->shm_lpid = current->pid;
-	shp->shm_dtime = CURRENT_TIME;
-	if (--shp->shm_nattch <= 0 && shp->shm_perm.mode & SHM_DEST)
+  	shp->u.shm_lpid = current->pid;
+	shp->u.shm_dtime = CURRENT_TIME;
+	if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
 		killseg (id);
 }
 
@@ -659,7 +625,7 @@
 static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, unsigned long code)
 {
 	pte_t pte;
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	unsigned int id, idx;
 
 	id = SWP_OFFSET(code) & SHM_ID_MASK;
@@ -731,7 +697,7 @@
 int shm_swap (int prio, int gfp_mask)
 {
 	pte_t page;
-	struct shmid_ds *shp;
+	struct shmid_kernel *shp;
 	struct vm_area_struct *shmd;
 	unsigned long swap_nr;
 	unsigned long id, idx;
@@ -744,7 +710,7 @@
 
  check_id:
 	shp = shm_segs[swap_id];
-	if (shp == IPC_UNUSED || shp == IPC_NOID || shp->shm_perm.mode & SHM_LOCKED ) {
+	if (shp == IPC_UNUSED || shp == IPC_NOID || shp->u.shm_perm.mode & SHM_LOCKED ) {
 		next_id:
 		swap_idx = 0;
 		if (++swap_id > max_shmid) {
@@ -843,7 +809,7 @@
 /*
  * Free the swap entry and set the new pte for the shm page.
  */
-static void shm_unuse_page(struct shmid_ds *shp, unsigned long idx,
+static void shm_unuse_page(struct shmid_kernel *shp, unsigned long idx,
 			   unsigned long page, unsigned long entry)
 {
 	pte_t pte;
diff -u --recursive --new-file v2.1.125/linux/kernel/acct.c linux/kernel/acct.c
--- v2.1.125/linux/kernel/acct.c	Mon Oct  5 13:13:47 1998
+++ linux/kernel/acct.c	Wed Oct 21 15:59:56 1998
@@ -20,6 +20,9 @@
  *  the file happened to be read-only. 2) If the accounting was suspended
  *  due to the lack of space it happily allowed to reopen it and completely
  *  lost the old acct_file. 3/10/98, Al Viro.
+ *
+ *  Now we silently close acct_file on attempt to reopen. Cleaned sys_acct().
+ *  XTerms and EMACS are manifestations of pure evil. 21/10/98, AV.
  */
 
 #include <linux/config.h>
@@ -79,17 +82,18 @@
 {
 	mm_segment_t fs;
 	struct statfs sbuf;
+	struct super_block *sb;
 
 	if (!acct_file || !acct_needcheck)
 		return;
 
-	if (!acct_file->f_dentry->d_inode->i_sb->s_op ||
-            !acct_file->f_dentry->d_inode->i_sb->s_op->statfs)
+	sb = acct_file->f_dentry->f_inode->i_sb;
+	if (!sb->s_op || !sb->s_op->statfs)
 		return;
 
 	fs = get_fs();
 	set_fs(KERNEL_DS);
-	acct_file->f_dentry->d_inode->i_sb->s_op->statfs(acct_file->f_dentry->d_inode->i_sb, &sbuf, sizeof(struct statfs));
+	sb->s_op->statfs(sb, &sbuf, sizeof(struct statfs));
 	set_fs(fs);
 
 	if (acct_active) {
@@ -119,6 +123,7 @@
 {
 	struct dentry *dentry;
 	struct inode *inode;
+	struct file_operations *ops;
 	char *tmp;
 	int error = -EPERM;
 
@@ -126,86 +131,74 @@
 	if (!capable(CAP_SYS_PACCT))
 		goto out;
 
-	if (name == (char *)NULL) {
-		if (acct_file) {
-			/* fput() may block, so just in case... */
-			struct file *tmp = acct_file;
-			if (acct_active)
-				acct_process(0); 
-		        del_timer(&acct_timer);
-			acct_active = 0;
-			acct_needcheck = 0;
-			acct_file = NULL;
-			fput(tmp);
-		}
-		error = 0;
+	if (acct_file) {
+		/* fput() may block, so just in case... */
+		struct file *tmp = acct_file;
+		if (acct_active)
+			acct_process(0); 
+		del_timer(&acct_timer);
+		acct_active = 0;
+		acct_needcheck = 0;
+		acct_file = NULL;
+		fput(tmp);
+	}
+	error = 0;
+	if (!name)		/* We are done */
 		goto out;
-	} else {
-		/*
-		 * We can't rely on acct_active - it might be disabled
-		 * due to the lack of space.
-		 */
-		if (!acct_file) {
-			tmp = getname(name);
-			error = PTR_ERR(tmp);
-			if (IS_ERR(tmp))
-				goto out;
-
-			dentry = open_namei(tmp, O_RDWR, 0600);
-			putname(tmp);
-
-			error = PTR_ERR(dentry);
-			if (IS_ERR(dentry))
-				goto out;
-
-			inode = dentry->d_inode;
-
-			if (!S_ISREG(inode->i_mode)) {
-				dput(dentry);
-				error = -EACCES;
-				goto out;
-			}
-
-			if (!inode->i_op || !inode->i_op->default_file_ops || 
-			    !inode->i_op->default_file_ops->write) {
-				dput(dentry);
-				error = -EIO;
-				goto out;
-			}
-
-			if ((acct_file = get_empty_filp()) != (struct file *)NULL) {
-				acct_file->f_mode = (O_WRONLY + 1) & O_ACCMODE;
-				acct_file->f_flags = O_WRONLY;
-				acct_file->f_dentry = dentry;
-				acct_file->f_pos = inode->i_size;
-				acct_file->f_reada = 0;
-				acct_file->f_op = inode->i_op->default_file_ops;
-				if ((error = get_write_access(acct_file->f_dentry->d_inode)) == 0) {
-					if (acct_file->f_op && acct_file->f_op->open)
-						error = acct_file->f_op->open(inode, acct_file);
-					if (error == 0) {
-						acct_needcheck = 0;
-						acct_active = 1;
-						acct_timer.expires = jiffies + ACCT_TIMEOUT;
-						add_timer(&acct_timer);
-						error = 0;
-						goto out;
-					}
-					put_write_access(acct_file->f_dentry->d_inode);
-				}
-				/* decrementing f_count is _not_ enough */
-				put_filp(acct_file);
-				acct_file = NULL;
-			} else
-				error = -EUSERS;
-			dput(dentry);
-		} else
-			/*
-			 * NB: in this case FreeBSD just closes acct_file
-			 * and opens new one. Maybe it's better behavior...
-			 */
-			error = -EBUSY;
+
+	tmp = getname(name);
+	error = PTR_ERR(tmp);
+	if (IS_ERR(tmp))
+		goto out;
+
+	dentry = open_namei(tmp, O_RDWR, 0600);
+	putname(tmp);
+
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
+		goto out;
+
+	inode = dentry->d_inode;
+
+	error = -EACCES;
+	if (!S_ISREG(inode->i_mode)) 
+		goto out_d;
+
+	error = -EIO;
+	if (!inode->i_op || !(ops = inode->i_op->default_file_ops) || 
+	    !ops->write) 
+		goto out_d;
+
+	error = -EUSERS;
+	if (!(acct_file = get_empty_filp()))
+		goto out_d;
+
+	acct_file->f_mode = (O_WRONLY + 1) & O_ACCMODE;
+	acct_file->f_flags = O_WRONLY;
+	acct_file->f_dentry = dentry;
+	acct_file->f_pos = inode->i_size;
+	acct_file->f_reada = 0;
+	acct_file->f_op = ops;
+	error = get_write_access(inode);
+	if (error)
+		goto out_f;
+	if (ops->open)
+		error = ops->open(inode, acct_file);
+	if (error) {
+		put_write_access(inode);
+		goto out_f;
 	}
+	acct_needcheck = 0;
+	acct_active = 1;
+	acct_timer.expires = jiffies + ACCT_TIMEOUT;
+	add_timer(&acct_timer);
+	goto out;
+out_f:
+	/* decrementing f_count is _not_ enough */
+	put_filp(acct_file);
+	acct_file = NULL;
+out_d:
+	dput(dentry);
 out:
 	unlock_kernel();
 	return error;
@@ -274,9 +267,9 @@
 	unsigned long vsize;
 
 	/*
-	 * First check to see if there is enough free_space to continue the process
-	 * accounting system. Check_free_space toggles the acct_active flag so we
-	 * need to check that after check_free_space.
+	 * First check to see if there is enough free_space to continue
+	 * the process accounting system. Check_free_space toggles the
+	 * acct_active flag so we need to check that after check_free_space.
 	 */
 	check_free_space();
 
@@ -329,7 +322,8 @@
 	ac.ac_exitcode = exitcode;
 
 	/*
-         * Kernel segment override to datasegment and write it to the accounting file.
+         * Kernel segment override to datasegment and write it
+         * to the accounting file.
          */
 	fs = get_fs();
 	set_fs(KERNEL_DS);
diff -u --recursive --new-file v2.1.125/linux/kernel/capability.c linux/kernel/capability.c
--- v2.1.125/linux/kernel/capability.c	Wed Aug 26 11:37:45 1998
+++ linux/kernel/capability.c	Wed Oct 21 10:02:49 1998
@@ -61,9 +61,9 @@
      }
 
      if (!error) { 
-	     data.permitted = target->cap_permitted.cap;
-	     data.inheritable = target->cap_inheritable.cap; 
-	     data.effective = target->cap_effective.cap;
+	     data.permitted = cap_t(target->cap_permitted);
+	     data.inheritable = cap_t(target->cap_inheritable); 
+	     data.effective = cap_t(target->cap_effective);
      }
 
      if (target != current)
diff -u --recursive --new-file v2.1.125/linux/kernel/dma.c linux/kernel/dma.c
--- v2.1.125/linux/kernel/dma.c	Fri Oct  9 13:27:16 1998
+++ linux/kernel/dma.c	Mon Oct 12 11:50:15 1998
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <asm/dma.h>
 #include <asm/system.h>
+#include <asm/spinlock.h>
 
 
 /* A note on resource allocation:
diff -u --recursive --new-file v2.1.125/linux/kernel/exit.c linux/kernel/exit.c
--- v2.1.125/linux/kernel/exit.c	Mon Sep 28 10:51:36 1998
+++ linux/kernel/exit.c	Tue Oct 20 22:18:13 1998
@@ -29,6 +29,7 @@
 #include <asm/mmu_context.h>
 
 extern void sem_exit (void);
+extern struct task_struct *child_reaper;
 
 int getrusage(struct task_struct *, int, struct rusage *);
 
@@ -156,7 +157,7 @@
 	for_each_task(p) {
 		if (p->p_opptr == father) {
 			p->exit_signal = SIGCHLD;
-			p->p_opptr = task[smp_num_cpus] ? : task[0]; /* init */
+			p->p_opptr = child_reaper; /* init */
 			if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
 		}
 	}
diff -u --recursive --new-file v2.1.125/linux/kernel/kmod.c linux/kernel/kmod.c
--- v2.1.125/linux/kernel/kmod.c	Wed Aug 26 11:37:45 1998
+++ linux/kernel/kmod.c	Tue Oct 20 22:16:06 1998
@@ -24,24 +24,23 @@
 */
 char modprobe_path[256] = "/sbin/modprobe";
 
-/*
-	exec_modprobe is spawned from a kernel-mode user process,
-	then changes its state to behave _as_if_ it was spawned
-	from the kernel's init process
-	(ppid and {e,}gid are not adjusted, but that shouldn't
-	be a problem since we trust modprobe)
-*/
-#define task_init task[smp_num_cpus]
-
 static inline void
 use_init_file_context(void)
 {
+	struct fs_struct * fs;
+
 	lock_kernel();
 
-	/* don't use the user's root, use init's root instead */
+	/*
+	 * Don't use the user's root, use init's root instead.
+	 * Note that we can use "init_task" (which is not actually
+	 * the same as the user-level "init" process) because we
+	 * started "init" with a CLONE_FS
+	 */
 	exit_fs(current);	/* current->fs->count--; */
-	current->fs = task_init->fs;
-	atomic_inc(&current->fs->count);
+	fs = init_task.fs;
+	current->fs = fs;
+	atomic_inc(&fs->count);
 
 	unlock_kernel();
 }
diff -u --recursive --new-file v2.1.125/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.1.125/linux/kernel/ksyms.c	Thu Sep 17 17:53:39 1998
+++ linux/kernel/ksyms.c	Fri Oct 23 10:18:45 1998
@@ -53,7 +53,7 @@
 #include <linux/console.h>
 #include <linux/time.h>
 
-extern unsigned char aux_device_present, pckbd_read_mask;
+#include <asm/spinlock.h>
 
 #if defined(CONFIG_PROC_FS)
 #include <linux/proc_fs.h>
@@ -79,6 +79,7 @@
 extern int sys_tz;
 extern int request_dma(unsigned int dmanr, char * deviceID);
 extern void free_dma(unsigned int dmanr);
+extern spinlock_t dma_spin_lock;
 
 #ifdef MODVERSIONS
 const struct module_symbol __export_Using_Versions
@@ -192,6 +193,7 @@
 EXPORT_SYMBOL(shrink_dcache_parent);
 EXPORT_SYMBOL(find_inode_number);
 EXPORT_SYMBOL(is_subdir);
+EXPORT_SYMBOL(get_unused_fd);
 
 #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
 EXPORT_SYMBOL(do_nfsservctl);
@@ -300,6 +302,7 @@
 /* dma handling */
 EXPORT_SYMBOL(request_dma);
 EXPORT_SYMBOL(free_dma);
+EXPORT_SYMBOL(dma_spin_lock);
 #ifdef HAVE_DISABLE_HLT
 EXPORT_SYMBOL(disable_hlt);
 EXPORT_SYMBOL(enable_hlt);
@@ -379,14 +382,6 @@
 /* all busmice */
 EXPORT_SYMBOL(add_mouse_randomness);
 EXPORT_SYMBOL(fasync_helper);
-
-#ifdef CONFIG_PSMOUSE_MODULE
-/* psaux mouse */
-EXPORT_SYMBOL(aux_device_present);
-#ifdef CONFIG_VT
-EXPORT_SYMBOL(pckbd_read_mask);
-#endif
-#endif
 
 #ifdef CONFIG_BLK_DEV_MD
 EXPORT_SYMBOL(disk_name);	/* for md.c */
diff -u --recursive --new-file v2.1.125/linux/kernel/sys.c linux/kernel/sys.c
--- v2.1.125/linux/kernel/sys.c	Tue Aug 18 22:02:08 1998
+++ linux/kernel/sys.c	Wed Oct 21 10:02:49 1998
@@ -586,11 +586,11 @@
 	
 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
 		if (old_fsuid == 0 && current->fsuid != 0) {
-			current->cap_effective.cap &= ~CAP_FS_MASK;
+			cap_t(current->cap_effective) &= ~CAP_FS_MASK;
 		}
 		if (old_fsuid != 0 && current->fsuid == 0) {
-			current->cap_effective.cap |=
-				(current->cap_permitted.cap & CAP_FS_MASK);
+			cap_t(current->cap_effective) |=
+				(cap_t(current->cap_permitted) & CAP_FS_MASK);
 		}
 	}
 
diff -u --recursive --new-file v2.1.125/linux/mm/filemap.c linux/mm/filemap.c
--- v2.1.125/linux/mm/filemap.c	Thu Aug 20 17:05:19 1998
+++ linux/mm/filemap.c	Thu Oct 22 12:14:53 1998
@@ -153,7 +153,7 @@
 		} while (tmp != bh);
 
 		/* Refuse to swap out all buffer pages */
-		if ((buffermem >> PAGE_SHIFT) * 100 < (buffer_mem.min_percent * num_physpages))
+		if (buffer_under_min())
 			goto next;
 	}
 
@@ -167,6 +167,11 @@
 	case 1:
 		/* is it a swap-cache or page-cache page? */
 		if (page->inode) {
+			/* Throw swap-cache pages away more aggressively */
+			if (PageSwapCache(page)) {
+				delete_from_swap_cache(page);
+				return 1;
+			}
 			if (test_and_clear_bit(PG_referenced, &page->flags)) {
 				touch_page(page);
 				break;
@@ -174,12 +179,8 @@
 			age_page(page);
 			if (page->age)
 				break;
-			if (page_cache_size * 100 < (page_cache.min_percent * num_physpages))
+			if (pgcache_under_min())
 				break;
-			if (PageSwapCache(page)) {
-				delete_from_swap_cache(page);
-				return 1;
-			}
 			remove_inode_page(page);
 			return 1;
 		}
@@ -1519,24 +1520,42 @@
 {
 	struct dentry	*dentry = file->f_dentry; 
 	struct inode	*inode = dentry->d_inode; 
+	unsigned long	pos = *ppos;
+	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
 	struct page	*page, **hash;
 	unsigned long	page_cache = 0;
 	unsigned long	pgpos, offset;
 	unsigned long	bytes, written;
-	unsigned long	pos;
 	long		status, sync, didread;
 
 	if (!inode->i_op || !inode->i_op->updatepage)
 		return -EIO;
 
 	sync    = file->f_flags & O_SYNC;
-	pos     = *ppos;
 	written = 0;
-	status  = 0;
 
 	if (file->f_flags & O_APPEND)
 		pos = inode->i_size;
 
+	/*
+	 * Check whether we've reached the file size limit.
+	 */
+	status = -EFBIG;
+	if (pos >= limit) {
+		send_sig(SIGXFSZ, current, 0);
+		goto out;
+	}
+
+	status  = 0;
+	/*
+	 * Check whether to truncate the write,
+	 * and send the signal if we do.
+	 */
+	if (count > limit - pos) {
+		send_sig(SIGXFSZ, current, 0);
+		count = limit - pos;
+	}
+
 	while (count) {
 		/*
 		 * Try to find the page in the cache. If it isn't there,
@@ -1621,6 +1640,7 @@
 
 	if (page_cache)
 		free_page(page_cache);
+out:
 	return written ? written : status;
 }
 
diff -u --recursive --new-file v2.1.125/linux/mm/memory.c linux/mm/memory.c
--- v2.1.125/linux/mm/memory.c	Thu Sep 17 17:53:39 1998
+++ linux/mm/memory.c	Thu Oct 22 12:20:37 1998
@@ -289,10 +289,6 @@
 				}
 				if (cow)
 					pte = pte_wrprotect(pte);
-#if 0	/* No longer needed with the new swap cache code */
-				if (delete_from_swap_cache(&mem_map[page_nr]))
-					pte = pte_mkdirty(pte);
-#endif
 				set_pte(dst_pte, pte_mkold(pte));
 				set_pte(src_pte, pte);
 				atomic_inc(&mem_map[page_nr].count);
diff -u --recursive --new-file v2.1.125/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.1.125/linux/mm/page_alloc.c	Mon Sep 28 10:51:36 1998
+++ linux/mm/page_alloc.c	Thu Oct 22 12:19:51 1998
@@ -408,8 +408,9 @@
 	/* The page is unshared, and we want write access.  In this
 	   case, it is safe to tear down the swap cache and give the
 	   page over entirely to this process. */
-		
-	delete_from_swap_cache(page_map);
+
+	if (PageSwapCache(page_map))
+		delete_from_swap_cache(page_map);
 	set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))));
   	return;
 }
diff -u --recursive --new-file v2.1.125/linux/mm/slab.c linux/mm/slab.c
--- v2.1.125/linux/mm/slab.c	Wed Aug 26 11:37:45 1998
+++ linux/mm/slab.c	Wed Oct 21 08:52:06 1998
@@ -1444,8 +1444,10 @@
 		}
 		/* Couldn't grow, but some objs may have been freed. */
 		spin_lock_irq(&cachep->c_spinlock);
-		if (cachep->c_freep != kmem_slab_end(cachep))
-			goto try_again;
+		if (cachep->c_freep != kmem_slab_end(cachep)) {
+			if ((flags & SLAB_ATOMIC) == 0) 
+				goto try_again;
+		}
 	} else {
 		/* Very serious error - maybe panic() here? */
 		kmem_report_alloc_err("Bad slab magic (corrupt)", cachep);
diff -u --recursive --new-file v2.1.125/linux/mm/swap_state.c linux/mm/swap_state.c
--- v2.1.125/linux/mm/swap_state.c	Mon Sep 28 10:51:36 1998
+++ linux/mm/swap_state.c	Thu Oct 22 12:21:57 1998
@@ -219,24 +219,25 @@
 }
 
 
+/*
+ * This must be called only on pages that have
+ * been verified to be in the swap cache.
+ */
 void delete_from_swap_cache(struct page *page)
 {
+	long entry = page->offset;
+
 #ifdef SWAP_CACHE_INFO
 	swap_cache_del_total++;
-#endif	
-	if (PageSwapCache (page))  {
-		long entry = page->offset;
-#ifdef SWAP_CACHE_INFO
-		swap_cache_del_success++;
+	swap_cache_del_success++;
 #endif
 #ifdef DEBUG_SWAP
-		printk("DebugVM: delete_from_swap_cache(%08lx count %d, "
-		       "entry %08lx)\n",
-		       page_address(page), atomic_read(&page->count), entry);
+	printk("DebugVM: delete_from_swap_cache(%08lx count %d, "
+	       "entry %08lx)\n",
+	       page_address(page), atomic_read(&page->count), entry);
 #endif
-		remove_from_swap_cache (page);
-		swap_free (entry);
-	}
+	remove_from_swap_cache (page);
+	swap_free (entry);
 }
 
 /* 
diff -u --recursive --new-file v2.1.125/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.1.125/linux/mm/vmscan.c	Fri Oct  9 13:27:17 1998
+++ linux/mm/vmscan.c	Mon Oct 12 13:08:48 1998
@@ -458,8 +458,7 @@
 	if (gfp_mask & __GFP_WAIT)
 		stop = 0;
 
-	if (((buffermem >> PAGE_SHIFT) * 100 > buffer_mem.borrow_percent * num_physpages)
-		   || (page_cache_size * 100 > page_cache.borrow_percent * num_physpages))
+	if (buffer_over_borrow() || pgcache_over_borrow())
 		shrink_mmap(i, gfp_mask);
 
 	switch (state) {
@@ -650,11 +649,10 @@
 	}
  
 	if ((long) (now - want) >= 0) {
-		if (want_wakeup || (num_physpages * buffer_mem.max_percent) < (buffermem >> PAGE_SHIFT) * 100
-				|| (num_physpages * page_cache.max_percent < page_cache_size * 100)) {
+		if (want_wakeup || buffer_over_max() || pgcache_over_max()) {
 			/* Set the next wake-up time */
 			next_swap_jiffies = now + swapout_interval;
-			wake_up(&kswapd_wait);
+			kswapd_wakeup();
 		}
 	}
 	timer_active |= (1<<SWAP_TIMER);
diff -u --recursive --new-file v2.1.125/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- v2.1.125/linux/net/netrom/af_netrom.c	Sat Sep  5 16:46:42 1998
+++ linux/net/netrom/af_netrom.c	Fri Oct  9 11:56:59 1998
@@ -238,7 +238,7 @@
 /*
  *	Find a connected NET/ROM socket given their circuit IDs.
  */
-static struct sock *nr_find_peer(unsigned char index, unsigned char id)
+static struct sock *nr_find_peer(unsigned char index, unsigned char id, ax25_address *dest)
 {
 	struct sock *s;
 	unsigned long flags;
@@ -247,7 +247,7 @@
 	cli();
 
 	for (s = nr_list; s != NULL; s = s->next) {
-		if (s->protinfo.nr->your_index == index && s->protinfo.nr->your_id == id) {
+		if (s->protinfo.nr->your_index == index && s->protinfo.nr->your_id == id && ax25cmp(&s->protinfo.nr->dest_addr, dest) == 0) {
 			restore_flags(flags);
 			return s;
 		}
@@ -575,14 +575,15 @@
 			sk->state_change(sk);
 			sk->dead                 = 1;
 			sk->destroy              = 1;
+			sk->socket               = NULL;
 			break;
 
 		default:
+			sk->socket = NULL;
 			break;
 	}
 
 	sock->sk   = NULL;	
-	sk->socket = NULL;	/* Not used, but we should do this */
 
 	return 0;
 }
@@ -597,7 +598,11 @@
 	if (sk->zapped == 0)
 		return -EINVAL;
 
-	if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25))
+	if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct
+full_sockaddr_ax25))
+		return -EINVAL;
+
+	if (addr_len < (addr->fsa_ax25.sax25_ndigis * sizeof(ax25_address) + sizeof(struct sockaddr_ax25)))
 		return -EINVAL;
 
 	if (addr->fsa_ax25.sax25_family != AF_NETROM)
@@ -863,10 +868,10 @@
 
 	if (circuit_index == 0 && circuit_id == 0) {
 		if (frametype == NR_CONNACK && flags == NR_CHOKE_FLAG)
-			sk = nr_find_peer(peer_circuit_index, peer_circuit_id);
+			sk = nr_find_peer(peer_circuit_index, peer_circuit_id, src);
 	} else {
 		if (frametype == NR_CONNREQ)
-			sk = nr_find_peer(circuit_index, circuit_id);
+			sk = nr_find_peer(circuit_index, circuit_id, src);
 		else
 			sk = nr_find_socket(circuit_index, circuit_id);
 	}
diff -u --recursive --new-file v2.1.125/linux/net/netrom/nr_loopback.c linux/net/netrom/nr_loopback.c
--- v2.1.125/linux/net/netrom/nr_loopback.c	Tue Apr 14 14:29:26 1998
+++ linux/net/netrom/nr_loopback.c	Fri Oct  9 11:56:59 1998
@@ -77,16 +77,16 @@
 	ax25_address *nr_dest;
 	struct device *dev;
 
-	while ((skb = skb_dequeue(&loopback_queue)) != NULL) {
+	if ((skb = skb_dequeue(&loopback_queue)) != NULL) {
 		nr_dest = (ax25_address *)(skb->data + 7);
 
-		if ((dev = nr_dev_get(nr_dest)) == NULL) {
-			kfree_skb(skb);
-			continue;
-		}
+		dev = nr_dev_get(nr_dest);
 
-		if (nr_rx_frame(skb, dev) == 0)
+		if (dev == NULL || nr_rx_frame(skb, dev) == 0)
 			kfree_skb(skb);
+
+		if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
+			nr_set_loopback_timer();
 	}
 }
 
diff -u --recursive --new-file v2.1.125/linux/net/netrom/nr_route.c linux/net/netrom/nr_route.c
--- v2.1.125/linux/net/netrom/nr_route.c	Tue Apr 14 14:29:26 1998
+++ linux/net/netrom/nr_route.c	Fri Oct  9 11:56:59 1998
@@ -81,6 +81,22 @@
 		if (ax25cmp(ax25, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev)
 			break;
 
+	/*
+	 * The L2 link to a neighbour has failed in the past
+	 * and now a frame comes from this neighbour. We assume
+	 * it was a temporary trouble with the link and reset the
+	 * routes now (and not wait for a node broadcast).
+	 */
+	if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) {
+		struct nr_node *node;
+
+		for (node = nr_node_list; node != NULL; node = node->next)
+			for (i = 0; i < node->count; i++)
+				if (node->routes[i].neighbour == nr_neigh)
+					if (i < node->which)
+						node->which = i;
+	}
+
 	if (nr_neigh != NULL)
 		nr_neigh->failed = 0;
 
diff -u --recursive --new-file v2.1.125/linux/net/unix/garbage.c linux/net/unix/garbage.c
--- v2.1.125/linux/net/unix/garbage.c	Fri May  8 23:14:58 1998
+++ linux/net/unix/garbage.c	Sat Oct 17 16:18:52 1998
@@ -31,6 +31,25 @@
  *  Fixes:
  *	Alan Cox	07 Sept	1997	Vmalloc internal stack as needed.
  *					Cope with changing max_files.
+ *	Al Viro		11 Oct 1998
+ *		Graph may have cycles. That is, we can send the descriptor
+ *		of foo to bar and vice versa. Current code chokes on that.
+ *		Fix: move SCM_RIGHTS ones into the separate list and then
+ *		skb_free() them all instead of doing explicit fput's.
+ *		Another problem: since fput() may block somebody may
+ *		create a new unix_socket when we are in the middle of sweep
+ *		phase. Fix: revert the logic wrt MARKED. Mark everything
+ *		upon the beginning and unmark non-junk ones.
+ *
+ *		[12 Oct 1998] AAARGH! New code purges all SCM_RIGHTS
+ *		sent to connect()'ed but still not accept()'ed sockets.
+ *		Fixed. Old code had slightly different problem here:
+ *		extra fput() in situation when we passed the descriptor via
+ *		such socket and closed it (descriptor). That would happen on
+ *		each unix_gc() until the accept(). Since the struct file in
+ *		question would go to the free list and might be reused...
+ *		That might be the reason of random oopses on close_fp() in
+ *		unrelated processes.
  *
  */
  
@@ -123,11 +142,11 @@
 	return in_stack == 0;
 }
 
-extern inline void maybe_mark_and_push(unix_socket *x)
+extern inline void maybe_unmark_and_push(unix_socket *x)
 {
-	if (x->protinfo.af_unix.marksweep&MARKED)
+	if (!(x->protinfo.af_unix.marksweep&MARKED))
 		return;
-	x->protinfo.af_unix.marksweep|=MARKED;
+	x->protinfo.af_unix.marksweep&=~MARKED;
 	push_stack(x);
 }
 
@@ -139,7 +158,8 @@
 	static int in_unix_gc=0;
 	int i;
 	unix_socket *s;
-	unix_socket *next;
+	struct sk_buff_head hitlist;
+	struct sk_buff *skb;
 	
 	/*
 	 *	Avoid a recursive GC.
@@ -163,17 +183,21 @@
 		max_stack=max_files;
 	}
 	
+	forall_unix_sockets(i, s)
+	{
+		s->protinfo.af_unix.marksweep|=MARKED;
+	}
 	/*
-	 *	Assume everything is now unmarked 
+	 *	Everything is now marked 
 	 */
 
 	/* Invariant to be maintained:
-		- everything marked is either:
+		- everything unmarked is either:
 		-- (a) on the stack, or
-		-- (b) has all of its children marked
-		- everything on the stack is always marked
+		-- (b) has all of its children unmarked
+		- everything on the stack is always unmarked
 		- nothing is ever pushed onto the stack twice, because:
-		-- nothing previously marked is ever pushed on the stack
+		-- nothing previously unmarked is ever pushed on the stack
 	 */
 
 	/*
@@ -186,8 +210,9 @@
 		 *	If all instances of the descriptor are not
 		 *	in flight we are in use.
 		 */
-		if(s->socket && s->socket->file && s->socket->file->f_count > s->protinfo.af_unix.inflight)
-			maybe_mark_and_push(s);
+		if(s->socket && s->socket->file &&
+		   s->socket->file->f_count > s->protinfo.af_unix.inflight)
+			maybe_unmark_and_push(s);
 	}
 
 	/*
@@ -198,7 +223,6 @@
 	{
 		unix_socket *x = pop_stack();
 		unix_socket *f=NULL,*sk;
-		struct sk_buff *skb;
 tail:		
 		skb=skb_peek(&x->receive_queue);
 		
@@ -227,16 +251,23 @@
 					if((sk=unix_get_socket(*fp++))!=NULL)
 					{
 						/*
-						 *	Remember the first, mark the
-						 *	rest.
+						 *	Remember the first,
+						 *	unmark the rest.
 						 */
 						if(f==NULL)
 							f=sk;
 						else
-							maybe_mark_and_push(sk);
+							maybe_unmark_and_push(sk);
 					}
 				}
 			}
+			/* We have to scan not-yet-accepted ones too */
+			if (UNIXCB(skb).attr & MSG_SYN) {
+				if (f==NULL)
+					f=skb->sk;
+				else
+					maybe_unmark_and_push(skb->sk);
+			}
 			skb=skb->next;
 		}
 		/*
@@ -245,9 +276,9 @@
 
 		if (f) 
 		{
-			if (!(f->protinfo.af_unix.marksweep&MARKED))
+			if ((f->protinfo.af_unix.marksweep&MARKED))
 			{
-				f->protinfo.af_unix.marksweep|=MARKED;
+				f->protinfo.af_unix.marksweep&=~MARKED;
 				x=f;
 				f=NULL;
 				goto tail;
@@ -255,35 +286,37 @@
 		}
 	}
 
-	/*
-	 *	Sweep phase.  NOTE: this part dominates the time complexity 
-	 */
+	skb_queue_head_init(&hitlist);
 
 	forall_unix_sockets(i, s)
 	{
-		next=s->next;
-		if (!(s->protinfo.af_unix.marksweep&MARKED))
+		if (s->protinfo.af_unix.marksweep&MARKED)
 		{
-			/*
-			 *	We exist only in the passing tree of sockets
-			 *	that is no longer connected to active descriptors
-			 *	Time to die..
-			 *
-			 *	Subtle item: We will correctly sweep out the
-			 *	socket that has just been closed by the user.
-			 *	We must not close this as we are in the middle
-			 *	of its close at this moment. Skip that file
-			 *	using f_count==0 to spot it.
-			 */
-			 
-			if(s->socket && s->socket->file && s->socket->file->f_count)
-				fput(s->socket->file);
+			struct sk_buff *nextsk;
+			skb=skb_peek(&s->receive_queue);
+			while(skb && skb != (struct sk_buff *)&s->receive_queue)
+			{
+				nextsk=skb->next;
+				/*
+				 *	Do we have file descriptors ?
+				 */
+				if(UNIXCB(skb).fp)
+				{
+					skb_unlink(skb);
+					skb_queue_tail(&hitlist,skb);
+				}
+				skb=nextsk;
+			}
 		}
-		else
-			s->protinfo.af_unix.marksweep&=~MARKED;	/* unmark everything for next collection */
 	}
-	
+
+	/*
+	 *	Here we are. Hitlist is filled. Die.
+	 */
+
+	while ((skb=skb_dequeue(&hitlist))!=NULL) {
+		kfree_skb(skb);
+	}
+
 	in_unix_gc=0;
-	
-	free_page((long)stack);
 }
diff -u --recursive --new-file v2.1.125/linux/scripts/lxdialog/menubox.c linux/scripts/lxdialog/menubox.c
--- v2.1.125/linux/scripts/lxdialog/menubox.c	Fri Oct  9 13:27:18 1998
+++ linux/scripts/lxdialog/menubox.c	Sat Oct 10 10:09:58 1998
@@ -60,8 +60,11 @@
 static void
 print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
 {
-    int i, j;
+    int j;
     char menu_item[menu_width+1];
+#if OLD_NCURSES
+     int i;
+#endif
 
     strncpy(menu_item, item, menu_width);
     menu_item[menu_width] = 0;
diff -u --recursive --new-file v2.1.125/linux/scripts/lxdialog/textbox.c linux/scripts/lxdialog/textbox.c
--- v2.1.125/linux/scripts/lxdialog/textbox.c	Fri Oct  9 13:27:18 1998
+++ linux/scripts/lxdialog/textbox.c	Sat Oct 10 10:09:58 1998
@@ -451,8 +451,11 @@
 static void
 print_line (WINDOW * win, int row, int width)
 {
-    int i, y, x;
+    int y, x;
     char *line;
+#if OLD_NCURSES
+     int i;
+#endif
 
     line = get_line ();
     line += MIN (strlen (line), hscroll);	/* Scroll horizontally */
