diff -u --recursive --new-file v2.1.80/linux/CREDITS linux/CREDITS
--- v2.1.80/linux/CREDITS	Tue Jan 20 16:44:57 1998
+++ linux/CREDITS	Wed Jan 21 14:09:54 1998
@@ -465,11 +465,12 @@
 S: Germany
 
 N: Jeremy Fitzhardinge
-E: jeremy@sw.oz.au
+E: jeremy@zip.com.au
 D: Improved mmap and munmap handling
 D: General mm minor tidyups
-S: 99 Albermarle Street
-S: Newtown 2042
+S: 67 Surrey St.
+S: Darlinghurst, Sydney
+S: NSW 2010
 S: Australia
 
 N: Ralf Flaxa
@@ -705,6 +706,7 @@
 N: Ron Holt
 E: ron@caldera.com
 W: http://www.holt.org/
+P: 1024/1FD44539 DF 4B EB 9F 5B 68 38 9A  40 E3 FB 71 D1 C8 0B 56
 D: Kernel development
 D: Minor kernel modifications to support Wabi and Wine
 S: Caldera, Inc.
@@ -820,9 +822,11 @@
 
 N: Ian Kluft
 E: ikluft@thunder.sbay.org
-D: Smail binary packages for Slackware and Debian
-S: 2200 Monroe Street #1509
-S: Santa Clara, California 95050-3452
+W: http://www.kluft.com/~ikluft/
+D: NET-1 beta testing & minor patches, original Smail binary packages for
+D: Slackware and Debian, vote-taker for 2nd comp.os.linux reorganization
+S: PO Box 611311
+S: San Jose, CA 95161-1311
 S: USA
 
 N: Alain L. Knaff
@@ -977,6 +981,14 @@
 S: Nepean, Ontario
 S: Canada K2H 6S3
 
+N: Jamie Lokier
+E: jamie@imbolc.ucc.ie
+D: Reboot-through-BIOS for broken 486 motherboards
+S: 26 Oatlands Road
+S: Oxford
+S: OX2 0ET
+S: United Kingdom
+
 N: Warner Losh
 E: imp@village.org
 D: Linux/MIPS Deskstation support, Provided OI/OB for Linux
@@ -1146,6 +1158,7 @@
 
 N: Rick Miller
 E: rdmiller@execpc.com
+W: http://www.execpc.com/~rdmiller/
 D: Original Linux Device Registrar (Major/minor numbers)
 D: au-play, bwBASIC
 S: S78 W16203 Woods Road
@@ -1309,8 +1322,12 @@
 D: Some PCI kernel support
 
 N: Stefan Probst
-E: snprobst@immd4.informatik.uni-erlangen.de
-D: The Linux Support Team Erlangen
+E: sp@caldera.de
+D: The Linux Support Team Erlangen, 1993-97
+S: Caldera (Deutschland) GmbH
+S: Lazarettstrasse 8
+S: 91054 Erlangen
+S: Germany
 
 N: Daniel Quinlan
 E: quinlan@pathname.com
@@ -1651,6 +1668,14 @@
 S: Obere Heerbergstrasse 17
 S: 97078 Wuerzburg
 S: Germany
+
+N: Greg Ungerer
+E: gerg@stallion.com
+D: Author of Stallion multiport serial drivers
+S: Stallion Technologies
+S: 33 Woodstock Rd
+S: Toowong, QLD. 4066
+S: Australia
 
 N: Jeffrey A. Uphoff
 E: juphoff@nrao.edu
diff -u --recursive --new-file v2.1.80/linux/Documentation/00-INDEX linux/Documentation/00-INDEX
--- v2.1.80/linux/Documentation/00-INDEX	Sun Dec 28 12:05:44 1997
+++ linux/Documentation/00-INDEX	Wed Jan 21 17:51:11 1998
@@ -80,6 +80,8 @@
 	- notes on how to use the Real Time Clock (aka CMOS clock) driver.
 scsi.txt
 	- short blurb on using SCSI support as a module.
+smart-config.txt
+	- description of the Smart Config makefile feature.
 smp.tex
 	- TeX document describing implementation of Multiprocessor Linux
 svga.txt
diff -u --recursive --new-file v2.1.80/linux/Documentation/binfmt_misc.txt linux/Documentation/binfmt_misc.txt
--- v2.1.80/linux/Documentation/binfmt_misc.txt	Sun Aug 31 09:40:01 1997
+++ linux/Documentation/binfmt_misc.txt	Fri Jan 23 16:40:13 1998
@@ -54,10 +54,10 @@
 - enable support for packed DOS applications (pre-configured dosemu hdimages):
   echo ':DEXE:M::\x0eDEX::/usr/bin/dosexec:' > register
 
-- enable support for DOS/Windows executables (using mzloader and dosemu/wine):
-  echo ':DOSWin:M::MZ::/usr/sbin/mzloader:' > register
-  echo ':DOScom:E::com::/usr/sbin/mzloader:' > register
-  echo ':DOSexe:E::exe::/usr/sbin/mzloader:' > register
+- enable support for Windows executables using wine:
+  echo ':DOSWin:M::MZ::/usr/local/bin/wine:' > register
+
+For java support see Documentation/java.txt
 
 
 You can enable/disable binfmt_misc or one binary type by echoing 0 (to disable)
@@ -68,73 +68,12 @@
 or /proc/sys/fs/binfmt_misc/status.
 
 
-Emulating binfmt_java:
-======================
-
-To emulate binfmt_java the following register-strings could be used: 
-for compiled Java programs use
-  ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:'
-for simple applet support use
-  ':Applet:E::html::/usr/local/java/bin/appletviewer:'
-for more selective applet support (like binfmt_java) use
-  ':Applet:M::<!--applet::/usr/local/java/bin/appletviewer:'
-
-Note, that for the more selective applet support you have to modify
-existing html-files to contain <!--applet--> in the first line to
-let this work!
-
-For the compiled Java programs you need a wrapper script like the
-following (this is because Java is broken in case of the filename
-handling):
-
-====================== Cut here ===================
-#!/bin/bash
-# /usr/local/java/bin/javawrapper - the wrapper for binfmt_misc/java
-CLASS=$1
-
-# if classname is a link, we follow it (this could be done easier - how?)
-if [ -L "$1" ] ; then
-	CLASS=`ls --color=no -l $1 | tr -s '\t ' '  ' | cut -d ' ' -f 11` 
-fi
-CLASSN=`basename $CLASS .class`
-CLASSP=`dirname $CLASS`
-
-FOO=$PATH
-PATH=$CLASSPATH
-if [ -z "`type -p -a $CLASSN.class`" ] ; then
-	# class is not in CLASSPATH
-	if [ -e "$CLASSP/$CLASSN.class" ] ; then
-		# append dir of class to CLASSPATH
-		if [ -z "${CLASSPATH}" ] ; then
-			export CLASSPATH=$CLASSP
-		else
-			export CLASSPATH=$CLASSP:$CLASSPATH
-		fi
-	else
-		# uh! now we would have to create a symbolic link - really
-		# ugly, i.e. print a message that one has to change the setup
-		echo "Hey! This is not a good setup to run $1 !"
-		exit 1
-	fi
-fi
-PATH=$FOO
-
-shift
-/usr/local/java/bin/java $CLASSN $@
-====================== Cut here ===================
-
-To add a Java program to your path best put a symbolic link to the main
-.class file into /usr/bin (or another place you like) omitting the .class
-extension. The directory containing the original .class file will be
-added to your CLASSPATH during execution.
-
-
-
 HINTS:
 ======
 
 If you want to pass special arguments to your interpreter, you can
-write a wrapper script for it.
+write a wrapper script for it. See Documentation/java.txt for an
+example.
 
 Your interpreter should NOT look in the PATH for the filename; the
 kernel passes it the full filename to use.  Using the PATH can cause
diff -u --recursive --new-file v2.1.80/linux/Documentation/filesystems/smbfs.txt linux/Documentation/filesystems/smbfs.txt
--- v2.1.80/linux/Documentation/filesystems/smbfs.txt	Mon Nov 24 10:30:40 1997
+++ linux/Documentation/filesystems/smbfs.txt	Wed Jan 21 10:09:31 1998
@@ -1,27 +1,20 @@
 Smbfs is a filesystem that implements the SMB protocol, which is the
 protocol used by Windows for Workgroups, Windows 95 and Windows NT.
-Smbfs was inspired by samba, the program written by Andrew Tridgell
+Smbfs was inspired by Samba, the program written by Andrew Tridgell
 that turns any unix host into a file server for DOS or Windows clients.
 See ftp://nimbus.anu.edu.au/pub/tridge/samba/ for this interesting
 program suite and much more information on SMB, NetBIOS over TCP/IP,
 and explanations for concepts like netbios name or share.
 
-To use smbfs, you need to install the Samba package (Samba-1.9.17p1 or
-later), and you need the special mount program from the smbfs package
-(smbfs-2.1.0 or later), found on
-
-	ftp://ftp.gwdg.de/pub/linux/misc/smbfs/dontuse
-
-After downloading the smbfs package, apply the patch to the smbclient
-program and recompile.  Smbfs can then be mounted from the smbclient
-command line, as for example:
-
-	smb: \>mount /mnt/tmp -f 755
-
-For convenience, you may wish to package the command in a script like this:
-
-#!/bin/sh
-echo "mount /mnt/tmp -f 755" | smbclient //server/c$ -U administrator%
+To use smbfs, you must first install the Samba package (Samba-1.9.18p1 or
+later). This package includes the special smbmount utility needed to mount
+smbfs volumes. Refer to the smbmount(8) and smbmnt(8) manpages for the
+details regarding smbfs mounts.
+
+The smbmount utility reads the Samba smb.conf config file for some of its
+options, and at least one of these is important for smbfs operation. You
+should enable the TCP_NODELAY socket option, or else directory listings
+will be dramatically slower (under Win NT at least).
 
 Mount-Time Options
 Windows 95 has several bugs that affect SMB operations, and smbfs includes
@@ -37,11 +30,12 @@
 Option                  Value  Effect
 Identify Win 95 Server    1    Enables bug fixes
 Use Core Attributes       2    Speeds up directory scans, only mtime
+Use Dir Attributes        4    Alternate way to get file attributes
 
 To apply the options, sum the values and prepend it to the file mode. For
-example, to use both options with file mode 755, you would prepend 3 to 755:
+example, to use options 1 and 2 with file mode 755, you would specify 3755:
 
-	cnt>mount /mnt/tmp -f 3755
+	mount /mnt/tmp -f 3755
 
 Smbfs will print a message at mount time confirming the selected options.
 Note that _only_ Windows 95 servers require special treatment; using the
diff -u --recursive --new-file v2.1.80/linux/Documentation/java.txt linux/Documentation/java.txt
--- v2.1.80/linux/Documentation/java.txt	Thu Nov 21 01:00:33 1996
+++ linux/Documentation/java.txt	Fri Jan 23 16:40:13 1998
@@ -4,45 +4,92 @@
 Linux beats them ALL! While all other OS's are TALKING about direct
 support of Java Binaries in the OS, Linux is doing it!
 
-You execute Java classes as you would any other executable, after a few
-small details:
+You can execute Java applications and Java Applets just like any
+other program after you have done the following:
+
+1) You MUST FIRST install the Java Developers Kit for Linux.
+   The Java on Linux HOWTO gives the details on getting and
+   installing this. This HOWTO can be found at:
+
+	ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO
+
+   You should also set up a reasonable CLASSPATH environment
+   variable to use Java applications that make use of any
+   nonstandard classes (not included in the same directory
+   as the application itself).
+
+2) You have to compile BINFMT_MISC either as module or into
+   the kernel (CONFIG_BINFMT_MISC) and set it up properly.
+   If you choose to compile it as a module, you will have
+   to insert it manually with modprobe/insmod, as kerneld
+   can not easy be supported with binfmt_misc. 
+   Read the file 'binfmt_misc.txt' in this directory to know
+   more about the configuration process.
+
+3) Add the following configuration items to binfmt_misc
+   (you should really have read binfmt_misc.txt now):
+   support for Java applications:
+     ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:'
+   support for Java Applets:
+     ':Applet:E::html::/usr/local/java/bin/appletviewer:'
+   or the following, if you want to be more selective:
+     ':Applet:M::<!--applet::/usr/local/java/bin/appletviewer:'
+
+   Of cause you have to fix the path names, if you installed the JDK
+   at another place than /usr/local/java.
+
+   Note, that for the more selective applet support you have to modify
+   existing html-files to contain <!--applet--> in the first line
+   ('<' has to be the first character!) to let this work!
+
+   For the compiled Java programs you need a wrapper script like the
+   following (this is because Java is broken in case of the filename
+   handling), again fix the path names, both in the script and in the
+   above given configuration string:
+
+====================== Cut here ===================
+#!/bin/bash
+# /usr/local/java/bin/javawrapper - the wrapper for binfmt_misc/java
+CLASS=$1
+
+# if classname is a link, we follow it (this could be done easier - how?)
+if [ -L "$1" ] ; then
+        CLASS=`ls --color=no -l $1 | tr -s '\t ' '  ' | cut -d ' ' -f 11`
+fi
+CLASSN=`basename $CLASS .class`
+CLASSP=`dirname $CLASS`
+
+FOO=$PATH
+PATH=$CLASSPATH
+if [ -z "`type -p -a $CLASSN.class`" ] ; then
+        # class is not in CLASSPATH
+        if [ -e "$CLASSP/$CLASSN.class" ] ; then
+                # append dir of class to CLASSPATH
+                if [ -z "${CLASSPATH}" ] ; then
+                        export CLASSPATH=$CLASSP
+                else
+                        export CLASSPATH=$CLASSP:$CLASSPATH
+                fi
+        else
+                # uh! now we would have to create a symbolic link - really
+                # ugly, i.e. print a message that one has to change the setup
+                echo "Hey! This is not a good setup to run $1 !"
+                exit 1
+        fi
+fi
+PATH=$FOO
+
+shift
+/usr/local/java/bin/java $CLASSN "$@"
+====================== Cut here ===================
+
+
+Now simply chmod +x the .class and/or .html files you want to execute.
+To add a Java program to your path best put a symbolic link to the main
+.class file into /usr/bin (or another place you like) omitting the .class
+extension. The directory containing the original .class file will be
+added to your CLASSPATH during execution.
 
-	1) You MUST FIRST install the Java Developers Kit for Linux.
-	   The Java on Linux HOWTO gives the details on getting and
-	   installing this. This HOWTO can be found at:
-
-		ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO
-
-	   If you install the JDK in a location other than /usr/bin/java,
-	   then you will need to tell the kernel where you put the Java
-	   interpreter.  
-           There are two ways to do this.
-           One, edit fs/binfmt_java.c file and make the needed change to 
-	   the _PATH_JAVA definition at the top of that file.  
-           Two, as root, issue the command:
-	 echo "/path/to/java/interpreter" > /proc/sys/kernel/java-interpreter
-	   (Currently, this does not work if you're using a module for
-	    Java support.)
-
-	2) You must chmod the '*.class' files you wish to execute with
-	   the execute bit. This is not normally (till now) done with
-	   '.class' files.
-
-	3) You must optionally export a CLASSPATH environment variable,
-	   if you plan to use Java applications installed outside of
-	   /usr/local/java/classes/*.
-
-	4) Either compile your kernel with Java support builtin, or
-	   as a loadable module. If a module, load it with insmod or
-	   kerneld.
-
-	5) A caveat.  When executing a java file, the java interpreter is
-	   invoked only with the class name, not with the complete file path.
-	   Therefore it is possible that the file the shell finds with PATH
-	   is not the same file the java interpreter finds with CLASSPATH.
-	   The recommended solution is to make symbolic links from a directory
-	   in PATH to the actual class file in CLASSPATH, e.g.,
-	   /usr/local/bin/myapp -> /usr/local/java/classes/myapp.class.
 
 To test your new setup, enter in the following simple Java app, and name
 it "HelloWorld.java":
@@ -53,59 +100,20 @@
 		}
 	}
 
-
 Now compile the application with:
-
-	/usr/local/java/bin/javac HelloWorld.java
+	javac HelloWorld.java
 
 Set the executable permissions of the binary file, with:
-
 	chmod 755 HelloWorld.class
 
 And then execute it:
-
 	./HelloWorld.class
 
 
-Yes, it's JUST THAT EASY! ;-)
-
------------------------------------------------------------------
-
-Nope, I didn't forget about Java Applets! ;-)
-
-While this may not be the best way to do this, it works!
-
-Take any html file used with the Java appletviewer (like the
-demo/Blink/example1.html file), and:
-
-	1) Insert a new first line of:
-
-		<!--applet-->
-
-	   Make sure the '<' is the first character in the file. This
-	   will be treated as a valid HTML comment outside of this
-	   Java Applet support, so the modified file can still be used
-	   with all known browsers.
-
-	2) If you install the applet viewer in a location other than
-	   /usr/bin/appletviewer, then you will need to tell the
-	   kernel where you put the Java appletviewer.  
-           There are two ways to do this.
-           One, edit fs/binfmt_java.c file and make the needed change to 
-	   the _PATH_APPLET definition at the top of that file.  
-           Two, as root, issue the command:
-	echo "/path/to/java/appletviewer" > /proc/sys/kernel/java-appletviewer
-	   (Currently, this does not work if you're using a module for
-	    Java support.)
-
-	3) You must chmod the '*.html' files you wish to execute with
-	   the execute bit. This is not normally (till now) done with
-	   '.html' files.
-
-	4) And then execute it.
-
+To execute Java Applets, simple chmod the *.html files to include
+the execution bit, then just do
+	./Applet.html
 
-Brian A. Lantz
-brian@lantz.com
-(/proc/sys/kernel/java-* support by Mike Shaver (shaver@ingenia.com))
 
+originally by Brian A. Lantz, brian@lantz.com
+heavily edited for binfmt_misc by Richard Günther.
diff -u --recursive --new-file v2.1.80/linux/Documentation/smart-config.txt linux/Documentation/smart-config.txt
--- v2.1.80/linux/Documentation/smart-config.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/smart-config.txt	Wed Jan 21 17:51:11 1998
@@ -0,0 +1,103 @@
+Smart CONFIG_* Dependencies
+Fri 2 Dec 1997
+
+Michael Chastain   <mec@shout.net>
+Werner Almesberger <almesber@lrc.di.epfl.ch>
+Martin von Loewis  <martin@mira.isdn.cs.tu-berlin.de>
+
+Here is the problem:
+
+    Suppose that drivers/net/foo.c has the following lines:
+
+	#include <linux/config.h>
+
+	...
+
+	#ifdef CONFIG_FOO_AUTOFROB
+	    /* Code for auto-frobbing */
+	#else
+	    /* Manual frobbing only */
+	#endif
+
+	...
+
+	#ifdef CONFIG_FOO_MODEL_TWO
+	    /* Code for model two */
+	#endif
+
+    Now suppose the user (the person building kernels) reconfigures the
+    kernel to change some unrelated setting.  This will regenerate the
+    file include/linux/autoconf.h, which will cause include/linux/config.h
+    to be out of date, which will cause drivers/net/foo.c to be recompiled.
+
+    Most kernel sources, perhaps 80% of them, have at least one CONFIG_*
+    dependency somewhere.  So changing _any_ CONFIG_* setting requires
+    almost _all_ of the kernel to be recompiled.
+
+Here is the solution:
+
+    We've made the dependency generator, mkdep.c, smarter.  Instead of
+    generating this dependency:
+
+	drivers/net/foo.c: include/linux/config.h
+
+    It now generates these dependencies:
+
+	drivers/net/foo.c: \
+	    include/config/foo_autofrob.h \
+	    include/config/foo_model_two.h
+
+    So drivers/net/foo.c depends only on the CONFIG_* lines that
+    it actually uses.
+
+    A new program, split-include.c, runs at the end of make config (also
+    make oldconfig, make menuconfig, and make xconfig).  split-include
+    reads include/linux/autoconf.h and updates the include/linux/*.h
+    directory, writing one file per option.  It updates only the files
+    that changed.
+
+    mkdep.c also generates much better warning messages for missing
+    or unneeded <linux/config.h> lines.  In fact, you can get these
+    messages without generating dependencies with the new top-level
+    target 'make checkconfig'.
+
+Flag Dependencies
+
+    Martin Von Loewis contributed another feature to this patch:
+    'flag dependencies'.  The idea is that a .o file depends on
+    the compilation flags used to build it.  The file foo.o has
+    its flags stored in .flags.foo.o.
+
+    Suppose the user changes the foo driver from resident to
+    modular, 'make' will notice that the foo.o was not compiled
+    with -DMODULE and will recompile foo.c.
+
+    Flag dependencies also work with per-source-file flags such
+    as those in drivers/net/CONFIG.
+
+    All .a and .o files made from C source or with 'ld' or 'ar'
+    have flag dependencies.  .S files do not have flag dependencies.
+
+Per-source-file Flags
+
+    You can specify compilation flags for individual source files
+    like this:
+
+	CFLAGS_foo.o = -DSPECIAL_FOO_DEFINE
+
+    This helps clean up drivers/net/Makefile, drivers/scsi/Makefile,
+    and several other Makefiles.
+
+Credit
+
+    Werner Almesberger had the original idea and wrote the first
+    version of this patch.
+    
+    Michael Chastain picked it up and continued development.  He is
+    now the principal author and maintainer.  Report bugs to him,
+    or to all three people together.
+
+    Martin von Loewis wrote flag dependencies, with some modifications
+    by Michael Chastain.
+
+    Thanks to all of the beta testers.
diff -u --recursive --new-file v2.1.80/linux/Makefile linux/Makefile
--- v2.1.80/linux/Makefile	Wed Jan 14 11:25:15 1998
+++ linux/Makefile	Fri Jan 23 16:36:22 1998
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 80
+SUBLEVEL = 81
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
@@ -343,14 +343,16 @@
 
 clean:	archclean
 	rm -f kernel/ksyms.lst include/linux/compile.h
-	rm -f `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print`
-	rm -f `find . -type f -name 'core' -print`
-	rm -f `find . -name '.*.flags' -print`
+	rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print`
+	rm -f core `find . -type f -name 'core' -print`
+	rm -f core `find . -name '.*.flags' -print`
 	rm -f vmlinux System.map
 	rm -f .tmp*
 	rm -f drivers/char/consolemap_deftbl.c drivers/char/conmakehash
 	rm -f drivers/sound/bin2hex drivers/sound/hex2hex
-	rm -f `find modules/ -type f -print`
+	if [ -d modules ]; then \
+		rm -f core `find modules/ -type f -print`; \
+	fi
 	rm -f submenu*
 
 mrproper: clean
@@ -368,6 +370,7 @@
 	rm -f include/asm
 	rm -rf include/config
 	rm -f .depend `find . -name .depend -print`
+	rm -f core `find . -size 0 -print`
 	rm -f .hdepend scripts/mkdep scripts/split-include
 	rm -f $(TOPDIR)/include/linux/modversions.h
 	rm -rf $(TOPDIR)/include/linux/modules
diff -u --recursive --new-file v2.1.80/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.1.80/linux/arch/alpha/kernel/irq.c	Mon Jan 12 14:51:14 1998
+++ linux/arch/alpha/kernel/irq.c	Wed Jan 21 17:46:00 1998
@@ -373,7 +373,7 @@
 		if (!action) 
 			continue;
 		len += sprintf(buf+len, "%2d: %10u %c %s",
-			       i, kstat.interrupts[i],
+			       i, kstat.interrupts[0][i],
 			       (action->flags & SA_INTERRUPT) ? '+' : ' ',
 			       action->name);
 		for (action=action->next; action; action = action->next) {
@@ -567,7 +567,7 @@
 	int cpu = smp_processor_id();
 
 	irq_enter(cpu, irq);
-	kstat.interrupts[irq]++;
+	kstat.interrupts[0][irq] += 1;
 	if (!action) {
 		unexpected_irq(irq, regs);
 	} else {
@@ -590,7 +590,7 @@
 	}
 
 	irq_enter(cpu, irq);
-	kstat.interrupts[irq]++;
+	kstat.interrupts[0][irq] += 1;
 	action = irq_action[irq];
 	/*
 	 * For normal interrupts, we mask it out, and then ACK it.
@@ -1050,7 +1050,6 @@
  */
 int probe_irq_off(unsigned long irqs)
 {
-	unsigned long delay;
 	int i;
 	
         irqs &= irq_mask;
diff -u --recursive --new-file v2.1.80/linux/arch/alpha/lib/csum_partial_copy.c linux/arch/alpha/lib/csum_partial_copy.c
--- v2.1.80/linux/arch/alpha/lib/csum_partial_copy.c	Sun Nov 30 10:59:02 1997
+++ linux/arch/alpha/lib/csum_partial_copy.c	Wed Jan 21 17:46:00 1998
@@ -112,7 +112,7 @@
  * easy.
  */
 static inline unsigned long
-csum_partial_cfu_dest_aligned(unsigned long *src, unsigned long *dst,
+csum_partial_cfu_dest_aligned(const unsigned long *src, unsigned long *dst,
 			      unsigned long soff,
 			      long len, unsigned long checksum,
 			      int *errp)
diff -u --recursive --new-file v2.1.80/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.1.80/linux/arch/i386/kernel/entry.S	Sat Jan 10 11:57:29 1998
+++ linux/arch/i386/kernel/entry.S	Fri Jan 23 16:23:44 1998
@@ -532,7 +532,8 @@
 	.long SYMBOL_NAME(sys_rt_sigsuspend)
 	.long SYMBOL_NAME(sys_pread)		/* 180 */
 	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown);
 	
-	.rept NR_syscalls-181
+	.rept NR_syscalls-182
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -u --recursive --new-file v2.1.80/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.1.80/linux/arch/i386/kernel/i386_ksyms.c	Sat Jan 10 18:04:59 1998
+++ linux/arch/i386/kernel/i386_ksyms.c	Fri Jan 23 11:21:28 1998
@@ -39,7 +39,7 @@
 EXPORT_SYMBOL_NOVERS(__down_failed);
 EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
 EXPORT_SYMBOL_NOVERS(__up_wakeup);
-EXPORT_SYMBOL(__intel_bh_counter);
+EXPORT_SYMBOL(global_bh_lock);
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_partial_copy);
 /* Delay loops */
diff -u --recursive --new-file v2.1.80/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.80/linux/arch/i386/kernel/irq.c	Tue Jan 20 14:20:55 1998
+++ linux/arch/i386/kernel/irq.c	Fri Jan 23 17:29:49 1998
@@ -68,12 +68,8 @@
 # define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
 #endif
 
+unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
-#ifdef __SMP__
-atomic_t __intel_bh_counter;
-#else
-int __intel_bh_counter;
-#endif
 
 atomic_t nmi_counter;
 
@@ -120,69 +116,31 @@
 #ifndef __SMP__
   static const unsigned int io_apic_irqs = 0;
 #else
-	/*
-	 * the timer interrupt is not connected to the IO-APIC on all boards
-	 * (mine is such ;), and since it is not performance critical anyway,
-	 * we route it through the INTA pin and win lots of design simplicity.
-	 * Ditto the obsolete EISA dma chaining irq. All other interrupts are
-	 * routed through the IO-APIC, distributed amongst all CPUs, dependent
-	 * on irq traffic and CPU load.
-	 */
-  const unsigned int io_apic_irqs = ~((1<<0)|(1<<2)|(1<<13));
+  /*
+   * Default to all normal IRQ's _not_ using the IO APIC.
+   *
+   * To get IO-APIC interrupts you should either:
+   *  - turn some of them into IO-APIC interrupts at runtime
+   *    with some magic system call interface.
+   *  - explicitly use irq 16-19 depending on which PCI irq
+   *    line your PCI controller uses.
+   */
+  unsigned int io_apic_irqs = 0xff0000;
 #endif
 
-static inline int ack_irq(int irq)
+static inline void mask_8259A(int irq)
 {
-	/*
-	 * The IO-APIC part will be moved to assembly, nested
-	 * interrupts will be ~5 instructions from entry to iret ...
-	 */
-	int should_handle_irq = 0;
-	int cpu = smp_processor_id();
-
-	/*
-	 * We always call this with local irqs disabled
-	 */
-	spin_lock(&irq_controller_lock);
-
-	if (!irq_events[irq]++ && !disabled_irq[irq]) {
-		should_handle_irq = 1;
-#ifdef __SMP__
-		irq_owner[irq] = cpu;
-#endif
-		hardirq_enter(cpu);
-	}
-
-	if (IO_APIC_IRQ(irq))
-		ack_APIC_irq ();
-	else {
-	/*
-	 * 8259-triggered INTA-cycle interrupt
-	 */
-		if (should_handle_irq)
-			mask_irq(irq);
-			
-		if (irq & 8) {
-			inb(0xA1);	/* DUMMY */
-			outb(0x62,0x20);	/* Specific EOI to cascade */
-			outb(0x20,0xA0);
-		} else {
-			inb(0x21);	/* DUMMY */
-			outb(0x20,0x20);
-		}
+	cached_irq_mask |= 1 << irq;
+	if (irq & 8) {
+		outb(cached_A1,0xA1);
+	} else {
+		outb(cached_21,0x21);
 	}
-
-	spin_unlock(&irq_controller_lock);
-
-	return (should_handle_irq);
 }
 
-void set_8259A_irq_mask(int irq)
+static inline void unmask_8259A(int irq)
 {
-	if (irq >= 16) {
-		printk ("HUH #3 (%d)?\n", irq);
-		return;
-	}
+	cached_irq_mask &= ~(1 << irq);
 	if (irq & 8) {
 		outb(cached_A1,0xA1);
 	} else {
@@ -190,6 +148,21 @@
 	}
 }
 
+void set_8259A_irq_mask(int irq)
+{
+	/*
+	 * (it might happen that we see IRQ>15 on a UP box, with SMP
+	 * emulation)
+	 */
+	if (irq < 16) {
+		if (irq & 8) {
+			outb(cached_A1,0xA1);
+		} else {
+			outb(cached_21,0x21);
+		}
+	}
+}
+
 /*
  * These have to be protected by the spinlock
  * before being called.
@@ -356,12 +329,13 @@
 			continue;
 		p += sprintf(p, "%3d: ",i);
 #ifndef __SMP__
-		p += sprintf(p, "%10u ", kstat.interrupts[0][i]);
+		p += sprintf(p, "%10u ", kstat_irqs(i));
 #else
 		for (j=0; j<smp_num_cpus; j++)
 			p += sprintf(p, "%10u ",
-				kstat.interrupts[cpu_logical_map[j]][i]);
+				kstat.irqs[cpu_logical_map(j)][i]);
 #endif
+
 		if (IO_APIC_IRQ(i))
 			p += sprintf(p, " IO-APIC ");
 		else
@@ -389,8 +363,8 @@
 unsigned volatile int global_irq_lock;
 atomic_t global_irq_count;
 
-#define irq_active(cpu) \
-	(global_irq_count != local_irq_count[cpu])
+atomic_t global_bh_count;
+atomic_t global_bh_lock;
 
 /*
  * "global_cli()" is a special case, in that it can hold the
@@ -408,35 +382,56 @@
 	}
 }
 
-static unsigned long previous_irqholder;
+static void show(char * str)
+{
+	int i;
+	unsigned long *stack;
+	int cpu = smp_processor_id();
 
-static inline void wait_on_irq(int cpu, unsigned long where)
+	printk("\n%s, CPU %d:\n", str, cpu);
+	printk("irq:  %d [%d %d]\n",
+		atomic_read(&global_irq_count), local_irq_count[0], local_irq_count[1]);
+	printk("bh:   %d [%d %d]\n",
+		atomic_read(&global_bh_count), local_bh_count[0], local_bh_count[1]);
+	stack = (unsigned long *) &str;
+	for (i = 40; i ; i--) {
+		unsigned long x = *++stack;
+		if (x > (unsigned long) &init_task_union && x < (unsigned long) &vsprintf) {
+			printk("<[%08lx]> ", x);
+		}
+	}
+}
+	
+
+#define MAXCOUNT 100000000
+
+static inline void wait_on_bh(void)
 {
-	int local_count = local_irq_count[cpu];
+	int count = MAXCOUNT;
+	do {
+		if (!--count) {
+			show("wait_on_bh");
+			count = ~0;
+		}
+		/* nothing .. wait for the other bh's to go away */
+	} while (atomic_read(&global_bh_count) != 0);
+}
+
+static inline void wait_on_irq(int cpu)
+{
+	int count = MAXCOUNT;
+
+	while (atomic_read(&global_irq_count)) {
+		clear_bit(0,&global_irq_lock);
 
-	/* Are we the only one in an interrupt context? */
-	while (local_count != atomic_read(&global_irq_count)) {
-		/*
-		 * No such luck. Now we need to release the lock,
-		 * _and_ release our interrupt context, because
-		 * otherwise we'd have dead-locks and live-locks
-		 * and other fun things.
-		 */
-		atomic_sub(local_count, &global_irq_count);
-		global_irq_holder = NO_PROC_ID;
-		global_irq_lock = 0;
-
-		/*
-		 * Wait for everybody else to go away and release
-		 * their things before trying to get the lock again.
-		 */
 		for (;;) {
-			atomic_add(local_count, &global_irq_count);
+			if (!--count) {
+				show("wait_on_irq");
+				count = ~0;
+			}
 			__sti();
 			SYNC_OTHER_CORES(cpu);
 			__cli();
-			atomic_sub(local_count, &global_irq_count);
-			SYNC_OTHER_CORES(cpu);
 			check_smp_invalidate(cpu);
 			if (atomic_read(&global_irq_count))
 				continue;
@@ -445,8 +440,24 @@
 			if (!test_and_set_bit(0,&global_irq_lock))
 				break;
 		}
-		atomic_add(local_count, &global_irq_count);
-		global_irq_holder = cpu;
+	}
+}
+
+/*
+ * This is called when we want to synchronize with
+ * bottom half handlers. We need to wait until
+ * no other CPU is executing any bottom half handler.
+ *
+ * Don't wait if we're already running in an interrupt
+ * context or are inside a bh handler.
+ */
+void synchronize_bh(void)
+{
+	if (atomic_read(&global_bh_count)) {
+		int cpu = smp_processor_id();
+		if (!local_irq_count[cpu] && !local_bh_count[cpu]) {
+			wait_on_bh();
+		}
 	}
 }
 
@@ -456,37 +467,15 @@
  * stop sending interrupts: but to make sure there
  * are no interrupts that are executing on another
  * CPU we need to call this function.
- *
- * We have to give pending interrupts a chance to
- * arrive (ie. let them get until hard_irq_enter()),
- * even if they are arriving to another CPU.
- *
- * On UP this is a no-op.
- *
- * UPDATE: this method is not quite safe, as it wont
- * catch irq handlers polling for the irq lock bit
- * in __global_cli():get_interrupt_lock():wait_on_irq().
- * drivers should rather use disable_irq()/enable_irq()
- * and/or synchronize_one_irq()
  */
 void synchronize_irq(void)
 {
-	int local_count = local_irq_count[smp_processor_id()];
-
-	if (local_count != atomic_read(&global_irq_count)) {
-		int i;
-
-		/* The very stupid way to do this */
-		for (i=0; i<NR_IRQS; i++) {
-			disable_irq(i);
-			enable_irq(i);
-		}
-		cli();
-		sti();
-	}
+	/* Stupid approach */
+	cli();
+	sti();
 }
 
-static inline void get_irqlock(int cpu, unsigned long where)
+static inline void get_irqlock(int cpu)
 {
 	if (test_and_set_bit(0,&global_irq_lock)) {
 		/* do we already hold the lock? */
@@ -499,34 +488,40 @@
 			} while (test_bit(0,&global_irq_lock));
 		} while (test_and_set_bit(0,&global_irq_lock));		
 	}
-	/*
-	 * Ok, we got the lock bit.
-	 * But that's actually just the easy part.. Now
-	 * we need to make sure that nobody else is running
+	/* 
+	 * We also to make sure that nobody else is running
 	 * in an interrupt context. 
 	 */
-	wait_on_irq(cpu, where);
+	wait_on_irq(cpu);
 
 	/*
-	 * Finally.
+	 * Ok, finally..
 	 */
 	global_irq_holder = cpu;
-	previous_irqholder = where;
 }
 
+/*
+ * A global "cli()" while in an interrupt context
+ * turns into just a local cli(). Interrupts
+ * should use spinlocks for the (very unlikely)
+ * case that they ever want to protect against
+ * each other.
+ */
 void __global_cli(void)
 {
 	int cpu = smp_processor_id();
-	unsigned long where;
 
-	__asm__("movl 16(%%esp),%0":"=r" (where));
 	__cli();
-	get_irqlock(cpu, where);
+	if (!local_irq_count[cpu])
+		get_irqlock(cpu);
 }
 
 void __global_sti(void)
 {
-	release_irqlock(smp_processor_id());
+	int cpu = smp_processor_id();
+
+	if (!local_irq_count[cpu])
+		release_irqlock(cpu);
 	__sti();
 }
 
@@ -539,8 +534,7 @@
 {
 	switch (flags) {
 	case 0:
-		release_irqlock(smp_processor_id());
-		__sti();
+		__global_sti();
 		break;
 	case 1:
 		__global_cli();
@@ -551,60 +545,21 @@
 	}
 }
 
-void synchronize_one_irq(unsigned int irq)
-{
-	int cpu = smp_processor_id(), owner;
-	int local_count = local_irq_count[cpu];
-	unsigned long flags;
-
-	__save_flags(flags);
-	__cli();
-	release_irqlock(cpu);
-	atomic_sub(local_count, &global_irq_count);
-
-repeat:	
-	spin_lock(&irq_controller_lock);
-	owner = irq_owner[irq];
-	spin_unlock(&irq_controller_lock);
-
-	if ((owner != NO_PROC_ID) && (owner != cpu)) {
-		atomic_add(local_count, &global_irq_count);
-		__sti();
-		SYNC_OTHER_CORES(cpu);
-		__cli();
-		atomic_sub(local_count, &global_irq_count);
-		SYNC_OTHER_CORES(cpu);
-		goto repeat;
-	}
-
-	if (!disabled_irq[irq])
-		printk("\n...WHAT??.#1...\n");
-
-	atomic_add(local_count, &global_irq_count);
-	__restore_flags(flags);
-}
-
 #endif
 
-static void handle_IRQ_event(int irq, struct pt_regs * regs)
+static int handle_IRQ_event(int irq, struct pt_regs * regs)
 {
 	struct irqaction * action;
-	int status, cpu = smp_processor_id();
-
-again:
-#ifdef __SMP__
-	while (test_bit(0,&global_irq_lock)) mb();
-#endif
+	int status;
 
-	kstat.interrupts[cpu][irq]++;
 	status = 0;
 	action = *(irq + irq_action);
 
 	if (action) {
-#if 0
+		status |= 1;
+
 		if (!(action->flags & SA_INTERRUPT))
 			__sti();
-#endif
 
 		do {
 			status |= action->flags;
@@ -616,23 +571,7 @@
 		__cli();
 	}
 
-	spin_lock(&irq_controller_lock);
-
-#ifdef __SMP__
-	release_irqlock(cpu);
-#endif
-
-	if ((--irq_events[irq]) && (!disabled_irq[irq])) {
-		spin_unlock(&irq_controller_lock);
-		goto again;
-	}
-#ifdef __SMP__
-	/* FIXME: move this into hardirq.h */
-	irq_owner[irq] = NO_PROC_ID;
-#endif
-	hardirq_exit(cpu);
-
-	spin_unlock(&irq_controller_lock);
+	return status;
 }
 
 
@@ -642,94 +581,103 @@
  */
 void disable_irq(unsigned int irq)
 {
-#ifdef __SMP__
-	int cpu = smp_processor_id();
-#endif
-	unsigned long f, flags;
-
-	save_flags(flags);
-	__save_flags(f);
-	__cli();
-	spin_lock(&irq_controller_lock);
+	unsigned long flags;
 
+	spin_lock_irqsave(&irq_controller_lock, flags);
 	disabled_irq[irq]++;
+	mask_irq(irq);
+	spin_unlock_irqrestore(&irq_controller_lock, flags);
 
-#ifdef __SMP__
-	/*
-	 * We have to wait for all irq handlers belonging to this IRQ
-	 * vector to finish executing.
-	 */
-	if ((irq_owner[irq] == NO_PROC_ID) || (irq_owner[irq] == cpu) ||
-		(disabled_irq[irq] > 1)) {
-
-		spin_unlock(&irq_controller_lock);
-		__restore_flags(f);
-		restore_flags(flags);
-		if (disabled_irq[irq] > 100)
-			printk("disable_irq(%d), infinit recursion!\n",irq);
-		return;
-	}
-#endif
-
-	spin_unlock(&irq_controller_lock);
-
-#ifdef __SMP__
-	synchronize_one_irq(irq);
-#endif
-
-	__restore_flags(f);
-	restore_flags(flags);
+	synchronize_irq();
 }
 
 void enable_irq(unsigned int irq)
 {
 	unsigned long flags;
-	int cpu = smp_processor_id();
 
-	spin_lock_irqsave(&irq_controller_lock,flags);
+	spin_lock_irqsave(&irq_controller_lock, flags);
+	disabled_irq[irq]--;
+	unmask_irq(irq);
+	spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
 
-	if (!disabled_irq[irq]) {
-		spin_unlock_irqrestore(&irq_controller_lock,flags);
-		printk("more enable_irq(%d)'s than disable_irq(%d)'s!!",irq,irq);
-		return;
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+static inline void mask_and_ack_8259A(int irq_nr)
+{
+	spin_lock(&irq_controller_lock);
+	cached_irq_mask |= 1 << irq_nr;
+	if (irq_nr & 8) {
+		inb(0xA1);	/* DUMMY */
+		outb(cached_A1,0xA1);
+		outb(0x62,0x20);	/* Specific EOI to cascade */
+		outb(0x20,0xA0);
+	} else {
+		inb(0x21);	/* DUMMY */
+		outb(cached_21,0x21);
+		outb(0x20,0x20);
 	}
+	spin_unlock(&irq_controller_lock);
+}
 
-	disabled_irq[irq]--;
+static void do_8259A_IRQ(int irq, int cpu, struct pt_regs * regs)
+{
+	mask_and_ack_8259A(irq);
 
-#ifndef __SMP__
-	if (disabled_irq[irq]) {
-		spin_unlock_irqrestore(&irq_controller_lock,flags);
-		return;
-	}
-#else
-	if (disabled_irq[irq] || (irq_owner[irq] != NO_PROC_ID)) {
-		spin_unlock_irqrestore(&irq_controller_lock,flags);
-		return;
+	irq_enter(cpu, irq);
+
+	if (handle_IRQ_event(irq, regs)) {
+		spin_lock(&irq_controller_lock);
+		unmask_8259A(irq);
+		spin_unlock(&irq_controller_lock);
 	}
-#endif
 
-	/*
-	 * Nobody is executing this irq handler currently, lets check
-	 * wether we have outstanding events to be handled.
-	 */
+	irq_exit(cpu, irq);
+}
 
-	if (irq_events[irq]) {
-		struct pt_regs regs;
+/*
+ * FIXME! This is completely broken.
+ */
+static void do_ioapic_IRQ(int irq, int cpu, struct pt_regs * regs)
+{
+	int should_handle_irq;
 
-#ifdef __SMP__
+	spin_lock(&irq_controller_lock);
+	should_handle_irq = 0;
+	if (!irq_events[irq]++ && !disabled_irq[irq]) {
+		should_handle_irq = 1;
 		irq_owner[irq] = cpu;
-#endif
 		hardirq_enter(cpu);
-#ifdef __SMP__
-		release_irqlock(cpu);
-#endif
-		spin_unlock(&irq_controller_lock);
+	}
+
+	ack_APIC_irq();
+
+	spin_unlock(&irq_controller_lock);
+	
+	if (should_handle_irq) {
+again:
+		if (!handle_IRQ_event(irq, regs))
+			disabled_irq[irq] = 1;
 
-		handle_IRQ_event(irq,&regs);
-		__restore_flags(flags);
-		return;
 	}
-	spin_unlock_irqrestore(&irq_controller_lock,flags);
+
+	spin_lock(&irq_controller_lock);
+	release_irqlock(cpu);
+
+	if ((--irq_events[irq]) && (!disabled_irq[irq]) && should_handle_irq) {
+		spin_unlock(&irq_controller_lock);
+		goto again;
+	}
+
+	irq_owner[irq] = NO_PROC_ID;
+	hardirq_exit(cpu);
+	spin_unlock(&irq_controller_lock);
+
+	enable_IO_APIC_irq(irq);
 }
 
 /*
@@ -747,7 +695,9 @@
  * overlapping ... i saw no driver problem so far.
  */
 asmlinkage void do_IRQ(struct pt_regs regs)
-{
+{	
+	void (*do_lowlevel_IRQ)(int, int, struct pt_regs *);
+
 	/* 
 	 * We ack quickly, we don't want the irq controller
 	 * thinking we're snobs just because some other CPU has
@@ -759,16 +709,15 @@
 	 * handled by some other CPU. (or is disabled)
 	 */
 	int irq = regs.orig_eax & 0xff;
+	int cpu = smp_processor_id();
 
-/*
-	printk("<%d>",irq);
- */
-	if (!ack_irq(irq))
-		return;
-
-	handle_IRQ_event(irq,&regs);
+	kstat.irqs[cpu][irq]++;
 
-	unmask_irq(irq);
+	do_lowlevel_IRQ = do_8259A_IRQ;
+	if (IO_APIC_IRQ(irq))
+		do_lowlevel_IRQ = do_ioapic_IRQ;
+	
+	do_lowlevel_IRQ(irq, cpu, &regs);
 
 	/*
 	 * This should be conditional: we should really get
@@ -897,7 +846,7 @@
 	/*
 	 * save current irq counts
 	 */
-	memcpy(probe_irqs,kstat.interrupts,NR_CPUS*NR_IRQS*sizeof(int));
+	memcpy(probe_irqs,kstat.irqs,NR_CPUS*NR_IRQS*sizeof(int));
 
 	/*
 	 * first, enable any unassigned irqs
@@ -922,7 +871,7 @@
 	 */
 	for (i=0; i<NR_IRQS; i++)
 		for (j=0; j<NR_CPUS; j++)
-			if (kstat.interrupts[j][i] != probe_irqs[j][i])
+			if (kstat.irqs[j][i] != probe_irqs[j][i])
 				irqs &= ~(i<<1);
 
 	return irqs;
@@ -935,7 +884,7 @@
 	for (i=0; i<NR_IRQS; i++) {
 		int sum = 0;
 		for (j=0; j<NR_CPUS; j++) {
-			sum += kstat.interrupts[j][i];
+			sum += kstat.irqs[j][i];
 			sum -= probe_irqs[j][i];
 		}
 		if (sum && (irqs & (i<<1))) {
diff -u --recursive --new-file v2.1.80/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.1.80/linux/arch/i386/kernel/irq.h	Tue Jan 20 16:35:18 1998
+++ linux/arch/i386/kernel/irq.h	Fri Jan 23 16:21:16 1998
@@ -19,7 +19,12 @@
 void setup_IO_APIC (void);
 void init_IO_APIC_traps(void);
 
-extern const unsigned int io_apic_irqs;
+#ifdef __SMP__
+ extern unsigned int io_apic_irqs;
+#else
+ extern const unsigned int io_apic_irqs;
+#endif
+
 #define IO_APIC_IRQ(x) ((1<<x) & io_apic_irqs)
 
 #define MAX_IRQ_SOURCES 128
@@ -36,6 +41,8 @@
 					*/
 
 #ifdef __SMP__
+
+#include <asm/atomic.h>
 
 static inline void irq_enter(int cpu, int irq)
 {
diff -u --recursive --new-file v2.1.80/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.1.80/linux/arch/i386/kernel/smp.c	Tue Jan 20 12:52:09 1998
+++ linux/arch/i386/kernel/smp.c	Wed Jan 21 12:04:45 1998
@@ -115,7 +115,7 @@
 int smp_num_cpus = 1;					/* Total count of live CPU's 				*/
 int smp_threads_ready=0;				/* Set when the idlers are all forked 			*/
 volatile int cpu_number_map[NR_CPUS];			/* which CPU maps to which logical number		*/
-volatile int cpu_logical_map[NR_CPUS];			/* which logical number maps to which CPU		*/
+volatile int __cpu_logical_map[NR_CPUS];			/* which logical number maps to which CPU		*/
 volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};	/* We always use 0 the rest is ready for parallel delivery */
 volatile unsigned long smp_invalidate_needed;		/* Used for the invalidate map that's also checked in the spinlock */
 volatile unsigned long kstack_ptr;			/* Stack vector for booting CPU's			*/
@@ -526,7 +526,7 @@
 				 *	set some other information about it.
 				 */
 				nlong = boot_cpu_id<<24;	/* Dummy 'self' for bootup */
-				cpu_logical_map[0] = boot_cpu_id;
+				__cpu_logical_map[0] = boot_cpu_id;
 				global_irq_holder = boot_cpu_id;
 				current->processor = boot_cpu_id;
 
@@ -717,7 +717,7 @@
 		panic("No idle process for CPU %d", i);
 
 	idle->processor = i;
-	cpu_logical_map[cpucount] = i;
+	__cpu_logical_map[cpucount] = i;
 	cpu_number_map[i] = cpucount;
 
 	/* start_eip had better be page-aligned! */
@@ -861,7 +861,7 @@
 			/* number CPUs logically, starting from 1 (BSP is 0) */
 #if 0
 			cpu_number_map[i] = cpucount;
-			cpu_logical_map[cpucount] = i;
+			__cpu_logical_map[cpucount] = i;
 #endif
 			printk("OK.\n");
 			printk("CPU%d: ", i);
@@ -927,6 +927,7 @@
 	if (!smp_found_config)
 	{
 		printk(KERN_NOTICE "SMP motherboard not detected. Using dummy APIC emulation.\n");
+		io_apic_irqs = 0;
 		return;
 	}
 
@@ -1087,6 +1088,12 @@
 	if(smp_b_stepping)
 		printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
 	SMP_PRINTK(("Boot done.\n"));
+
+	/*
+	 * Here we can be sure that there is an IO-APIC in the system, lets
+	 * go and set it up:
+	 */
+	setup_IO_APIC();
 }
 
 /*
diff -u --recursive --new-file v2.1.80/linux/arch/i386/lib/usercopy.c linux/arch/i386/lib/usercopy.c
--- v2.1.80/linux/arch/i386/lib/usercopy.c	Sat Jan 10 21:28:41 1998
+++ linux/arch/i386/lib/usercopy.c	Fri Jan 23 16:34:36 1998
@@ -89,7 +89,7 @@
 		"	.long 0b,3b\n"					\
 		"	.long 1b,2b\n"					\
 		".previous"						\
-		: "=c"(size)						\
+		: "=&c"(size)						\
 		: "r"(size & 3), "0"(size / 4), "D"(addr), "a"(0)	\
 		: "di")
 
diff -u --recursive --new-file v2.1.80/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.1.80/linux/drivers/block/floppy.c	Mon Jan 12 14:57:50 1998
+++ linux/drivers/block/floppy.c	Fri Jan 23 11:07:07 1998
@@ -1710,10 +1710,11 @@
 		} while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
 	}
 	if (handler) {
-		if(softirq_trylock()) {
+		int cpu = smp_processor_id();
+		if(softirq_trylock(cpu)) {
 			/* got the lock, call the handler immediately */
 			handler();
-			softirq_endlock();
+			softirq_endlock(cpu);
 		} else
 			/* we interrupted a bottom half. Defer handler */
 			schedule_bh( (void *)(void *) handler);
diff -u --recursive --new-file v2.1.80/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.1.80/linux/drivers/block/genhd.c	Sun Jan  4 10:40:15 1998
+++ linux/drivers/block/genhd.c	Fri Jan 23 17:38:04 1998
@@ -776,7 +776,9 @@
 	int blk, blocks_in_map;
 	int dev_bsize, dev_pos, pos;
 	unsigned secsize;
+#ifdef CONFIG_PMAC
 	int first_bootable = 1;
+#endif
 	struct mac_partition *part;
 	struct mac_driver_desc *md;
 
diff -u --recursive --new-file v2.1.80/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.1.80/linux/drivers/block/md.c	Thu Jan 15 14:33:05 1998
+++ linux/drivers/block/md.c	Fri Jan 23 17:38:04 1998
@@ -493,7 +493,7 @@
 		/*
 		 * ioctl : one open channel
 		 */
-		printk ("STOP_MD md%x failed : i_count=%ld, busy=%d\n",
+		printk ("STOP_MD md%x failed : i_count=%d, busy=%d\n",
 				minor, inode->i_count, md_dev[minor].busy);
 		return -EBUSY;
 	}
@@ -846,6 +846,7 @@
 static struct proc_dir_entry proc_md = {
 	PROC_MD, 6, "mdstat",
 	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, &proc_array_inode_operations,
 };
 
 static void md_geninit (struct gendisk *gdisk)
diff -u --recursive --new-file v2.1.80/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.1.80/linux/drivers/block/ps2esdi.c	Tue May 13 22:41:05 1997
+++ linux/drivers/block/ps2esdi.c	Fri Jan 23 17:38:04 1998
@@ -1038,14 +1038,9 @@
 }
 
 
-
 static int ps2esdi_open(struct inode *inode, struct file *file)
 {
-	int dev = DEVICE_NR(MINOR(inode->i_rdev));
-
-#if 0
-	printk("%s: dev= %d\n", DEVICE_NAME, dev);
-#endif
+	int dev = DEVICE_NR(inode->i_rdev);
 
 	if (dev < ps2esdi_drives) {
 		while (!ps2esdi_valid[dev])
@@ -1062,7 +1057,7 @@
 
 static int ps2esdi_release(struct inode *inode, struct file *file)
 {
-	int dev = DEVICE_NR(MINOR(inode->i_rdev));
+	int dev = DEVICE_NR(inode->i_rdev);
 
 	if (dev < ps2esdi_drives) {
 		sync_dev(dev);
@@ -1078,7 +1073,7 @@
 {
 
 	struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
-	int dev = DEVICE_NR(MINOR(inode->i_rdev)), err;
+	int dev = DEVICE_NR(inode->i_rdev), err;
 
 	if (inode && (dev < ps2esdi_drives))
 		switch (cmd) {
@@ -1133,7 +1128,7 @@
 
 static int ps2esdi_reread_partitions(int dev)
 {
-	int target = DEVICE_NR(MINOR(dev));
+	int target = DEVICE_NR(dev);
 	int start = target << ps2esdi_gendisk.minor_shift;
 	int partition;
 
@@ -1145,15 +1140,20 @@
 
 	for (partition = ps2esdi_gendisk.max_p - 1;
 	     partition >= 0; partition--) {
-		sync_dev(MAJOR_NR << 8 | start | partition);
-		invalidate_inodes(MAJOR_NR << 8 | start | partition);
-		invalidate_buffers(MAJOR_NR << 8 | start | partition);
+		int minor = (start | partition);
+		kdev_t devp = MKDEV(MAJOR_NR, minor);
+		struct super_block * sb = get_super(devp);
+		
+		sync_dev(devp);
+		if (sb)
+			invalidate_inodes(sb);
+		invalidate_buffers(devp);
 		ps2esdi_gendisk.part[start + partition].start_sect = 0;
 		ps2esdi_gendisk.part[start + partition].nr_sects = 0;
-	};
+	}
 
 	ps2esdi_gendisk.part[start].nr_sects = ps2esdi_info[target].head *
-	    ps2esdi_info[target].cyl * ps2esdi_info[target].sect;
+		ps2esdi_info[target].cyl * ps2esdi_info[target].sect;
 	resetup_one_dev(&ps2esdi_gendisk, target);
 
 	ps2esdi_valid[target] = 1;
diff -u --recursive --new-file v2.1.80/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v2.1.80/linux/drivers/cdrom/cdu31a.c	Mon Jan  5 00:06:26 1998
+++ linux/drivers/cdrom/cdu31a.c	Fri Jan 23 17:38:04 1998
@@ -1242,6 +1242,7 @@
    buf[2] = size % 256;
 }
 
+#if 0
 /* Uniform cdrom interface function.
    Return the status of the current disc:
    If it is recognized as CD-I -> return XA Mode 2 Form 2
@@ -1268,6 +1269,7 @@
   } else 
     return CDS_NO_INFO;
 }
+#endif
 
 /* Starts a read operation. Returns 0 on success and 1 on failure. 
    The read operation used here allows multiple sequential sectors 
diff -u --recursive --new-file v2.1.80/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.1.80/linux/drivers/char/bttv.c	Thu Jan 15 14:33:05 1998
+++ linux/drivers/char/bttv.c	Fri Jan 23 16:41:00 1998
@@ -129,16 +129,22 @@
 	btwrite(BT848_INT_I2CDONE, BT848_INT_STAT);
   
 	btwrite(((addr & 0xff) << 24) | I2C_COMMAND, BT848_I2C);
-  
-	for (i=0x7fffffff; i; i--)
+
+	/*
+	 * Timeout for I2CRead is 1 second (this should be enough, really!)
+	 */
+	for (i=1000; i; i--)
 	{
 		stat=btread(BT848_INT_STAT);
 		if (stat & BT848_INT_I2CDONE)
 			break;
+		udelay(1000); /* 1ms, as I2C is 1kHz (?) */
 	}
   
-	if (!i)
+	if (!i) {
+		printk(KERN_DEBUG "bttv: I2CRead timeout\n");
 		return -1;
+	}
 	if (!(stat & BT848_INT_RACK))
 		return -2;
   
@@ -167,15 +173,18 @@
   
 	btwrite(data, BT848_I2C);
 
-	for (i=0x7fffffff; i; i--)
+	for (i=1000; i; i--)
 	{
 		stat=btread(BT848_INT_STAT);
 		if (stat & BT848_INT_I2CDONE)
 			break;
+		udelay(1000);
 	}
   
-	if (!i)
+	if (!i) {
+		printk(KERN_DEBUG "bttv: I2CWrite timeout\n");
 		return -1;
+	}
 	if (!(stat & BT848_INT_RACK))
 		return -2;
   
@@ -772,7 +781,7 @@
 	/*
 	 *	32bit depth frame buffers need extra flags setting
 	 */
-	 
+
 	if (depth==4)
 		mask=BT848_RISC_BYTE3;
 	else
@@ -1093,13 +1102,13 @@
 		case VIDIOCGPICT:
 		{
 			struct video_picture p=btv->picture;
-			if(btv->win.bpp==8)
+			if(btv->win.bpp==1)
 				p.palette=VIDEO_PALETTE_HI240;
-			if(btv->win.bpp==16)
+			if(btv->win.bpp==2)
 				p.palette=VIDEO_PALETTE_RGB565;
-			if(btv->win.bpp==24)
+			if(btv->win.bpp==3)
 				p.palette=VIDEO_PALETTE_RGB24;
-			if(btv->win.bpp==32)
+			if(btv->win.bpp==4)
 				p.palette=VIDEO_PALETTE_RGB32;
 			if(copy_to_user(arg, &p, sizeof(p)))
 				return -EFAULT;
diff -u --recursive --new-file v2.1.80/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c
--- v2.1.80/linux/drivers/char/busmouse.c	Mon Nov  3 15:14:20 1997
+++ linux/drivers/char/busmouse.c	Fri Jan 23 17:38:04 1998
@@ -109,7 +109,6 @@
 static int fasync_mouse(struct file *filp, int on)
 {
 	int retval;
-	struct inode *inode = filp->f_dentry->d_inode;
 
 	retval = fasync_helper(filp, on, &mouse.fasyncptr);
 	if (retval < 0)
diff -u --recursive --new-file v2.1.80/linux/drivers/char/bw-qcam.c linux/drivers/char/bw-qcam.c
--- v2.1.80/linux/drivers/char/bw-qcam.c	Mon Jan 12 14:46:16 1998
+++ linux/drivers/char/bw-qcam.c	Fri Jan 23 17:38:04 1998
@@ -923,11 +923,12 @@
 		close_bwqcam(qcams[i]);
 }
 #else
-__initfunc(int init_bwqcams(struct video_init *unused))
+__initfunc(int init_bw_qcams(struct video_init *unused))
 {
 	struct parport *port;
 
 	for (port = parport_enumerate(); port; port=port->next)
 		init_bwqcam(port);
+	return 0;
 }
 #endif
diff -u --recursive --new-file v2.1.80/linux/drivers/char/c-qcam.c linux/drivers/char/c-qcam.c
--- v2.1.80/linux/drivers/char/c-qcam.c	Mon Jan 12 14:46:16 1998
+++ linux/drivers/char/c-qcam.c	Fri Jan 23 17:38:04 1998
@@ -771,5 +771,6 @@
 
 	for (port = parport_enumerate(); port; port=port->next)
 		init_cqcam(port);
+	return 0;
 }
 #endif
diff -u --recursive --new-file v2.1.80/linux/drivers/char/ftape/lowlevel/fdc-io.c linux/drivers/char/ftape/lowlevel/fdc-io.c
--- v2.1.80/linux/drivers/char/ftape/lowlevel/fdc-io.c	Tue Dec  2 09:33:16 1997
+++ linux/drivers/char/ftape/lowlevel/fdc-io.c	Fri Jan 23 17:38:04 1998
@@ -385,7 +385,7 @@
 int fdc_interrupt_wait(unsigned int time)
 {
 	struct wait_queue wait = {current, NULL};
-	int current_blocked = current->blocked;
+	sigset_t old_sigmask;	
 	static int resetting = 0;
 	TRACE_FUN(ft_t_fdc_dma);
 
@@ -401,14 +401,23 @@
 	/* timeout time will be up to USPT microseconds too long ! */
 	current->timeout = jiffies + (1000 * time + FT_USPT - 1) / FT_USPT;
 	current->state = TASK_INTERRUPTIBLE;
-	current->blocked = _BLOCK_ALL; /* isn't this already set by the
-					* high level routines?
-					*/
+
+	spin_lock_irq(&current->sigmask_lock);
+        old_sigmask = current->blocked;
+        siginitset(&current->blocked, _BLOCK_ALL);
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->sigmask_lock);
+
 	add_wait_queue(&ftape_wait_intr, &wait);
 	while (!ft_interrupt_seen && current->state != TASK_RUNNING) {
 		schedule();	/* sets TASK_RUNNING on timeout */
         }
-	current->blocked = current_blocked;	/* restore */
+
+	spin_lock_irq(&current->sigmask_lock);
+        current->blocked = old_sigmask;
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->sigmask_lock);
+	
 	remove_wait_queue(&ftape_wait_intr, &wait);
 	/*  the following IS necessary. True: as well
 	 *  wake_up_interruptible() as the schedule() set TASK_RUNNING
diff -u --recursive --new-file v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-ctl.c linux/drivers/char/ftape/lowlevel/ftape-ctl.c
--- v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-ctl.c	Tue Nov 25 14:45:27 1997
+++ linux/drivers/char/ftape/lowlevel/ftape-ctl.c	Fri Jan 23 17:38:04 1998
@@ -794,8 +794,8 @@
 			      i, *ft_buffer[i]->address);
 		}
 	}
-	if ((current->signal & _DONT_BLOCK) && 
-	    !(current->signal & _NEVER_BLOCK) &&
+	if (sigtestsetmask(&current->signal, _DONT_BLOCK) && 
+	    !(sigtestsetmask(&current->signal, _NEVER_BLOCK)) &&
 	    ftape_tape_running) {
 		TRACE(ft_t_warn,
 		      "Interrupted by fatal signal and tape still running");
diff -u --recursive --new-file v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-init.h linux/drivers/char/ftape/lowlevel/ftape-init.h
--- v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-init.h	Tue Nov 25 14:45:27 1997
+++ linux/drivers/char/ftape/lowlevel/ftape-init.h	Fri Jan 23 17:38:04 1998
@@ -32,12 +32,9 @@
 #include <linux/linkage.h>
 #include <linux/signal.h>
 
-#define _S(nr) (1<<((nr)-1))
-#define _NEVER_BLOCK    (_S(SIGKILL)|_S(SIGSTOP))
-#define _DONT_BLOCK     (_NEVER_BLOCK|_S(SIGINT))
-#define _DO_BLOCK       (_S(SIGPIPE))
-#define _BLOCK_ALL      (0xffffffffL)
-
+#define _NEVER_BLOCK    (sigmask(SIGKILL) | sigmask(SIGSTOP))
+#define _DONT_BLOCK     (_NEVER_BLOCK | sigmask(SIGINT))
+#define _DO_BLOCK       (sigmask(SIGPIPE))
 
 #ifndef QIC117_TAPE_MAJOR
 #define QIC117_TAPE_MAJOR 27
diff -u --recursive --new-file v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-rw.c linux/drivers/char/ftape/lowlevel/ftape-rw.c
--- v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-rw.c	Tue Nov 25 14:45:27 1997
+++ linux/drivers/char/ftape/lowlevel/ftape-rw.c	Fri Jan 23 17:38:04 1998
@@ -432,7 +432,8 @@
 			 */
 			result = ftape_ready_wait(ftape_timeout.pause,&status);
 		}
-	} while (ftape_tape_running && (current->signal & _NEVER_BLOCK) == 0);
+	} while (ftape_tape_running
+		 && !(sigtestsetmask(&current->signal, _NEVER_BLOCK)));
 #ifndef TESTING
 	ft_location.known = 0;
 #endif
@@ -660,7 +661,7 @@
 		 *  to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!!
 		 */
 		if (ftape_read_id() < 0 || !ft_location.known ||
-		    (current->signal & _DONT_BLOCK)) {
+		    sigtestsetmask(&current->signal, _DONT_BLOCK)) {
 			ft_location.known = 0;
 			if (!ftape_tape_running ||
 			    ++failures > FT_SECTORS_PER_SEGMENT) {
@@ -775,7 +776,7 @@
 		fast_seek(count, 1);
 		logical_forward();
 		if (ftape_read_id() < 0 || !ft_location.known ||
-		    (current->signal & _DONT_BLOCK)) {
+		    (sigtestsetmask(&current->signal, _DONT_BLOCK))) {
 			if ((!ftape_tape_running && !ft_location.known) ||
 			    ++failures > FT_SECTORS_PER_SEGMENT) {
 				TRACE_ABORT(-EIO, ft_t_err,
@@ -1001,7 +1002,7 @@
 	while (result < 0     &&
 	       retry++ <= 5   &&
 	       !ft_failure &&
-	       (current->signal & _DONT_BLOCK) == 0) {
+	       !(sigtestsetmask(&current->signal, _DONT_BLOCK))) {
 		
 		if (retry && start_offset < 5) {
 			start_offset ++;
diff -u --recursive --new-file v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-tracing.h linux/drivers/char/ftape/lowlevel/ftape-tracing.h
--- v2.1.80/linux/drivers/char/ftape/lowlevel/ftape-tracing.h	Tue Nov 25 14:45:27 1997
+++ linux/drivers/char/ftape/lowlevel/ftape-tracing.h	Fri Jan 23 17:38:04 1998
@@ -171,7 +171,7 @@
  *  but rather into ftape-rw.h (maybe)
  */
 #define FT_SIGNAL_EXIT(sig_mask)					\
-	if (current->signal & (sig_mask)) {				\
+	if (sigtestsetmask(&current->signal, sig_mask)) {		\
 		TRACE_ABORT(-EINTR,					\
 			    ft_t_warn,					\
 			    "interrupted by non-blockable signal");	\
diff -u --recursive --new-file v2.1.80/linux/drivers/char/ftape/zftape/zftape-init.c linux/drivers/char/ftape/zftape/zftape-init.c
--- v2.1.80/linux/drivers/char/ftape/zftape/zftape-init.c	Tue Nov 25 14:45:28 1997
+++ linux/drivers/char/ftape/zftape/zftape-init.c	Fri Jan 23 17:38:04 1998
@@ -73,7 +73,7 @@
 /*      Local vars.
  */
 static int busy_flag = 0;
-static int orig_sigmask;
+static sigset_t orig_sigmask;
 
 /*  the interface to the kernel vfs layer
  */
@@ -171,7 +171,7 @@
 		TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr");
 	}
 	orig_sigmask = current->blocked;
-	current->blocked = _BLOCK_ALL;
+	sigfillset(&current->blocked);
 	result = _zft_open(MINOR(ino->i_rdev), filep->f_flags & O_ACCMODE);
 	if (result < 0) {
 		current->blocked = orig_sigmask; /* restore mask */
@@ -186,18 +186,15 @@
 		/* Mask signals that will disturb proper operation of the
 		 * program that is calling.
 		 */
-		current->blocked = orig_sigmask | _DO_BLOCK;
+		current->blocked = orig_sigmask;
+		sigaddsetmask (&current->blocked, _DO_BLOCK);
 		TRACE_EXIT 0;
 	}
 }
 
 /*      Close floppy tape device
  */
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,31)
 static int zft_close(struct inode *ino, struct file *filep)
-#else
-static void zft_close(struct inode *ino, struct file *filep)
-#endif
 {
 	int result;
 	TRACE_FUN(ft_t_flow);
@@ -210,7 +207,7 @@
 		TRACE_EXIT; /* keep busy_flag !(?) */
 #endif
 	}
-	current->blocked = _BLOCK_ALL;
+	sigfillset(&current->blocked);
 	result = _zft_close();
 	if (result < 0) {
 		TRACE(ft_t_err, "_zft_close failed");
@@ -235,7 +232,7 @@
 		     unsigned int command, unsigned long arg)
 {
 	int result = -EIO;
-	int old_sigmask;
+	sigset_t old_sigmask;
 	TRACE_FUN(ft_t_flow);
 
 	if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
@@ -243,7 +240,7 @@
 			    "failed: not busy, failure or wrong unit");
 	}
 	old_sigmask = current->blocked; /* save mask */
-	current->blocked = _BLOCK_ALL;
+	sigfillset(&current->blocked);
 	/* This will work as long as sizeof(void *) == sizeof(long) */
 	result = _zft_ioctl(command, (void *) arg);
 	current->blocked = old_sigmask; /* restore mask */
@@ -261,7 +258,7 @@
 #endif
 {
 	int result = -EIO;
-	int old_sigmask;
+	sigset_t old_sigmask;
 	TRACE_FUN(ft_t_flow);
 
 	if (!busy_flag || 
@@ -276,7 +273,7 @@
 			    "failed: not busy, failure or wrong unit");
 	}
 	old_sigmask = current->blocked; /* save mask */
-	current->blocked = _BLOCK_ALL;
+	sigfillset(&current->blocked);
 	if ((result = ftape_mmap(vma)) >= 0) {
 #ifndef MSYNC_BUG_WAS_FIXED
 		static struct vm_operations_struct dummy = { NULL, };
@@ -307,7 +304,7 @@
 #endif
 {
 	int result = -EIO;
-	int old_sigmask;
+	sigset_t old_sigmask;
 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60)
 	struct inode *ino = fp->f_dentry->d_inode;
 #endif
@@ -319,7 +316,7 @@
 			    "failed: not busy, failure or wrong unit");
 	}
 	old_sigmask = current->blocked; /* save mask */
-	current->blocked = _BLOCK_ALL;
+	sigfillset(&current->blocked);
 	result = _zft_read(buff, req_len);
 	current->blocked = old_sigmask; /* restore mask */
 	TRACE(ft_t_data_flow, "return with count: %d", result);
@@ -343,7 +340,7 @@
 #endif
 {
 	int result = -EIO;
-	int old_sigmask;
+	sigset_t old_sigmask;
 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60)
 	struct inode *ino = fp->f_dentry->d_inode;
 #endif
@@ -355,7 +352,7 @@
 			    "failed: not busy, failure or wrong unit");
 	}
 	old_sigmask = current->blocked; /* save mask */
-	current->blocked = _BLOCK_ALL;
+	sigfillset(&current->blocked);
 	result = _zft_write(buff, req_len);
 	current->blocked = old_sigmask; /* restore mask */
 	TRACE(ft_t_data_flow, "return with count: %d", result);
diff -u --recursive --new-file v2.1.80/linux/drivers/char/hfmodem/gentbl.c linux/drivers/char/hfmodem/gentbl.c
--- v2.1.80/linux/drivers/char/hfmodem/gentbl.c	Tue Aug  5 09:48:55 1997
+++ linux/drivers/char/hfmodem/gentbl.c	Wed Jan 21 15:34:19 1998
@@ -25,8 +25,8 @@
  */
 
 /*****************************************************************************/
-      
-#include <linux/hfmodem.h>
+
+/* This is compiled with HOSTCC - do not include any <linux/foo.h> headers. */
 #include <math.h>
 #include <stdio.h>
 
diff -u --recursive --new-file v2.1.80/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c
--- v2.1.80/linux/drivers/char/keyboard.c	Wed Dec  3 15:21:57 1997
+++ linux/drivers/char/keyboard.c	Wed Jan 21 14:27:21 1998
@@ -603,7 +603,7 @@
 static void do_pad(unsigned char value, char up_flag)
 {
 	static const char *pad_chars = "0123456789+-*/\015,.?()";
-	static const char *app_map = "pqrstuvwxylSRQMnn?PQ";
+	static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
 
 	if (up_flag)
 		return;		/* no action, if this is a key release */
diff -u --recursive --new-file v2.1.80/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.1.80/linux/drivers/char/mem.c	Mon Dec 22 08:42:36 1997
+++ linux/drivers/char/mem.c	Fri Jan 23 17:38:04 1998
@@ -30,10 +30,13 @@
 void soundcard_init(void);
 #endif
 #ifdef CONFIG_ISDN
-void isdn_init(void);
+int isdn_init(void);
 #endif
 #ifdef CONFIG_PCWATCHDOG
-void pcwatchdog_init(void);
+int pcwatchdog_init(void);
+#endif
+#ifdef CONFIG_VIDEO_DEV
+extern int videodev_init(void);
 #endif
 
 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
diff -u --recursive --new-file v2.1.80/linux/drivers/char/misc.c linux/drivers/char/misc.c
--- v2.1.80/linux/drivers/char/misc.c	Sat Nov 29 10:33:19 1997
+++ linux/drivers/char/misc.c	Fri Jan 23 17:38:04 1998
@@ -78,6 +78,9 @@
 extern int nvram_init(void);
 extern int radio_init(void);
 extern void hfmodem_init(void);
+#ifdef CONFIG_PC110_PAD
+extern int pc110pad_init(void);
+#endif
 
 #ifdef CONFIG_PROC_FS
 static int misc_read_proc(char *buf, char **start, off_t offset,
diff -u --recursive --new-file v2.1.80/linux/drivers/char/pms.c linux/drivers/char/pms.c
--- v2.1.80/linux/drivers/char/pms.c	Sun Jan  4 10:40:15 1998
+++ linux/drivers/char/pms.c	Fri Jan 23 17:38:04 1998
@@ -610,7 +610,7 @@
 {
 	int y;
 	int dw = 2*dev->width;
-	char *src = (char *)bus_to_virt((void *)mem_base);
+	char *src = (char *)bus_to_virt(mem_base);
 
 	char tmp[dw+32]; /* using a temp buffer is faster than direct  */
 	int cnt = 0;
diff -u --recursive --new-file v2.1.80/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- v2.1.80/linux/drivers/char/tpqic02.c	Sat Nov 29 10:33:19 1997
+++ linux/drivers/char/tpqic02.c	Fri Jan 23 17:38:04 1998
@@ -1766,8 +1766,10 @@
 
     if (TP_DIAGS(current_tape_dev))
       /* can't print a ``long long'' (for filp->f_pos), so chop it */
-      printk(TPQIC02_NAME ": request READ, minor=%x, buf=%p, count=%lx, pos=%lx, flags=%x\n",
-	     MINOR(dev), buf, count, (unsigned long) filp->f_pos, flags);
+      printk(TPQIC02_NAME ": request READ, minor=%x, buf=%p, count=%lx"
+	                  ", pos=%lx, flags=%x\n",
+	     MINOR(dev), buf, (long) count,
+	     (unsigned long) filp->f_pos, flags);
     
     if (count % TAPE_BLKSIZE)	/* Only allow mod 512 bytes at a time. */
     {
@@ -1980,8 +1982,10 @@
     if (TP_DIAGS(current_tape_dev))
     {
 	/* can't print a ``long long'' (for filp->f_pos), so chop it */
-	printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p, count=%lx, pos=%lx, flags=%x\n",
-	       MINOR(dev), buf, count, (unsigned long) filp->f_pos, flags);
+	printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p"
+	                    ", count=%lx, pos=%lx, flags=%x\n",
+	       MINOR(dev), buf,
+	       (long) count, (unsigned long) filp->f_pos, flags);
     }
     
     if (count % TAPE_BLKSIZE) 	/* only allow mod 512 bytes at a time */
@@ -2128,7 +2132,9 @@
     tpqputs(TPQD_ALWAYS, "write request for <0 bytes");
     if (TPQDBG(DEBUG))
     {
-	printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p, total_bytes_done %lx, count %lx\n", status_bytes_wr, buf, total_bytes_done, count);
+	printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p"
+	                    ", total_bytes_done %lx, count %lx\n",
+	       status_bytes_wr, buf, total_bytes_done, (long) count);
     }
     return -EINVAL;
 } /* qic02_tape_write */
@@ -2865,7 +2871,7 @@
     return 0;
 } /* qic02_get_resources */
 
-__initfunc(static int qic02_tape_init(void))
+__initfunc(int qic02_tape_init(void))
 {
     if (TPSTATSIZE != 6)
     {
diff -u --recursive --new-file v2.1.80/linux/drivers/char/videodev.c linux/drivers/char/videodev.c
--- v2.1.80/linux/drivers/char/videodev.c	Mon Jan 12 14:46:16 1998
+++ linux/drivers/char/videodev.c	Fri Jan 23 17:38:04 1998
@@ -36,17 +36,15 @@
  
 static struct video_device *video_device[VIDEO_NUM_DEVICES];
 
-/*
- *	Initialiser list
- */
- 
-struct video_init
-{
-	char *name;
-	int (*init)(struct video_init *);
-};
-
+#ifdef CONFIG_VIDEO_BT848
 extern int init_bttv_cards(struct video_init *);
+#endif
+#ifdef CONFIG_VIDEO_CQCAM
+extern int init_colour_qcams(struct video_init *);
+#endif
+#ifdef CONFIG_VIDEO_BWQCAM
+extern int init_bw_qcams(struct video_init *);
+#endif
 
 static struct video_init video_init_list[]={
 #ifdef CONFIG_VIDEO_BT848
@@ -59,7 +57,7 @@
 	{"bw-qcam", init_bw_qcams},
 #endif	
 #ifdef CONFIG_VIDEO_PMS
-	{"PMS", init_pms_cards},
+	{"PMS", init_pms_cards}, 	/* not defined anywhere */
 #endif	
 	{"end", NULL}
 };
@@ -72,7 +70,6 @@
 static ssize_t video_read(struct file *file,
 	char *buf, size_t count, loff_t *ppos)
 {
-	int err;
 	struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
 	return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
 }
@@ -85,7 +82,6 @@
 static ssize_t video_write(struct file *file, const char *buf, 
 	size_t count, loff_t *ppos)
 {
-	int err;
 	struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
 	return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
 }
diff -u --recursive --new-file v2.1.80/linux/drivers/isdn/hisax/avm_a1.c linux/drivers/isdn/hisax/avm_a1.c
--- v2.1.80/linux/drivers/isdn/hisax/avm_a1.c	Mon Nov  3 09:54:38 1997
+++ linux/drivers/isdn/hisax/avm_a1.c	Wed Jan 21 23:42:12 1998
@@ -772,7 +772,7 @@
 	int loop = 0;
 	char tmp[40];
 
-	sp->counter = kstat.interrupts[sp->irq];
+	sp->counter = kstat_irqs(sp->irq);
 	sprintf(tmp, "IRQ %d count %d", sp->irq, sp->counter);
 	debugl1(sp, tmp);
 	clear_pending_ints(sp);
@@ -785,16 +785,16 @@
 			/* At least 1-3 irqs must happen
 			 * (one from HSCX A, one from HSCX B, 3rd from ISAC)
 			 */
-			if (kstat.interrupts[sp->irq] > sp->counter)
+			if (kstat_irqs(sp->irq) > sp->counter)
 				break;
 			current->state = TASK_INTERRUPTIBLE;
 			current->timeout = jiffies + 1;
 			schedule();
 		}
 		sprintf(tmp, "IRQ %d count %d", sp->irq,
-			kstat.interrupts[sp->irq]);
+			kstat_irqs(sp->irq));
 		debugl1(sp, tmp);
-		if (kstat.interrupts[sp->irq] == sp->counter) {
+		if (kstat_irqs(sp->irq) == sp->counter) {
 			printk(KERN_WARNING
 			       "AVM A1: IRQ(%d) getting no interrupts during init\n",
 			       sp->irq);
diff -u --recursive --new-file v2.1.80/linux/drivers/isdn/hisax/elsa.c linux/drivers/isdn/hisax/elsa.c
--- v2.1.80/linux/drivers/isdn/hisax/elsa.c	Mon Nov  3 09:54:38 1997
+++ linux/drivers/isdn/hisax/elsa.c	Wed Jan 21 23:42:12 1998
@@ -1180,7 +1180,7 @@
 	int ret, irq_cnt, cnt = 3;
 	long flags;
 
-	irq_cnt = kstat.interrupts[sp->irq];
+	irq_cnt = kstat_irqs(sp->irq);
 	printk(KERN_INFO "Elsa: IRQ %d count %d\n", sp->irq, irq_cnt);
 	ret = get_irq(sp->cardnr, &elsa_interrupt);
 #ifdef CONFIG_HISAX_ELSA_PCC
@@ -1213,8 +1213,8 @@
 		}
 #endif
 		printk(KERN_INFO "Elsa: IRQ %d count %d\n", sp->irq,
-		       kstat.interrupts[sp->irq]);
-		if (kstat.interrupts[sp->irq] == irq_cnt) {
+		       kstat_irqs(sp->irq));
+		if (kstat_irqs(sp->irq) == irq_cnt) {
 			printk(KERN_WARNING
 			       "Elsa: IRQ(%d) getting no interrupts during init %d\n",
 			       sp->irq, 4 - cnt);
diff -u --recursive --new-file v2.1.80/linux/drivers/isdn/hisax/ix1_micro.c linux/drivers/isdn/hisax/ix1_micro.c
--- v2.1.80/linux/drivers/isdn/hisax/ix1_micro.c	Mon Nov  3 09:54:38 1997
+++ linux/drivers/isdn/hisax/ix1_micro.c	Wed Jan 21 23:42:12 1998
@@ -841,7 +841,7 @@
 	int loop = 0;
 	char tmp[40];
 
-	sp->counter = kstat.interrupts[sp->irq];
+	sp->counter = kstat_irqs(sp->irq);
 	sprintf(tmp, "IRQ %d count %d", sp->irq, sp->counter);
 	debugl1(sp, tmp);
 	clear_pending_ints(sp);
@@ -854,16 +854,16 @@
 			/* At least 1-3 irqs must happen
 			 * (one from HSCX A, one from HSCX B, 3rd from ISAC)
 			 */
-			if (kstat.interrupts[sp->irq] > sp->counter)
+			if (kstat_irqs(sp->irq) > sp->counter)
 				break;
 			current->state = TASK_INTERRUPTIBLE;
 			current->timeout = jiffies + 1;
 			schedule();
 		}
 		sprintf(tmp, "IRQ %d count %d", sp->irq,
-			kstat.interrupts[sp->irq]);
+			kstat_irqs(sp->irq));
 		debugl1(sp, tmp);
-		if (kstat.interrupts[sp->irq] == sp->counter) {
+		if (kstat_irqs(sp->irq) == sp->counter) {
 			printk(KERN_WARNING
 			       "ix1-Micro: IRQ(%d) getting no interrupts during init\n",
 			       sp->irq);
diff -u --recursive --new-file v2.1.80/linux/drivers/isdn/hisax/teles0.c linux/drivers/isdn/hisax/teles0.c
--- v2.1.80/linux/drivers/isdn/hisax/teles0.c	Mon Nov  3 09:54:38 1997
+++ linux/drivers/isdn/hisax/teles0.c	Wed Jan 21 23:42:12 1998
@@ -802,7 +802,7 @@
 	int loop = 0;
 	char tmp[40];
 
-	sp->counter = kstat.interrupts[sp->irq];
+	sp->counter = kstat_irqs(sp->irq);
 	sprintf(tmp, "IRQ %d count %d", sp->irq, sp->counter);
 	debugl1(sp, tmp);
 	clear_pending_ints(sp);
@@ -815,16 +815,16 @@
 			/* At least 1-3 irqs must happen
 			 * (one from HSCX A, one from HSCX B, 3rd from ISAC)
 			 */
-			if (kstat.interrupts[sp->irq] > sp->counter)
+			if (kstat_irqs(sp->irq) > sp->counter)
 				break;
 			current->state = TASK_INTERRUPTIBLE;
 			current->timeout = jiffies + 1;
 			schedule();
 		}
 		sprintf(tmp, "IRQ %d count %d", sp->irq,
-			kstat.interrupts[sp->irq]);
+			kstat_irqs(sp->irq));
 		debugl1(sp, tmp);
-		if (kstat.interrupts[sp->irq] == sp->counter) {
+		if (kstat_irqs(sp->irq) == sp->counter) {
 			printk(KERN_WARNING
 			       "Teles0: IRQ(%d) getting no interrupts during init\n",
 			       sp->irq);
diff -u --recursive --new-file v2.1.80/linux/drivers/isdn/hisax/teles3.c linux/drivers/isdn/hisax/teles3.c
--- v2.1.80/linux/drivers/isdn/hisax/teles3.c	Mon Nov  3 09:54:38 1997
+++ linux/drivers/isdn/hisax/teles3.c	Wed Jan 21 23:43:24 1998
@@ -801,7 +801,7 @@
 	int loop = 0;
 	char tmp[40];
 
-	sp->counter = kstat.interrupts[sp->irq];
+	sp->counter = kstat_irqs(sp->irq);
 	sprintf(tmp, "IRQ %d count %d", sp->irq, sp->counter);
 	debugl1(sp, tmp);
 	clear_pending_ints(sp);
@@ -816,16 +816,16 @@
 			/* At least 1-3 irqs must happen
 			 * (one from HSCX A, one from HSCX B, 3rd from ISAC)
 			 */
-			if (kstat.interrupts[sp->irq] > sp->counter)
+			if (kstat_irqs(sp->irq) > sp->counter)
 				break;
 			current->state = TASK_INTERRUPTIBLE;
 			current->timeout = jiffies + 1;
 			schedule();
 		}
 		sprintf(tmp, "IRQ %d count %d loop %d", sp->irq,
-			kstat.interrupts[sp->irq], loop);
+			kstat_irqs(sp->irq), loop);
 		debugl1(sp, tmp);
-		if (kstat.interrupts[sp->irq] <= sp->counter) {
+		if (kstat_irqs(sp->irq) <= sp->counter) {
 			printk(KERN_WARNING
 			       "Teles3: IRQ(%d) getting no interrupts during init\n",
 			       sp->irq);
diff -u --recursive --new-file v2.1.80/linux/drivers/misc/parport_init.c linux/drivers/misc/parport_init.c
--- v2.1.80/linux/drivers/misc/parport_init.c	Sat Nov 29 16:19:41 1997
+++ linux/drivers/misc/parport_init.c	Fri Jan 23 17:38:04 1998
@@ -68,8 +68,6 @@
 #else
 __initfunc(int parport_init(void))
 {
-	struct parport *pb;
-
 	if (io[0] == PARPORT_DISABLE) 
 		return 1;
 
diff -u --recursive --new-file v2.1.80/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.1.80/linux/drivers/net/3c59x.c	Mon Jan 12 15:28:18 1998
+++ linux/drivers/net/3c59x.c	Fri Jan 23 17:38:04 1998
@@ -482,9 +482,11 @@
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Note: this is the only limit on the number of cards supported!! */
 static int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1,};
+#ifdef MODULE
 static int full_duplex[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
 /* A list of all installed Vortex devices, for removing the driver module. */
 static struct device *root_vortex_dev = NULL;
+#endif
 
 #ifdef MODULE
 /* Variables to work-around the Compaq PCI BIOS32 problem. */
diff -u --recursive --new-file v2.1.80/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- v2.1.80/linux/drivers/net/dgrs.c	Sun Jan  4 10:55:08 1998
+++ linux/drivers/net/dgrs.c	Fri Jan 23 17:38:04 1998
@@ -1250,12 +1250,12 @@
 ))
 {
 	DGRS_PRIV	*priv;
-	int		i;
 
 	#ifdef MODULE
 	{
 		/* Allocate and fill new device structure. */
 		int dev_size = sizeof(struct device) + sizeof(DGRS_PRIV);
+		int i;
 
 		dev = (struct device *) kmalloc(dev_size, GFP_KERNEL);
 		memset(dev, 0, dev_size);
diff -u --recursive --new-file v2.1.80/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v2.1.80/linux/drivers/net/lance.c	Mon Nov  3 09:29:30 1997
+++ linux/drivers/net/lance.c	Fri Jan 23 17:38:04 1998
@@ -611,7 +611,7 @@
 		   can watch the LEDs even if the board isn't opened. */
 		outw(0x0002, ioaddr+LANCE_ADDR);
 		/* set autoselect and clean xmausel */
-		outw(inw(ioaddr+LANCE_BUS_IF) & 0xfffe | 0x0002, ioaddr+LANCE_BUS_IF);
+		outw((inw(ioaddr+LANCE_BUS_IF) & 0xfffe) | 0x0002, ioaddr+LANCE_BUS_IF);
 	}
 
 	if (lance_debug > 0  &&  did_version++ == 0)
@@ -667,7 +667,7 @@
 		/* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */
 		outw(0x0002, ioaddr+LANCE_ADDR);
 		/* set autoselect and clean xmausel */
-		outw(inw(ioaddr+LANCE_BUS_IF) & 0xfffe | 0x0002, ioaddr+LANCE_BUS_IF);
+		outw((inw(ioaddr+LANCE_BUS_IF) & 0xfffe) | 0x0002, ioaddr+LANCE_BUS_IF);
 	}
 
 	if (lance_debug > 1)
diff -u --recursive --new-file v2.1.80/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c
--- v2.1.80/linux/drivers/net/sdla_fr.c	Thu Jan 15 14:33:06 1998
+++ linux/drivers/net/sdla_fr.c	Thu Jan 22 01:00:39 1998
@@ -1,4 +1,4 @@
-
+/****************************************************************************
 * sdla_fr.c	WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module.
 *
 * Author(s):	Gene Kozin	
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v2.1.80/linux/drivers/scsi/53c7,8xx.c	Wed Aug  6 13:02:59 1997
+++ linux/drivers/scsi/53c7,8xx.c	Fri Jan 23 17:38:04 1998
@@ -5958,7 +5958,7 @@
 		    host->host_no, cmd->pid);
 	    /* print_dsa does sanity check on address, no need to check */
 	    else
-	    	print_dsa (host, le32_to_cpu(((struct NCR53c7x0_cmd *) cmd->host_scribble)-> dsa), "");
+	    	print_dsa (host, bus_to_virt(le32_to_cpu(((struct NCR53c7x0_cmd *) cmd->host_scribble)-> dsa)), "");
 	} else 
 	    printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
 		host->host_no, cmd->pid, cmd->target, cmd->lun);
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- v2.1.80/linux/drivers/scsi/BusLogic.c	Tue Jan 20 15:02:21 1998
+++ linux/drivers/scsi/BusLogic.c	Wed Jan 21 12:04:45 1998
@@ -2338,15 +2338,11 @@
     Issue the Test Command Complete Interrupt commands.
   */
  
-  InitialInterruptCount = 0;
-  for (i=0; i<NR_CPUS; i++)
-	InitialInterruptCount += kstat.interrupts[i][HostAdapter->IRQ_Channel];
+  InitialInterruptCount = kstat_irqs(HostAdapter->IRQ_Channel);
   for (i = 0; i < TestCount; i++)
     BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
 		     NULL, 0, NULL, 0);
-  FinalInterruptCount = 0;
-  for (i=0; i<NR_CPUS; i++)
-  	FinalInterruptCount += kstat.interrupts[i][HostAdapter->IRQ_Channel];
+  FinalInterruptCount = kstat_irqs(HostAdapter->IRQ_Channel);
   /*
     Verify that BusLogic_InterruptHandler was called at least TestCount
     times.  Shared IRQ Channels could cause more than TestCount interrupts to
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v2.1.80/linux/drivers/scsi/Makefile	Mon Jan  5 01:41:01 1998
+++ linux/drivers/scsi/Makefile	Wed Jan 21 17:04:39 1998
@@ -430,6 +430,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_SCSI_PLUTO),y)
+L_OBJS += pluto.o
+else
+  ifeq ($(CONFIG_SCSI_PLUTO),m)
+  M_OBJS += pluto.o
+  endif
+endif
+
 ifeq ($(CONFIG_SCSI_EATA),y)
 L_OBJS += eata.o
 else
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c
--- v2.1.80/linux/drivers/scsi/NCR5380.c	Wed Apr 23 19:01:21 1997
+++ linux/drivers/scsi/NCR5380.c	Fri Jan 23 17:38:04 1998
@@ -625,7 +625,7 @@
  */
 
 
-static int probe_irq __initdata;
+static int probe_irq __initdata ;
 __initfunc(static void probe_intr (int irq, void *dev_id, struct pt_regs * regs)) {
     probe_irq = irq;
 };
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c
--- v2.1.80/linux/drivers/scsi/NCR53c406a.c	Wed Apr 23 19:01:21 1997
+++ linux/drivers/scsi/NCR53c406a.c	Fri Jan 23 17:38:04 1998
@@ -1012,7 +1012,7 @@
     outb(SYNC_MODE, SYNCOFF);   /* synchronous mode */  
 }
 
-__initfunc(void calc_port_addr())
+__initfunc(void calc_port_addr(void))
 {
     /* Control Register Set 0 */
     TC_LSB		= (port_base+0x00);
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- v2.1.80/linux/drivers/scsi/advansys.c	Sun Dec 21 17:04:48 1997
+++ linux/drivers/scsi/advansys.c	Fri Jan 23 17:35:23 1998
@@ -1,10 +1,10 @@
-/* $Id: advansys.c,v 1997/05/28 00:06:55 bobf Exp bobf $ */
-#define ASC_VERSION "2.8"    /* AdvanSys Driver Version */
+/* $Id: advansys.c,v 1.49 1998/01/22 20:19:25 bobf Exp bobf $ */
+#define ASC_VERSION "3.1D"    /* AdvanSys Driver Version */
 
 /*
  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
  * 
- * Copyright (c) 1995-1997 Advanced System Products, Inc.
+ * Copyright (c) 1995-1998 Advanced System Products, Inc.
  * All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -16,13 +16,12 @@
  *  http://www.advansys.com/linux.html
  *
  * The latest version of the AdvanSys driver is available at:
- *  ftp://ftp.advansys.com/pub/linux
+ *  ftp://ftp.advansys.com/pub/linux/linux.tgz
  *
  * Please send questions, comments, bug reports to:
- * bobf@advansys.com (Bob Frey)
+ *  bobf@advansys.com (Bob Frey)
  */
 
-
 /*
 
   Documentation for the AdvanSys Driver
@@ -43,7 +42,7 @@
   A. Linux Kernel Testing
 
      This driver has been tested in the following Linux kernels: v1.2.13,
-     v1.3.57, v2.0.30, v2.1.40. These kernel versions are major releases
+     v1.3.57, v2.0.33, v2.1.77. These kernel versions are major releases
      of Linux or the latest Linux kernel versions available when this version
      of the driver was released. The driver should also work in earlier
      versions of the Linux kernel. Beginning with v1.3.58 the AdvanSys driver
@@ -53,8 +52,10 @@
   B. Adapters Supported by this Driver
  
      AdvanSys (Advanced System Products, Inc.) manufactures the following
-     Bus-Mastering SCSI-2 Host Adapters for the ISA, EISA, VL, and PCI
-     buses. This Linux driver supports all of these adapters.
+     RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
+     (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
+     buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
+     transfer) SCSI Host Adapters for the PCI bus.
      
      The CDB counts below indicate the number of SCSI CDB (Command
      Descriptor Block) requests that can be stored in the RISC chip
@@ -72,7 +73,7 @@
         ABP930U - Bus-Master PCI Ultra (16 CDB)
         ABP930UA - Bus-Master PCI Ultra (16 CDB)
         ABP960 - Bus-Master PCI MAC/PC (16 CDB) (Footnote 2)
-        ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
+        ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) (Footnote 2)
      
      Single Channel Products:
         ABP542 - Bus-Master ISA with floppy (240 CDB)
@@ -82,11 +83,14 @@
         ABP940U - Bus-Master PCI Ultra (240 CDB)
         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
+        ABP940UW - Bus-Master PCI Ultra-Wide (240 CDB)
      
-     Dual Channel Products:
+     Multi Channel Products:
         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
+        ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
+        ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
      
      Footnotes:
        1. This board has been shipped by HP with the 4020i CD-R drive.
@@ -264,6 +268,7 @@
            --- Driver Options
            --- Debugging Header
            --- Asc Library Constants and Macros
+           --- Adv Library Constants and Macros
            --- Driver Constants and Macros
            --- Driver Structures
            --- Driver Data
@@ -272,20 +277,24 @@
            --- Loadable Driver Support
            --- Miscellaneous Driver Functions
            --- Functions Required by the Asc Library
+           --- Functions Required by the Adv Library
            --- Tracing and Debugging Functions
            --- Asc Library Functions
+           --- Adv Library Functions
  
      3. The string 'XXX' is used to flag code that needs to be re-written
         or that contains a problem that needs to be addressed.
  
      4. I have stripped comments from and reformatted the source for the
-        Asc Library which is included in this file. I haven't done this
-        to obfuscate the code. Actually I have done this to deobfuscate
-        the code. The Asc Library source can be found under the following
-        headings.
+        Asc Library and Adv Library to reduce the size of this file. This
+        source can be found under the following headings. The Asc Library
+        is used to support Narrow Boards. The Adv Library is used to
+        support Wide Boards.
  
            --- Asc Library Constants and Macros
+           --- Adv Library Constants and Macros
            --- Asc Library Functions
+           --- Adv Library Functions
  
   G. Driver Compile Time Options and Debugging
  
@@ -308,7 +317,7 @@
 
         Enabling this option adds tracing functions to the driver and
         the ability to set a driver tracing level at boot time. This
-        option will also symbols not required outside the driver to
+        option will also export symbols not required outside the driver to
         the kernel name space. This option is very useful for debugging
         the driver, but it will add to the size of the driver execution
         image and add overhead to the execution of the driver.
@@ -319,7 +328,7 @@
         
         If the driver is loaded at boot time and the LILO Driver Option
         is included in the system, the debug level can be changed by
-        specifying a 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port. The
+        specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
         first three hex digits of the pseudo I/O Port must be set to
         'deb' and the fourth hex digit specifies the debug level: 0 - F.
         The following command line will look for an adapter at 0x330
@@ -350,11 +359,6 @@
         I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
         prevents most level 1 debug messages from being lost.
 
-        this constant for debugging purposes, but for normal use of
-        the driver the constant should not be defined. This option
-        does not add overhead to the driver, but it does add unnecessary
-        symbols to the kernel name space.
- 
      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
  
         Enabling this option adds statistics collection and display
@@ -379,7 +383,6 @@
         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
         contain adapter and device configuration information.
 
-
   H. Driver LILO Option
  
      If init/main.c is modified as described in the 'Directions for Adding
@@ -406,7 +409,7 @@
 
            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
 
-     If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_BOARD_SUPPORTED + 1)
+     If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
      I/O Port may be added to specify the driver debug level. Refer to
      the 'Driver Compile Time Options and Debugging' section above for
      more information.
@@ -505,7 +508,7 @@
             repeat busy or QUEUE FULL status returned by a device.
          2. Incorporate miscellaneous Asc Library bug fixes.
          3. To allow the driver to work in kernels with broken module
-            support set 'cmd_per_lun' if the driver is compile as a
+            support set 'cmd_per_lun' if the driver is compiled as a
             module. This change affects kernels v1.3.89 to present.
          4. Remove PCI BIOS address from the driver banner. The PCI BIOS
             is relocated by the motherboard BIOS and its new address can
@@ -541,13 +544,42 @@
             option is enabled by default.
 
      2.8 (5/26/97):
-         1. Change version number to 2.8, skipping 2.3 through 2.7, in
-            order to synchronize the Linux driver version numbering with
-            other AdvanSys drivers.
-         2. Reformat source files without tabs to give everyone everyone
-            the same view of the file regardless of the tab setting used.
+         1. Change version number to 2.8 to synchronize the Linux driver
+            version numbering with other AdvanSys drivers.
+         2. Reformat source files without tabs to present the same view
+            of the file to everyone regardless of the editor tab setting
+            being used.
          3. Add Asc Library bug fixes.
 
+     3.1A (1/8/98):
+         1. Change version number to 3.1 to indicate that support for
+            Ultra-Wide adapters (ABP-940UW) is included in this release.
+         2. Add Asc Library (Narrow Board) bug fixes.
+         3. Report an underrun condition with the host status byte set
+            to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
+            causes the underrun condition to be ignored. When Linux defines
+            its own DID_UNDERRUN the constant defined in this file can be
+            removed.
+         4. Add patch to AscWaitTixISRDone().
+         5. Add support for up to 16 different AdvanSys host adapter SCSI
+            channels in one system. This allows four cards with four channels
+            to be used in one system.
+
+     3.1B (1/9/98):
+         1. Handle that PCI register base addresses are not always page
+            aligned even though ioremap() requires that the address argument
+            be page aligned.
+
+     3.1C (1/10/98):
+         1. Update latest BIOS version to 3.1E.
+         2. Don't set microcode SDTR variable at initialization. Instead
+            wait until device capabilities have been detected from an Inquiry
+            command.
+
+     3.1D (1/21/98):
+         1. Improve performance when the driver is compiled as module by
+            allowing up to 64 scatter-gather elements instead of 8.
+
   J. Known Problems or Issues
 
          1. Remove conditional constants (ASC_QUEUE_FLOW_CONTROL) around
@@ -563,8 +595,15 @@
      Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
      in advansys_biosparam() which was fixed in the 1.3 release.
 
-     Erik Ratcliffe <erik@caldera.com> has done a lot of testing of
-     the AdvanSys driver in the Caldera releases.
+     Erik Ratcliffe <erik@caldera.com> has done testing of the
+     AdvanSys driver in the Caldera releases.
+
+     Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
+     AscWaitTixISRDone() which he found necessary to make the
+     driver work with a SCSI-1 disk.
+
+     Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
+     support in the 3.1A driver.
 
   L. AdvanSys Contact Information
  
@@ -576,7 +615,7 @@
      Tech Support:           1-800-525-7440/1-408-467-2930
      BBS:                    1-408-383-9540 (14400,N,8,1)
      Interactive FAX:        1-408-383-9753
-     Customer Direct Sales:  1-800-883-1099/1-408-383-5777
+     Customer Direct Sales:  1-800-525-7443/1-408-383-5777
      Tech Support E-Mail:    support@advansys.com
      FTP Site:               ftp.advansys.com (login: anonymous)
      Web Site:               http://www.advansys.com
@@ -613,6 +652,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/malloc.h>
+#include <linux/mm.h>
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
 #include <linux/proc_fs.h>
 #endif /* version >= v1.3.0 */
@@ -633,6 +673,13 @@
 #include "sd.h"
 #include "advansys.h"
 
+/*
+ * If Linux eventually defines a DID_UNDERRUN, the constant here can be
+ * removed. The current value of zero for DID_UNDERRUN results in underrun
+ * conditions being ignored.
+ */
+#define DID_UNDERRUN 0
+
 
 /*
  * --- Driver Options
@@ -646,7 +693,7 @@
 
 /*
  * Because of no /proc to display them, statistics are disabled
- * for version prior to v1.3.0.
+ * for versions prior to v1.3.0.
  */
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
 #undef ADVANSYS_STATS /* Disable statistics */
@@ -672,7 +719,7 @@
 
 #define ASC_LIB_VERSION_MAJOR  1
 #define ASC_LIB_VERSION_MINOR  22
-#define ASC_LIB_SERIAL_NUMBER  105
+#define ASC_LIB_SERIAL_NUMBER  111
 
 typedef unsigned char uchar;
 
@@ -769,27 +816,6 @@
 #define ASC_MAX_SG_QUEUE    7
 #define ASC_MAX_SG_LIST     SG_ALL
 
-#define CC_CLEAR_LRAM_SRB_PTR           FALSE
-#define CC_VERIFY_LRAM_COPY             FALSE
-#define CC_DEBUG_SG_LIST                FALSE
-#define CC_FAST_STRING_IO               FALSE
-#define CC_WRITE_IO_COUNT               FALSE
-#define CC_CLEAR_DMA_REMAIN             FALSE
-#define CC_DISABLE_PCI_PARITY_INT       TRUE
-#define CC_LITTLE_ENDIAN_HOST           TRUE
-#define CC_STRUCT_ALIGNED               TRUE
-#define CC_MEMORY_MAPPED_IO             FALSE
-#define CC_INCLUDE_EEP_CONFIG           TRUE
-#define CC_PCI_ULTRA                    TRUE
-#define CC_ASC_SCSI_Q_USRDEF            FALSE
-#define CC_ASC_SCSI_REQ_Q_USRDEF        FALSE
-#define CC_ASCISR_CHECK_INT_PENDING     TRUE
-#define CC_CHK_FIX_EEP_CONTENT          TRUE
-#define CC_INCLUDE_EEP_CONFIG           TRUE
-#define CC_PLEXTOR_VL                   FALSE
-#define CC_TMP_USE_EEP_SDTR             FALSE
-#define CC_CHK_COND_REDO_SDTR           TRUE
-
 #define ASC_CS_TYPE  unsigned short
 #ifndef asc_ptr_type
 #define asc_ptr_type
@@ -840,27 +866,6 @@
 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
-#if !CC_STRUCT_ALIGNED
-#define DvcGetQinfo(iop_base, s_addr, outbuf, words)  \
-AscMemWordCopyFromLram(iop_base, s_addr, outbuf, words)
-#define DvcPutScsiQ(iop_base, s_addr, outbuf, words) \
-AscMemWordCopyToLram(iop_base, s_addr, outbuf, words)
-#endif
-#ifdef ASC_CHIP_VERSION
-#endif
-#if CC_MEMORY_MAPPED_IO
-#define inp(port)            *((uchar *)(port))
-#define outp(port, data)     *((uchar *)(port)) = (uchar)(data)
-#if CC_LITTLE_ENDIAN_HOST
-#define inpw(port)              *((ushort *)(port))
-#define outpw(port, data)       *((ushort *)(port)) = (ushort)(data)
-#else
-#define inpw(port)             EndianSwap16Bit((*((ushort *)(port))))
-#define outpw(port, data)      *((ushort *)(port)) = EndianSwap16Bit((ushort)(data))
-#define inpw_noswap(port)          *((ushort *)(port))
-#define outpw_noswap(port, data)   *((ushort *)(port)) = (ushort)(data)
-#endif
-#endif
 #ifndef inpw_noswap
 #define inpw_noswap(port)         inpw(port)
 #endif
@@ -901,6 +906,7 @@
 #define ASC_MAX_SENSE_LEN   32
 #define ASC_MIN_SENSE_LEN   14
 #define ASC_MAX_CDB_LEN     12
+#define ASC_SCSI_RESET_HOLD_TIME_US  60
 #define SCSICMD_TestUnitReady     0x00
 #define SCSICMD_Rewind            0x01
 #define SCSICMD_Rezero            0x01
@@ -963,6 +969,7 @@
 #define SCSI_SENKEY_VOL_OVERFLOW  0x0D
 #define SCSI_SENKEY_MISCOMP       0x0E
 #define SCSI_SENKEY_RESERVED      0x0F
+#define SCSI_ASC_NOMEDIA          0x3A
 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
@@ -1005,48 +1012,22 @@
 #define M2_QTAG_MSG_ORDERED     0x22
 #define M2_IGNORE_WIDE_RESIDUE  0x23
 
-#if CC_LITTLE_ENDIAN_HOST
 typedef struct {
     uchar               peri_dvc_type:5;
     uchar               peri_qualifier:3;
 } ASC_SCSI_INQ0;
 
-#else
-typedef struct {
-    uchar               peri_qualifier:3;
-    uchar               peri_dvc_type:5;
-} ASC_SCSI_INQ0;
-
-#endif
-#if CC_LITTLE_ENDIAN_HOST
 typedef struct {
     uchar               dvc_type_modifier:7;
     uchar               rmb:1;
 } ASC_SCSI_INQ1;
 
-#else
-typedef struct {
-    uchar               rmb:1;
-    uchar               dvc_type_modifier:7;
-} ASC_SCSI_INQ1;
-
-#endif
-#if CC_LITTLE_ENDIAN_HOST
 typedef struct {
     uchar               ansi_apr_ver:3;
     uchar               ecma_ver:3;
     uchar               iso_ver:2;
 } ASC_SCSI_INQ2;
 
-#else
-typedef struct {
-    uchar               iso_ver:2;
-    uchar               ecma_ver:3;
-    uchar               ansi_apr_ver:3;
-} ASC_SCSI_INQ2;
-
-#endif
-#if CC_LITTLE_ENDIAN_HOST
 typedef struct {
     uchar               rsp_data_fmt:4;
     uchar               res:2;
@@ -1054,16 +1035,6 @@
     uchar               aenc:1;
 } ASC_SCSI_INQ3;
 
-#else
-typedef struct {
-    uchar               aenc:1;
-    uchar               TemIOP:1;
-    uchar               res:2;
-    uchar               rsp_data_fmt:4;
-} ASC_SCSI_INQ3;
-
-#endif
-#if CC_LITTLE_ENDIAN_HOST
 typedef struct {
     uchar               StfRe:1;
     uchar               CmdQue:1;
@@ -1075,19 +1046,6 @@
     uchar               RelAdr:1;
 } ASC_SCSI_INQ7;
 
-#else
-typedef struct {
-    uchar               RelAdr:1;
-    uchar               WBus32:1;
-    uchar               WBus16:1;
-    uchar               Sync:1;
-    uchar               Linked:1;
-    uchar               Reserved:1;
-    uchar               CmdQue:1;
-    uchar               StfRe:1;
-} ASC_SCSI_INQ7;
-
-#endif
 typedef struct {
     ASC_SCSI_INQ0       byte0;
     ASC_SCSI_INQ1       byte1;
@@ -1102,7 +1060,6 @@
     uchar               product_rev_level[4];
 } ASC_SCSI_INQUIRY;
 
-#if CC_LITTLE_ENDIAN_HOST
 typedef struct asc_req_sense {
     uchar               err_code:7;
     uchar               info_valid:1;
@@ -1126,31 +1083,6 @@
     uchar               info2[4];
 } ASC_REQ_SENSE;
 
-#else
-typedef struct asc_req_sense {
-    uchar               info_valid:1;
-    uchar               err_code:7;
-    uchar               segment_no;
-    uchar               file_mark:1;
-    uchar               sense_EOM:1;
-    uchar               sense_ILI:1;
-    uchar               reserved_bit:1;
-    uchar               sense_key:4;
-    uchar               info1[4];
-    uchar               add_sense_len;
-    uchar               cmd_sp_info[4];
-    uchar               asc;
-    uchar               ascq;
-    uchar               fruc;
-    uchar               sks_valid:1;
-    uchar               sks_byte0:7;
-    uchar               sks_bytes[2];
-    uchar               notused[2];
-    uchar               ex_sense_code;
-    uchar               info2[4];
-} ASC_REQ_SENSE;
-
-#endif
 #define ASC_SG_LIST_PER_Q   7
 #define QS_FREE        0x00
 #define QS_READY       0x01
@@ -1348,9 +1280,6 @@
     ASC_SCSIQ_2         q2;
     uchar               *cdbptr;
     ASC_SG_HEAD         *sg_head;
-#if CC_ASC_SCSI_Q_USRDEF
-    ASC_SCSI_Q_USR      usr;
-#endif
 } ASC_SCSI_Q;
 
 typedef struct asc_scsi_req_q {
@@ -1362,9 +1291,6 @@
     ASC_SCSIQ_3         r3;
     uchar               cdb[ASC_MAX_CDB_LEN];
     uchar               sense[ASC_MIN_SENSE_LEN];
-#if CC_ASC_SCSI_REQ_Q_USRDEF
-    ASC_SCSI_REQ_Q_USR  usr;
-#endif
 } ASC_SCSI_REQ_Q;
 
 typedef struct asc_scsi_bios_req_q {
@@ -1569,9 +1495,10 @@
     ushort              mcode_date;
     ushort              mcode_version;
     uchar               max_tag_qng[ASC_MAX_TID + 1];
-    uchar       *overrun_buf;
+    uchar               *overrun_buf;
     uchar               sdtr_period_offset[ASC_MAX_TID + 1];
     ushort              pci_slot_info;
+    uchar               adapter_info[6];
 } ASC_DVC_CFG;
 
 #define ASC_DEF_DVC_CNTL       0xFFFF
@@ -1856,7 +1783,7 @@
 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
-#define ASC_CFG_MSW_CLR_MASK    0x30C0
+#define ASC_CFG_MSW_CLR_MASK    0x3080
 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
@@ -2000,7 +1927,7 @@
 STATIC void      AscDisableInterrupt(PortAddr);
 STATIC void      AscEnableInterrupt(PortAddr);
 STATIC void      AscSetBank(PortAddr, uchar);
-STATIC int       AscResetChipAndScsiBus(PortAddr);
+STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
 STATIC ushort    AscGetIsaDmaChannel(PortAddr);
 STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
 STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
@@ -2143,10 +2070,1120 @@
 
 
 /*
+ * --- Adv Library Constants and Macros
+ */
+
+#define ADV_LIB_VERSION_MAJOR  3
+#define ADV_LIB_VERSION_MINOR  34
+
+/* d_os_dep.h */
+#define ADV_OS_LINUX
+
+/*
+ * Define Adv Library required special types.
+ */
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
+#define AdvPortAddr  unsigned short     /* I/O Port address size */
+#else /* version >= v1,3,0 */
+#define AdvPortAddr  unsigned long      /* Virtual memory address size */
+#endif /* version >= v1,3,0 */
+
+/*
+ * Define Adv Library required memory access macros.
+ */
+#define ADV_MEM_READB(addr) readb(addr)
+#define ADV_MEM_READW(addr) readw(addr)
+#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
+#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
+
+/*
+ * The I/O memory mapping function names changed in 2.1.X.
+ */
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
+#define ioremap vremap
+#define iounmap vfree
+#endif /* version < v2.1.0 */
+
+/*
+ * Define total number of simultaneous maximum element scatter-gather
+ * requests, i.e. ADV_TOT_SG_LIST * ADV_MAX_SG_LIST is the total number
+ * of simultaneous scatter-gather elements supported per wide adapter.
+ */
+#define ADV_TOT_SG_LIST         64
+
+/*
+ * Define Adv Library required per request scatter-gather element limit.
+ */
+#define ADV_MAX_SG_LIST         64
+
+/*
+ * Scatter-Gather Definitions per request.
+ *
+ * Because SG block memory is allocated in virtual memory but is
+ * referenced by the microcode as physical memory, we need to do
+ * calculations to insure there will be enough physically contiguous
+ * memory to support ADV_MAX_SG_LIST SG entries.
+ */
+
+/* Number of SG blocks needed. */
+#define ADV_NUM_SG_BLOCK \
+     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
+
+/* Total contiguous memory needed for SG blocks. */
+#define ADV_SG_TOTAL_MEM_SIZE \
+    (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
+
+#define ASC_PAGE_SIZE PAGE_SIZE
+
+/*
+ * Number of page crossings possible for the total contiguous virtual memory
+ * needed for SG blocks.
+ *
+ * We need to allocate this many additional SG blocks in virtual memory to
+ * insure there will be space for ADV_NUM_SG_BLOCK physically contiguous
+ * scatter-gather blocks.
+ */
+#define ADV_NUM_PAGE_CROSSING \
+    ((ADV_SG_TOTAL_MEM_SIZE + (ASC_PAGE_SIZE - 1))/ASC_PAGE_SIZE)
+
+/*
+ * Define Adv Library Assertion Macro.
+ */
+
+#define ADV_ASSERT(a) ASC_ASSERT(a)
+
+/* a_condor.h */
+#define ADV_PCI_VENDOR_ID               0x10CD
+#define ADV_PCI_DEVICE_ID_REV_A         0x2300
+
+#define ASC_EEP_DVC_CFG_BEGIN           (0x00)
+#define ASC_EEP_DVC_CFG_END             (0x15)
+#define ASC_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
+#define ASC_EEP_MAX_WORD_ADDR           (0x1E)
+
+#define ASC_EEP_DELAY_MS                100
+
+/*
+ * EEPROM bits reference by the RISC after initialization.
+ */
+#define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
+#define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
+#define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
+
+/*
+ * EEPROM configuration format
+ *
+ * Field naming convention: 
+ *
+ *  *_enable indicates the field enables or disables the feature. The
+ *  value is never reset.
+ *
+ *  *_able indicates both whether a feature should be enabled or disabled
+ *  and whether a device isi capable of the feature. At initialization
+ *  this field may be set, but later if a device is found to be incapable
+ *  of the feature, the field is cleared.
+ *
+ * Default values are maintained in a_init.c in the structure
+ * Default_EEPROM_Config.
+ */
+typedef struct adveep_config
+{                              
+                                /* Word Offset, Description */
+
+  ushort cfg_lsw;               /* 00 power up initialization */
+                                /*  bit 13 set - Term Polarity Control */
+                                /*  bit 14 set - BIOS Enable */
+                                /*  bit 15 set - Big Endian Mode */
+  ushort cfg_msw;               /* 01 unused      */
+  ushort disc_enable;           /* 02 disconnect enable */         
+  ushort wdtr_able;             /* 03 Wide DTR able */
+  ushort sdtr_able;             /* 04 Synchronous DTR able */
+  ushort start_motor;           /* 05 send start up motor */      
+  ushort tagqng_able;           /* 06 tag queuing able */
+  ushort bios_scan;             /* 07 BIOS device control */   
+  ushort scam_tolerant;         /* 08 no scam */  
+ 
+  uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
+  uchar  bios_boot_delay;       /*    power up wait */
+ 
+  uchar  scsi_reset_delay;      /* 10 reset delay */
+  uchar  bios_id_lun;           /*    first boot device scsi id & lun */
+                                /*    high nibble is lun */  
+                                /*    low nibble is scsi id */
+
+  uchar  termination;           /* 11 0 - automatic */
+                                /*    1 - low off / high off */
+                                /*    2 - low off / high on */
+                                /*    3 - low on  / high on */
+                                /*    There is no low on  / high off */
+
+  uchar  reserved1;             /*    reserved byte (not used) */                                  
+
+  ushort bios_ctrl;             /* 12 BIOS control bits */
+                                /*  bit 0  set: BIOS don't act as initiator. */
+                                /*  bit 1  set: BIOS > 1 GB support */
+                                /*  bit 2  set: BIOS > 2 Disk Support */
+                                /*  bit 3  set: BIOS don't support removables */
+                                /*  bit 4  set: BIOS support bootable CD */
+                                /*  bit 5  set: */
+                                /*  bit 6  set: BIOS support multiple LUNs */
+                                /*  bit 7  set: BIOS display of message */
+                                /*  bit 8  set: */
+                                /*  bit 9  set: Reset SCSI bus during init. */
+                                /*  bit 10 set: */
+                                /*  bit 11 set: No verbose initialization. */
+                                /*  bit 12 set: SCSI parity enabled */
+                                /*  bit 13 set: */
+                                /*  bit 14 set: */
+                                /*  bit 15 set: */
+  ushort  ultra_able;           /* 13 ULTRA speed able */ 
+  ushort  reserved2;            /* 14 reserved */
+  uchar   max_host_qng;         /* 15 maximum host queuing */
+  uchar   max_dvc_qng;          /*    maximum per device queuing */
+  ushort  dvc_cntl;             /* 16 control bit for driver */
+  ushort  bug_fix;              /* 17 control bit for bug fix */
+  ushort  serial_number_word1;  /* 18 Board serial number word 1 */  
+  ushort  serial_number_word2;  /* 19 Board serial number word 2 */  
+  ushort  serial_number_word3;  /* 20 Board serial number word 3 */
+  ushort  check_sum;            /* 21 EEP check sum */
+  uchar   oem_name[16];         /* 22 OEM name */
+  ushort  dvc_err_code;         /* 30 last device driver error code */
+  ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
+  ushort  adv_err_addr;         /* 32 last uc error address */
+  ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
+  ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
+  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */  
+  ushort  num_of_err;           /* 36 number of error */
+} ADVEEP_CONFIG; 
+
+/*
+ * EEPROM Commands
+ */
+#define ASC_EEP_CMD_DONE             0x0200
+#define ASC_EEP_CMD_DONE_ERR         0x0001
+
+/* cfg_word */
+#define EEP_CFG_WORD_BIG_ENDIAN      0x8000
+
+/* bios_ctrl */
+#define BIOS_CTRL_BIOS               0x0001
+#define BIOS_CTRL_EXTENDED_XLAT      0x0002
+#define BIOS_CTRL_GT_2_DISK          0x0004
+#define BIOS_CTRL_BIOS_REMOVABLE     0x0008
+#define BIOS_CTRL_BOOTABLE_CD        0x0010
+#define BIOS_CTRL_MULTIPLE_LUN       0x0040
+#define BIOS_CTRL_DISPLAY_MSG        0x0080
+#define BIOS_CTRL_NO_SCAM            0x0100
+#define BIOS_CTRL_RESET_SCSI_BUS     0x0200
+#define BIOS_CTRL_INIT_VERBOSE       0x0800
+#define BIOS_CTRL_SCSI_PARITY        0x1000
+
+/*
+ * ASC 3550 Internal Memory Size - 8KB
+ */
+#define ADV_CONDOR_MEMSIZE   0x2000     /* 8 KB Internal Memory */
+
+/*
+ * ASC 3550 I/O Length - 64 bytes
+ */
+#define ADV_CONDOR_IOLEN     0x40       /* I/O Port Range in bytes */
+
+/*
+ * Byte I/O register address from base of 'iop_base'.
+ */
+#define IOPB_INTR_STATUS_REG    0x00
+#define IOPB_CHIP_ID_1          0x01
+#define IOPB_INTR_ENABLES       0x02
+#define IOPB_CHIP_TYPE_REV      0x03
+#define IOPB_RES_ADDR_4         0x04
+#define IOPB_RES_ADDR_5         0x05
+#define IOPB_RAM_DATA           0x06
+#define IOPB_RES_ADDR_7         0x07
+#define IOPB_FLAG_REG           0x08
+#define IOPB_RES_ADDR_9         0x09
+#define IOPB_RISC_CSR           0x0A
+#define IOPB_RES_ADDR_B         0x0B
+#define IOPB_RES_ADDR_C         0x0C
+#define IOPB_RES_ADDR_D         0x0D
+#define IOPB_RES_ADDR_E         0x0E
+#define IOPB_RES_ADDR_F         0x0F
+#define IOPB_MEM_CFG            0x10
+#define IOPB_RES_ADDR_11        0x11
+#define IOPB_RES_ADDR_12        0x12
+#define IOPB_RES_ADDR_13        0x13
+#define IOPB_FLASH_PAGE         0x14
+#define IOPB_RES_ADDR_15        0x15
+#define IOPB_RES_ADDR_16        0x16
+#define IOPB_RES_ADDR_17        0x17
+#define IOPB_FLASH_DATA         0x18
+#define IOPB_RES_ADDR_19        0x19
+#define IOPB_RES_ADDR_1A        0x1A
+#define IOPB_RES_ADDR_1B        0x1B
+#define IOPB_RES_ADDR_1C        0x1C
+#define IOPB_RES_ADDR_1D        0x1D
+#define IOPB_RES_ADDR_1E        0x1E
+#define IOPB_RES_ADDR_1F        0x1F
+#define IOPB_DMA_CFG0           0x20
+#define IOPB_DMA_CFG1           0x21
+#define IOPB_TICKLE             0x22
+#define IOPB_DMA_REG_WR         0x23
+#define IOPB_SDMA_STATUS        0x24
+#define IOPB_SCSI_BYTE_CNT      0x25
+#define IOPB_HOST_BYTE_CNT      0x26
+#define IOPB_BYTE_LEFT_TO_XFER  0x27
+#define IOPB_BYTE_TO_XFER_0     0x28
+#define IOPB_BYTE_TO_XFER_1     0x29
+#define IOPB_BYTE_TO_XFER_2     0x2A
+#define IOPB_BYTE_TO_XFER_3     0x2B
+#define IOPB_ACC_GRP            0x2C
+#define IOPB_RES_ADDR_2D        0x2D
+#define IOPB_DEV_ID             0x2E
+#define IOPB_RES_ADDR_2F        0x2F
+#define IOPB_SCSI_DATA          0x30
+#define IOPB_RES_ADDR_31        0x31
+#define IOPB_RES_ADDR_32        0x32
+#define IOPB_SCSI_DATA_HSHK     0x33
+#define IOPB_SCSI_CTRL          0x34
+#define IOPB_RES_ADDR_35        0x35
+#define IOPB_RES_ADDR_36        0x36
+#define IOPB_RES_ADDR_37        0x37
+#define IOPB_RES_ADDR_38        0x38
+#define IOPB_RES_ADDR_39        0x39
+#define IOPB_RES_ADDR_3A        0x3A
+#define IOPB_RES_ADDR_3B        0x3B
+#define IOPB_RFIFO_CNT          0x3C
+#define IOPB_RES_ADDR_3D        0x3D
+#define IOPB_RES_ADDR_3E        0x3E
+#define IOPB_RES_ADDR_3F        0x3F
+
+/*
+ * Word I/O register address from base of 'iop_base'.
+ */
+#define IOPW_CHIP_ID_0          0x00  /* CID0  */
+#define IOPW_CTRL_REG           0x02  /* CC    */
+#define IOPW_RAM_ADDR           0x04  /* LA    */
+#define IOPW_RAM_DATA           0x06  /* LD    */
+#define IOPW_RES_ADDR_08        0x08
+#define IOPW_RISC_CSR           0x0A  /* CSR   */
+#define IOPW_SCSI_CFG0          0x0C  /* CFG0  */
+#define IOPW_SCSI_CFG1          0x0E  /* CFG1  */
+#define IOPW_RES_ADDR_10        0x10
+#define IOPW_SEL_MASK           0x12  /* SM    */
+#define IOPW_RES_ADDR_14        0x14
+#define IOPW_FLASH_ADDR         0x16  /* FA    */
+#define IOPW_RES_ADDR_18        0x18
+#define IOPW_EE_CMD             0x1A  /* EC    */
+#define IOPW_EE_DATA            0x1C  /* ED    */
+#define IOPW_SFIFO_CNT          0x1E  /* SFC   */
+#define IOPW_RES_ADDR_20        0x20
+#define IOPW_Q_BASE             0x22  /* QB    */
+#define IOPW_QP                 0x24  /* QP    */
+#define IOPW_IX                 0x26  /* IX    */
+#define IOPW_SP                 0x28  /* SP    */
+#define IOPW_PC                 0x2A  /* PC    */
+#define IOPW_RES_ADDR_2C        0x2C
+#define IOPW_RES_ADDR_2E        0x2E
+#define IOPW_SCSI_DATA          0x30  /* SD    */
+#define IOPW_SCSI_DATA_HSHK     0x32  /* SDH   */
+#define IOPW_SCSI_CTRL          0x34  /* SC    */
+#define IOPW_HSHK_CFG           0x36  /* HCFG  */
+#define IOPW_SXFR_STATUS        0x36  /* SXS   */
+#define IOPW_SXFR_CNTL          0x38  /* SXL   */
+#define IOPW_SXFR_CNTH          0x3A  /* SXH   */
+#define IOPW_RES_ADDR_3C        0x3C
+#define IOPW_RFIFO_DATA         0x3E  /* RFD   */
+
+/*
+ * Doubleword I/O register address from base of 'iop_base'.
+ */
+#define IOPDW_RES_ADDR_0         0x00
+#define IOPDW_RAM_DATA           0x04
+#define IOPDW_RES_ADDR_8         0x08
+#define IOPDW_RES_ADDR_C         0x0C
+#define IOPDW_RES_ADDR_10        0x10
+#define IOPDW_RES_ADDR_14        0x14
+#define IOPDW_RES_ADDR_18        0x18
+#define IOPDW_RES_ADDR_1C        0x1C
+#define IOPDW_SDMA_ADDR0         0x20
+#define IOPDW_SDMA_ADDR1         0x24
+#define IOPDW_SDMA_COUNT         0x28
+#define IOPDW_SDMA_ERROR         0x2C
+#define IOPDW_RDMA_ADDR0         0x30
+#define IOPDW_RDMA_ADDR1         0x34
+#define IOPDW_RDMA_COUNT         0x38
+#define IOPDW_RDMA_ERROR         0x3C
+
+#define ADV_CHIP_ID_BYTE         0x25
+#define ADV_CHIP_ID_WORD         0x04C1
+
+#define ADV_SC_SCSI_BUS_RESET    0x2000
+
+#define ADV_INTR_ENABLE_HOST_INTR                   0x01
+#define ADV_INTR_ENABLE_SEL_INTR                    0x02
+#define ADV_INTR_ENABLE_DPR_INTR                    0x04
+#define ADV_INTR_ENABLE_RTA_INTR                    0x08
+#define ADV_INTR_ENABLE_RMA_INTR                    0x10
+#define ADV_INTR_ENABLE_RST_INTR                    0x20
+#define ADV_INTR_ENABLE_DPE_INTR                    0x40
+#define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
+
+#define ADV_INTR_STATUS_INTRA            0x01
+#define ADV_INTR_STATUS_INTRB            0x02
+#define ADV_INTR_STATUS_INTRC            0x04
+
+#define ADV_RISC_CSR_STOP           (0x0000)
+#define ADV_RISC_TEST_COND          (0x2000)
+#define ADV_RISC_CSR_RUN            (0x4000)
+#define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
+
+#define ADV_CTRL_REG_HOST_INTR      0x0100
+#define ADV_CTRL_REG_SEL_INTR       0x0200
+#define ADV_CTRL_REG_DPR_INTR       0x0400
+#define ADV_CTRL_REG_RTA_INTR       0x0800
+#define ADV_CTRL_REG_RMA_INTR       0x1000
+#define ADV_CTRL_REG_RES_BIT14      0x2000
+#define ADV_CTRL_REG_DPE_INTR       0x4000
+#define ADV_CTRL_REG_POWER_DONE     0x8000
+#define ADV_CTRL_REG_ANY_INTR       0xFF00
+
+#define ADV_CTRL_REG_CMD_RESET             0x00C6
+#define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
+#define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
+#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
+#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
+
+#define ADV_SCSI_CTRL_RSTOUT        0x2000
+
+#define AdvIsIntPending(port)  \
+    (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
+
+/*
+ * SCSI_CFG0 Register bit definitions
+ */
+#define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
+#define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
+#define EVEN_PARITY     0x1000  /* Select Even Parity */
+#define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
+#define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
+#define PRIM_MODE       0x0100  /* Primitive SCSI mode */
+#define SCAM_EN         0x0080  /* Enable SCAM selection */
+#define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
+#define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
+#define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
+#define OUR_ID          0x000F  /* SCSI ID */
+
+/*
+ * SCSI_CFG1 Register bit definitions
+ */
+#define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
+#define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
+#define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
+#define FILTER_SEL      0x0C00  /* Filter Period Selection */
+#define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
+#define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */          
+#define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */          
+#define ACTIVE_DBL      0x0200  /* Disable Active Negation */
+#define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
+#define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
+#define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
+#define TERM_CTL        0x0030  /* External SCSI Termination Bits */
+#define  TERM_CTL_H      0x0020  /* Enable External SCSI Upper Termination */
+#define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
+#define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
+
+#define CABLE_ILLEGAL_A 0x7
+    /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
+
+#define CABLE_ILLEGAL_B 0xB
+    /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
+
+/*
+   The following table details the SCSI_CFG1 Termination Polarity,
+   Termination Control and Cable Detect bits.
+
+   Cable Detect | Termination
+   Bit 3 2 1 0  | 5   4  | Notes
+   _____________|________|____________________
+       1 1 1 0  | on  on | Internal wide only
+       1 1 0 1  | on  on | Internal narrow only
+       1 0 1 1  | on  on | External narrow only
+       0 x 1 1  | on  on | External wide only
+       1 1 0 0  | on  off| Internal wide and internal narrow
+       1 0 1 0  | on  off| Internal wide and external narrow
+       0 x 1 0  | off off| Internal wide and external wide
+       1 0 0 1  | on  off| Internal narrow and external narrow
+       0 x 0 1  | on  off| Internal narrow and external wide
+       1 1 1 1  | on  on | No devices are attached
+       x 0 0 0  | on  on | Illegal (all 3 connectors are used)
+       0 x 0 0  | on  on | Illegal (all 3 connectors are used)
+  
+       x means don't-care (either '0' or '1')
+  
+       If term_pol (bit 13) is '0' (active-low terminator enable), then:
+           'on' is '0' and 'off' is '1'.
+  
+       If term_pol bit is '1' (meaning active-hi terminator enable), then:
+           'on' is '1' and 'off' is '0'.
+ */
+
+/*
+ * MEM_CFG Register bit definitions
+ */
+#define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
+#define FAST_EE_CLK     0x20    /* Diagnostic Bit */
+#define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
+#define  RAM_SZ_2KB      0x00    /* 2 KB */
+#define  RAM_SZ_4KB      0x04    /* 4 KB */
+#define  RAM_SZ_8KB      0x08    /* 8 KB */
+#define  RAM_SZ_16KB     0x0C    /* 16 KB */
+#define  RAM_SZ_32KB     0x10    /* 32 KB */
+#define  RAM_SZ_64KB     0x14    /* 64 KB */
+
+/*
+ * DMA_CFG0 Register bit definitions
+ *
+ * This register is only accessible to the host.
+ */
+#define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
+#define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
+#define  FIFO_THRESH_16B  0x00   /* 16 bytes */
+#define  FIFO_THRESH_32B  0x20   /* 32 bytes */
+#define  FIFO_THRESH_48B  0x30   /* 48 bytes */
+#define  FIFO_THRESH_64B  0x40   /* 64 bytes */
+#define  FIFO_THRESH_80B  0x50   /* 80 bytes (default) */
+#define  FIFO_THRESH_96B  0x60   /* 96 bytes */
+#define  FIFO_THRESH_112B 0x70   /* 112 bytes */
+#define START_CTL       0x0C    /* DMA start conditions */
+#define  START_CTL_TH    0x00    /* Wait threshold level (default) */
+#define  START_CTL_ID    0x04    /* Wait SDMA/SBUS idle */
+#define  START_CTL_THID  0x08    /* Wait threshold and SDMA/SBUS idle */
+#define  START_CTL_EMFU  0x0C    /* Wait SDMA FIFO empty/full */
+#define READ_CMD        0x03    /* Memory Read Method */
+#define  READ_CMD_MR     0x00    /* Memory Read */
+#define  READ_CMD_MRL    0x02    /* Memory Read Long */
+#define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
+
+/* a_advlib.h */
+
+/*
+ * Adv Library Status Definitions
+ */
+#define ADV_TRUE        1
+#define ADV_FALSE       0
+#define ADV_NOERROR     1
+#define ADV_SUCCESS     1
+#define ADV_BUSY        0
+#define ADV_ERROR       (-1)
+
+
+/*
+ * ASC_DVC_VAR 'warn_code' values
+ */
+#define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
+#define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
+#define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
+#define ASC_WARN_ERROR                  0xFFFF /* ADV_ERROR return */
+
+#define ADV_MAX_TID                     15 /* max. target identifier */
+#define ADV_MAX_LUN                     7  /* max. logical unit number */
+
+
+/*
+ * AscInitGetConfig() and AscInitAsc1000Driver() Definitions
+ *
+ * Error code values are set in ASC_DVC_VAR 'err_code'.
+ */
+#define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
+#define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
+#define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
+#define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
+#define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
+#define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
+#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
+#define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
+#define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
+#define ASC_IERR_RW_LRAM            0x8000 /* read/write local RAM error */
+
+/*
+ * Fixed locations of microcode operating variables.
+ */
+#define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
+#define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
+#define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
+#define ASC_MC_STACK_BEGIN              0x002E /* microcode stack begin */
+#define ASC_MC_STACK_END                0x0030 /* microcode stack end */
+#define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
+#define ASC_MC_VERSION_NUM              0x003A /* microcode number */
+#define ASCV_VER_SERIAL_W               0x003C /* used in dos_init */
+#define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
+#define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
+#define ASC_MC_HALTCODE                 0x0094 /* microcode halt code */
+#define ASC_MC_CALLERPC                 0x0096 /* microcode halt caller PC */
+#define ASC_MC_ADAPTER_SCSI_ID          0x0098 /* one ID byte + reserved */
+#define ASC_MC_ULTRA_ABLE               0x009C
+#define ASC_MC_SDTR_ABLE                0x009E
+#define ASC_MC_TAGQNG_ABLE              0x00A0
+#define ASC_MC_DISC_ENABLE              0x00A2
+#define ASC_MC_IDLE_CMD                 0x00A6
+#define ASC_MC_IDLE_PARA_STAT           0x00A8
+#define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
+#define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
+#define ASC_MC_DEFAULT_MEM_CFG          0x00B0
+#define ASC_MC_DEFAULT_SEL_MASK         0x00B2
+#define ASC_MC_RISC_NEXT_READY          0x00B4
+#define ASC_MC_RISC_NEXT_DONE           0x00B5
+#define ASC_MC_SDTR_DONE                0x00B6
+#define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
+#define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
+#define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
+#define ASC_MC_WDTR_ABLE                0x0120 /* Wide Transfer TID bitmask. */
+#define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
+#define ASC_MC_WDTR_DONE                0x0124
+#define ASC_MC_HOST_NEXT_READY          0x0128 /* Host Next Ready RQL Entry. */
+#define ASC_MC_HOST_NEXT_DONE           0x0129 /* Host Next Done RQL Entry. */
+
+/*
+ * BIOS LRAM variable absolute offsets.
+ */
+#define BIOS_CODESEG    0x54
+#define BIOS_CODELEN    0x56
+#define BIOS_SIGNATURE  0x58
+#define BIOS_VERSION    0x5A
+#define BIOS_SIGNATURE  0x58
+
+/*
+ * Microcode Control Flags
+ *
+ * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
+ * and handled by the microcode.
+ */
+#define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
+
+/*
+ * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
+ */
+#define HSHK_CFG_WIDE_XFR       0x8000
+#define HSHK_CFG_RATE           0x0F00
+#define HSHK_CFG_OFFSET         0x001F
+
+/*
+ * LRAM RISC Queue Lists (LRAM addresses 0x1200 - 0x19FF)
+ *
+ * Each of the 255 Adv Library/Microcode RISC queue lists or mailboxes 
+ * starting at LRAM address 0x1200 is 8 bytes and has the following
+ * structure. Only 253 of these are actually used for command queues.
+ */
+
+#define ASC_MC_RISC_Q_LIST_BASE         0x1200
+#define ASC_MC_RISC_Q_LIST_SIZE         0x0008
+#define ASC_MC_RISC_Q_TOTAL_CNT         0x00FF /* Num. queue slots in LRAM. */
+#define ASC_MC_RISC_Q_FIRST             0x0001
+#define ASC_MC_RISC_Q_LAST              0x00FF
+
+#define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
+#define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
+#define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
+#define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
+
+/* RISC Queue List structure - 8 bytes */
+#define RQL_FWD     0     /* forward pointer (1 byte) */
+#define RQL_BWD     1     /* backward pointer (1 byte) */
+#define RQL_STATE   2     /* state byte - free, ready, done, aborted (1 byte) */
+#define RQL_TID     3     /* request target id (1 byte) */
+#define RQL_PHYADDR 4     /* request physical pointer (4 bytes) */
+     
+/* RISC Queue List state values */
+#define ASC_MC_QS_FREE                  0x00
+#define ASC_MC_QS_READY                 0x01
+#define ASC_MC_QS_DONE                  0x40
+#define ASC_MC_QS_ABORTED               0x80
+
+/* RISC Queue List pointer values */
+#define ASC_MC_NULL_Q                   0x00            /* NULL_Q == 0   */
+#define ASC_MC_BIOS_Q                   0xFF            /* BIOS_Q = 255  */
+
+/* ASC_SCSI_REQ_Q 'cntl' field values */
+#define ASC_MC_QC_START_MOTOR           0x02     /* Issue start motor. */
+#define ASC_MC_QC_NO_OVERRUN            0x04     /* Don't report overrun. */
+#define ASC_MC_QC_FIRST_DMA             0x08     /* Internal microcode flag. */
+#define ASC_MC_QC_ABORTED               0x10     /* Request aborted by host. */
+#define ASC_MC_QC_REQ_SENSE             0x20     /* Auto-Request Sense. */
+#define ASC_MC_QC_DOS_REQ               0x80     /* Request issued by DOS. */
+
+
+/*
+ * ASC_SCSI_REQ_Q 'a_flag' definitions
+ *
+ * The Adv Library should limit use to the lower nibble (4 bits) of
+ * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
+ */
+#define ADV_POLL_REQUEST                0x01   /* poll for request completion */
+#define ADV_SCSIQ_DONE                  0x02   /* request done */
+
+/*
+ * Adapter temporary configuration structure
+ *
+ * This structure can be discarded after initialization. Don't add
+ * fields here needed after initialization.
+ *
+ * Field naming convention: 
+ *
+ *  *_enable indicates the field enables or disables a feature. The
+ *  value of the field is never reset.
+ */
+typedef struct adv_dvc_cfg {
+  ushort disc_enable;       /* enable disconnection */
+  uchar  chip_version;      /* chip version */
+  uchar  termination;       /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
+  ushort pci_device_id;     /* PCI device code number */
+  ushort lib_version;       /* Adv Library version number */
+  ushort control_flag;      /* Microcode Control Flag */
+  ushort mcode_date;        /* Microcode date */
+  ushort mcode_version;     /* Microcode version */
+  ushort pci_slot_info;     /* high byte device/function number */
+                            /* bits 7-3 device num., bits 2-0 function num. */
+                            /* low byte bus num. */
+  ushort bios_boot_wait;    /* BIOS boot time delay */
+  ushort serial1;           /* EEPROM serial number word 1 */
+  ushort serial2;           /* EEPROM serial number word 2 */
+  ushort serial3;           /* EEPROM serial number word 3 */
+} ADV_DVC_CFG; 
+
+/*
+ * Adapter operation variable structure.
+ *
+ * One structure is required per host adapter.
+ *
+ * Field naming convention: 
+ *
+ *  *_able indicates both whether a feature should be enabled or disabled
+ *  and whether a device isi capable of the feature. At initialization
+ *  this field may be set, but later if a device is found to be incapable
+ *  of the feature, the field is cleared.
+ */
+typedef struct adv_dvc_var {
+  AdvPortAddr iop_base;   /* I/O port address */
+  ushort err_code;        /* fatal error code */
+  ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
+  Ptr2Func isr_callback;  /* pointer to function, called in AdvISR() */
+  Ptr2Func sbreset_callback;  /* pointer to function, called in AdvISR() */
+  ushort wdtr_able;       /* try WDTR for a device */
+  ushort sdtr_able;       /* try SDTR for a device */
+  ushort ultra_able;      /* try SDTR Ultra speed for a device */
+  ushort tagqng_able;     /* try tagged queuing with a device */
+  uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
+  ushort start_motor;     /* start motor command allowed */
+  uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
+  uchar  chip_no;         /* should be assigned by caller */
+  uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
+  uchar  cur_host_qng;    /* total number of queue command */
+  uchar  irq_no;          /* IRQ number */
+  ushort no_scam;         /* scam_tolerant of EEPROM */
+  ushort idle_cmd_done;   /* microcode idle command done set by AdvISR() */
+  ulong  drv_ptr;         /* driver pointer to private structure */
+  uchar  chip_scsi_id;    /* chip SCSI target ID */
+ /*
+  * Note: The following fields will not be used after initialization. The
+  * driver may discard the buffer after initialization is done.
+  */
+  ADV_DVC_CFG *cfg; /* temporary configuration structure  */
+} ADV_DVC_VAR; 
+
+#define NO_OF_SG_PER_BLOCK              15
+
+typedef struct asc_sg_block {
+    uchar reserved1; 
+    uchar reserved2; 
+    uchar first_entry_no;             /* starting entry number */
+    uchar last_entry_no;              /* last entry number */
+    struct asc_sg_block *sg_ptr; /* links to the next sg block */
+    struct  {
+        ulong sg_addr;                /* SG element address */
+        ulong sg_count;               /* SG element count */
+    } sg_list[NO_OF_SG_PER_BLOCK];
+} ADV_SG_BLOCK;
+
+/*
+ * ASC_SCSI_REQ_Q - microcode request structure
+ *
+ * All fields in this structure up to byte 60 are used by the microcode.
+ * The microcode makes assumptions about the size and ordering of fields
+ * in this structure. Do not change the structure definition here without
+ * coordinating the change with the microcode.
+ */
+typedef struct adv_scsi_req_q {
+    uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
+    uchar       sg_entry_cnt;   /* SG element count. Zero for no SG. */
+    uchar       target_id;      /* Device target identifier. */
+    uchar       target_lun;     /* Device target logical unit number. */
+    ulong       data_addr;      /* Data buffer physical address. */
+    ulong       data_cnt;       /* Data count. Ucode sets to residual. */
+    ulong       sense_addr;     /* Sense buffer physical address. */
+    ulong       srb_ptr;        /* Driver request pointer. */
+    uchar       a_flag;         /* Adv Library flag field. */
+    uchar       sense_len;      /* Auto-sense length. Ucode sets to residual. */
+    uchar       cdb_len;        /* SCSI CDB length. */
+    uchar       tag_code;       /* SCSI-2 Tag Queue Code: 00, 20-22. */
+    uchar       done_status;    /* Completion status. */
+    uchar       scsi_status;    /* SCSI status byte. */
+    uchar       host_status;    /* Ucode host status. */
+    uchar       ux_sg_ix;       /* Ucode working SG variable. */
+    uchar       cdb[12];        /* SCSI command block. */
+    ulong       sg_real_addr;   /* SG list physical address. */
+    struct adv_scsi_req_q *free_scsiq_link;
+    ulong       ux_wk_data_cnt; /* Saved data count at disconnection. */
+    struct adv_scsi_req_q *scsiq_ptr;
+    ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
+    /*
+     * End of microcode structure - 60 bytes. The rest of the structure
+     * is used by the Adv Library and ignored by the microcode.
+     */
+    ulong       vsense_addr;    /* Sense buffer virtual address. */
+    ulong       vdata_addr;     /* Data buffer virtual address. */
+    uchar       orig_sense_len; /* Original length of sense buffer. */
+} ADV_SCSI_REQ_Q; /* BIOS - 70 bytes, DOS - 76 bytes, W95, WNT - 69 bytes */
+
+/*
+ * Microcode idle loop commands
+ */
+#define IDLE_CMD_COMPLETED           0
+#define IDLE_CMD_STOP_CHIP           0x0001
+#define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
+#define IDLE_CMD_SEND_INT            0x0004
+#define IDLE_CMD_ABORT               0x0008
+#define IDLE_CMD_DEVICE_RESET        0x0010
+#define IDLE_CMD_SCSI_RESET          0x0020
+
+/*
+ * AdvSendIdleCmd() flag definitions.
+ */
+#define ADV_NOWAIT     0x01
+
+/*
+ * Wait loop time out values.
+ */
+#define SCSI_WAIT_10_SEC             10         /* 10 seconds */
+#define SCSI_MS_PER_SEC              1000       /* milliseconds per second */
+
+/*
+ * Device drivers must define the following functions.
+ */
+STATIC int   DvcEnterCritical(void);
+STATIC void  DvcLeaveCritical(int);
+STATIC void  DvcSleepMilliSecond(ulong);
+STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
+STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
+STATIC ulong DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
+                uchar *, long *, int);
+STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
+
+/*
+ * Adv Library functions available to drivers.
+ */
+STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *,
+                         ADV_SCSI_REQ_Q *);
+STATIC int     AdvISR(ADV_DVC_VAR *);
+STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
+STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
+STATIC int     AdvResetSB(ADV_DVC_VAR *);
+
+/*
+ * Internal Adv Library functions.
+ */
+STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ulong, int);
+STATIC void   AdvResetChip(ADV_DVC_VAR *);
+STATIC int    AdvSendScsiCmd(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
+STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
+STATIC int    AdvInitFromEEP(ADV_DVC_VAR *);
+STATIC ushort AdvGetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
+STATIC void   AdvSetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
+STATIC void   AdvWaitEEPCmd(AdvPortAddr);
+STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
+STATIC void   AdvResetSCSIBus(ADV_DVC_VAR *);
+
+/*
+ * PCI Bus Definitions
+ */
+#define AscPCICmdRegBits_BusMastering     0x0007
+#define AscPCICmdRegBits_ParErrRespCtrl   0x0040
+
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
+
+/* Read byte from a register. */
+#define AdvReadByteRegister(iop_base, reg_off) \
+     (inp((iop_base) + (reg_off)))
+
+/* Write byte to a register. */
+#define AdvWriteByteRegister(iop_base, reg_off, byte) \
+     (outp((iop_base) + (reg_off), (byte)))
+
+/* Read word (2 bytes) from a register. */
+#define AdvReadWordRegister(iop_base, reg_off) \
+     (inpw((iop_base) + (reg_off)))
+
+/* Write word (2 bytes) to a register. */
+#define AdvWriteWordRegister(iop_base, reg_off, word) \
+     (outpw((iop_base) + (reg_off), (word)))
+
+/* Read byte from LRAM. */
+#define AdvReadByteLram(iop_base, addr, byte) \
+do { \
+    outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \
+    (byte) = inp((iop_base) + IOPB_RAM_DATA); \
+} while (0)
+
+/* Write byte to LRAM. */
+#define AdvWriteByteLram(iop_base, addr, byte) \
+    (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
+     outp((iop_base) + IOPB_RAM_DATA, (byte)))
+
+/* Read word (2 bytes) from LRAM. */
+#define AdvReadWordLram(iop_base, addr, word) \
+do { \
+    outpw((iop_base) + IOPW_RAM_ADDR, (addr));  \
+    (word) = inpw((iop_base) + IOPW_RAM_DATA); \
+} while (0)
+
+/* Write word (2 bytes) to LRAM. */
+#define AdvWriteWordLram(iop_base, addr, word) \
+    (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
+     outpw((iop_base) + IOPW_RAM_DATA, (word)))
+
+/* Write double word (4 bytes) to LRAM */
+/* Because of unspecified C language ordering don't use auto-increment. */
+#define AdvWriteDWordLram(iop_base, addr, dword) \
+    ((outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
+      outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword) & 0xFFFF))), \
+     (outpw((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
+      outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword >> 16) & 0xFFFF))))
+
+/* Read word (2 bytes) from LRAM assuming that the address is already set. */
+#define AdvReadWordAutoIncLram(iop_base) \
+     (inpw((iop_base) + IOPW_RAM_DATA))
+
+/* Write word (2 bytes) to LRAM assuming that the address is already set. */
+#define AdvWriteWordAutoIncLram(iop_base, word) \
+     (outpw((iop_base) + IOPW_RAM_DATA, (word)))
+
+#else /* version >= v1,3,0 */
+
+/* Read byte from a register. */
+#define AdvReadByteRegister(iop_base, reg_off) \
+     (ADV_MEM_READB((iop_base) + (reg_off)))
+
+/* Write byte to a register. */
+#define AdvWriteByteRegister(iop_base, reg_off, byte) \
+     (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
+
+/* Read word (2 bytes) from a register. */
+#define AdvReadWordRegister(iop_base, reg_off) \
+     (ADV_MEM_READW((iop_base) + (reg_off)))
+
+/* Write word (2 bytes) to a register. */
+#define AdvWriteWordRegister(iop_base, reg_off, word) \
+     (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
+
+/* Read byte from LRAM. */
+#define AdvReadByteLram(iop_base, addr, byte) \
+do { \
+    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
+    (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
+} while (0)
+
+/* Write byte to LRAM. */
+#define AdvWriteByteLram(iop_base, addr, byte) \
+    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
+     ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
+
+/* Read word (2 bytes) from LRAM. */
+#define AdvReadWordLram(iop_base, addr, word) \
+do { \
+    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
+    (word) = ADV_MEM_READW((iop_base) + IOPW_RAM_DATA); \
+} while (0)
+
+/* Write word (2 bytes) to LRAM. */
+#define AdvWriteWordLram(iop_base, addr, word) \
+    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
+     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
+
+/* Write double word (4 bytes) to LRAM */
+/* Because of unspecified C language ordering don't use auto-increment. */
+#define AdvWriteDWordLram(iop_base, addr, dword) \
+    ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
+      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
+                     (ushort) ((dword) & 0xFFFF))), \
+     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
+      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
+                     (ushort) ((dword >> 16) & 0xFFFF))))
+
+/* Read word (2 bytes) from LRAM assuming that the address is already set. */
+#define AdvReadWordAutoIncLram(iop_base) \
+     (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
+
+/* Write word (2 bytes) to LRAM assuming that the address is already set. */
+#define AdvWriteWordAutoIncLram(iop_base, word) \
+     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
+
+#endif /* version >= v1,3,0 */
+
+/*
+ * Define macro to check for Condor signature.
+ *
+ * Evaluate to ADV_TRUE if a Condor chip is found the specified port
+ * address 'iop_base'. Otherwise evalue to ADV_FALSE.
+ */
+#define AdvFindSignature(iop_base) \
+    (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
+    ADV_CHIP_ID_BYTE) && \
+     (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
+    ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
+
+/*
+ * Define macro to Return the version number of the chip at 'iop_base'.
+ *
+ * The second parameter 'bus_type' is currently unused.
+ */
+#define AdvGetChipVersion(iop_base, bus_type) \
+    AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
+
+/*
+ * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
+ * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
+ * 
+ * If the request has not yet been sent to the device it will simply be
+ * aborted from RISC memory. If the request is disconnected it will be
+ * aborted on reselection by sending an Abort Message to the target ID.
+ *
+ * Return value:
+ *      ADV_TRUE(1) - Queue was successfully aborted.
+ *      ADV_FALSE(0) - Queue was not found on the active queue list.
+ */
+#define AdvAbortSRB(asc_dvc, srb_ptr) \
+    AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
+                (ulong) (srb_ptr), 0)
+
+/*
+ * Send a Bus Device Reset Message to the specified target ID.
+ *
+ * All outstanding commands will be purged if sending the
+ * Bus Device Reset Message is successful.
+ *
+ * Return Value:
+ *      ADV_TRUE(1) - All requests on the target are purged.
+ *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
+ *                     are not purged.
+ */
+#define AdvResetDevice(asc_dvc, target_id) \
+        AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
+                    (ulong) (target_id), 0)
+
+/*
+ * SCSI Wide Type definition.
+ */
+#define ADV_SCSI_BIT_ID_TYPE   ushort
+
+/*
+ * AdvInitScsiTarget() 'cntl_flag' options.
+ */
+#define ADV_SCAN_LUN           0x01
+#define ADV_CAPINFO_NOLUN      0x02
+
+/*
+ * Convert target id to target id bit mask.
+ */
+#define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
+
+/*
+ * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
+ */
+
+#define QD_NO_STATUS         0x00       /* Request not completed yet. */
+#define QD_NO_ERROR          0x01
+#define QD_ABORTED_BY_HOST   0x02
+#define QD_WITH_ERROR        0x04
+
+#define QHSTA_NO_ERROR              0x00
+#define QHSTA_M_SEL_TIMEOUT         0x11
+#define QHSTA_M_DATA_OVER_RUN       0x12
+#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
+#define QHSTA_M_QUEUE_ABORTED       0x15
+#define QHSTA_M_SXFR_SDMA_ERR       0x16 /* SXFR_STATUS SCSI DMA Error */
+#define QHSTA_M_SXFR_SXFR_PERR      0x17 /* SXFR_STATUS SCSI Bus Parity Error */
+#define QHSTA_M_RDMA_PERR           0x18 /* RISC PCI DMA parity error */
+#define QHSTA_M_SXFR_OFF_UFLW       0x19 /* SXFR_STATUS Offset Underflow */
+#define QHSTA_M_SXFR_OFF_OFLW       0x20 /* SXFR_STATUS Offset Overflow */
+#define QHSTA_M_SXFR_WD_TMO         0x21 /* SXFR_STATUS Watchdog Timeout */
+#define QHSTA_M_SXFR_DESELECTED     0x22 /* SXFR_STATUS Deselected */
+/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
+#define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
+#define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
+#define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
+#define QHSTA_M_WTM_TIMEOUT         0x41
+#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
+#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
+#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
+#define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
+
+typedef int (* ADV_ISR_CALLBACK)
+    (ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
+
+typedef int (* ADV_SBRESET_CALLBACK)
+    (ADV_DVC_VAR *);
+
+/*
+ * Default EEPROM Configuration structure defined in a_init.c.
+ */
+extern ADVEEP_CONFIG Default_EEPROM_Config;
+
+/*
+ * DvcGetPhyAddr() flag arguments
+ */
+#define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
+#define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
+#define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
+#define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
+#define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
+
+/* 'IS_SCSIQ_FLAG is now obsolete; Instead use ADV_IS_SCSIQ_FLAG. */
+#define IS_SCSIQ_FLAG           ADV_IS_SCSIQ_FLAQ
+
+
+/* Return the address that is aligned at the next doubleword >= to 'addr'. */
+#define ADV_DWALIGN(addr)       (((ulong) (addr) + 0x3) & ~0x3)
+
+/*
+ * Total contiguous memory needed for driver SG blocks.
+ *
+ * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
+ * number of scatter-gather elements the driver supports in a
+ * single request.
+ */
+
+#ifndef ADV_MAX_SG_LIST
+Forced Error: Driver must define ADV_MAX_SG_LIST.
+#endif /* ADV_MAX_SG_LIST */
+
+#define ADV_SG_LIST_MAX_BYTE_SIZE \
+         (sizeof(ADV_SG_BLOCK) * \
+          ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
+
+/*
+ * A driver may optionally define the assertion macro ADV_ASSERT() in
+ * its d_os_dep.h file. If the macro has not already been defined,
+ * then define the macro to a no-op.
+ */
+#ifndef ADV_ASSERT
+#define ADV_ASSERT(a)
+#endif /* ADV_ASSERT */
+
+
+/*
  * --- Driver Constants and Macros
  */
 
-#define ASC_NUM_BOARD_SUPPORTED 4
+#define ASC_NUM_BOARD_SUPPORTED 16
+#define ASC_NUM_IOPORT_PROBE    4
 #define ASC_NUM_BUS             4
 
 /* Reference Scsi_Host hostdata */
@@ -2155,22 +3192,27 @@
 /* asc_board_t flags */
 #define ASC_HOST_IN_RESET       0x01
 #define ASC_HOST_IN_ABORT       0x02
+#define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
+#define ASC_SELECT_QUEUE_DEPTHS 0x08
+
+#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
+#define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
 
 #define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
 
 /*
- * If the Linux kernel version supports throwing away initialization code
+ * If the Linux kernel version supports freeing initialization code
  * and data after loading, define macros for this purpose. These macros
  * are not used when the driver is built as a module, cf. linux/init.h.
  */
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,23)
-#define ASC_INITFUNC(func)      __initfunc(func)
-#define ASC_INITDATA            __initdata
-#define ASC_INIT                __init
-#else /* version >= v2.1.23 */
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,23)
 #define ASC_INITFUNC(func)      func
 #define ASC_INITDATA
 #define ASC_INIT
+#else /* version >= v2.1.23 */
+#define ASC_INITFUNC(func)      __initfunc(func)
+#define ASC_INITDATA            __initdata
+#define ASC_INIT                __init
 #endif /* version >= v2.1.23 */
 
 #define ASC_INFO_SIZE           128            /* advansys_info() line size */
@@ -2216,11 +3258,11 @@
  *  REQTIMESTAMP() - system time stamp value
  */
 typedef Scsi_Cmnd            REQ, *REQP;
-#define REQPNEXT(reqp)        ((REQP) ((reqp)->host_scribble))
-#define REQPNEXTP(reqp)        ((REQP *) &((reqp)->host_scribble))
+#define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
+#define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
 #define REQPTID(reqp)        ((reqp)->target)
-#define REQPTIME(reqp)        ((reqp)->SCp.this_residual)
-#define REQTIMESTAMP()        (jiffies)
+#define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
+#define REQTIMESTAMP()       (jiffies)
 
 #define REQTIMESTAT(function, ascq, reqp, tid) \
 { \
@@ -2253,7 +3295,7 @@
 }
 
 /* asc_enqueue() flags */
-#define ASC_FRONT        1
+#define ASC_FRONT       1
 #define ASC_BACK        2
 
 /* asc_dequeue_list() argument */
@@ -2316,6 +3358,7 @@
 #define ASC_PCI_DEVICE_ID_1100  0x1100
 #define ASC_PCI_DEVICE_ID_1200  0x1200
 #define ASC_PCI_DEVICE_ID_1300  0x1300
+#define ASC_PCI_DEVICE_ID_2300  0x2300
 
 /* PCI IO Port Addresses to generate special cycle */
 
@@ -2397,8 +3440,10 @@
 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
-#define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp)
-#define ASC_DBG_PRT_QDONE_INFO(lvl, qdone)
+#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
+#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
+#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
+#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
@@ -2462,17 +3507,24 @@
         } \
     }
 
-#define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp) \
+#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
+    { \
+        if (asc_dbglvl >= (lvl)) { \
+            asc_prt_asc_scsi_q(scsiqp); \
+        } \
+    }
+
+#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
     { \
         if (asc_dbglvl >= (lvl)) { \
-            asc_prt_scsi_q(scsiqp); \
+            asc_prt_asc_qdone_info(qdone); \
         } \
     }
 
-#define ASC_DBG_PRT_QDONE_INFO(lvl, qdone) \
+#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
     { \
         if (asc_dbglvl >= (lvl)) { \
-            asc_prt_qdone_info(qdone); \
+            asc_prt_adv_scsi_req_q(scsiqp); \
         } \
     }
 
@@ -2522,15 +3574,17 @@
     ulong     abort;           /* # calls to advansys_abort() */
     ulong     reset;           /* # calls to advansys_reset() */
     ulong     biosparam;       /* # calls to advansys_biosparam() */
-    ulong     check_interrupt; /* # advansys_interrupt() check pending calls */
-    ulong     interrupt;       /* # advansys_interrupt() interrupts */
-    ulong     callback;        /* # calls asc_isr_callback() */
-    ulong     done;            /* # calls request scsi_done */
-    /* AscExeScsiQueue() Statistics */
-    ulong     asc_noerror;     /* # AscExeScsiQueue() ASC_NOERROR returns. */
-    ulong     asc_busy;        /* # AscExeScsiQueue() ASC_BUSY returns. */
-    ulong     asc_error;       /* # AscExeScsiQueue() ASC_ERROR returns. */
-    ulong     asc_unknown;     /* # AscExeScsiQueue() unknown returns. */
+    ulong     interrupt;       /* # advansys_interrupt() calls */
+    ulong     callback;        /* # calls to asc/adv_isr_callback() */
+    ulong     done;            /* # calls to request's scsi_done function */
+    ulong     build_error;     /* # asc/adv_build_req() ASC_ERROR returns. */
+    ulong     adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
+    ulong     adv_build_nosg;  /* # adv_build_req() adv_sgblk_t alloc. fail. */
+    /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
+    ulong     exe_noerror;     /* # ASC_NOERROR returns. */
+    ulong     exe_busy;        /* # ASC_BUSY returns. */
+    ulong     exe_error;       /* # ASC_ERROR returns. */
+    ulong     exe_unknown;     /* # unknown returns. */
     /* Data Transfer Statistics */
     ulong     cont_cnt;        /* # non-scatter-gather I/O requests received */
     ulong     cont_xfer;       /* # contiguous transfer 512-bytes */
@@ -2544,20 +3598,49 @@
  * Request queuing structure
  */
 typedef struct asc_queue {
-    ASC_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
-    REQP                  q_first[ASC_MAX_TID+1];   /* first queued request */
-    REQP                  q_last[ASC_MAX_TID+1];    /* last queued request */
+    ADV_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
+    REQP                  q_first[ADV_MAX_TID+1];   /* first queued request */
+    REQP                  q_last[ADV_MAX_TID+1];    /* last queued request */
 #ifdef ADVANSYS_STATS
-    short                 q_cur_cnt[ASC_MAX_TID+1]; /* current queue count */
-    short                 q_max_cnt[ASC_MAX_TID+1]; /* maximum queue count */
-    ulong                 q_tot_cnt[ASC_MAX_TID+1]; /* total enqueue count */
-    ulong                 q_tot_tim[ASC_MAX_TID+1]; /* total time queued */
-    ushort                q_max_tim[ASC_MAX_TID+1]; /* maximum time queued */
-    ushort                q_min_tim[ASC_MAX_TID+1]; /* minimum time queued */
+    short                 q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
+    short                 q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
+    ulong                 q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
+    ulong                 q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
+    ushort                q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
+    ushort                q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
 #endif /* ADVANSYS_STATS */
 } asc_queue_t;
 
 /*
+ * Adv Library Request Structures
+ *
+ * The following two se structures are used to process Wide Board requests.
+ * One structure is needed for each command received from the Mid-Level SCSI
+ * driver.
+ *
+ * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
+ * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
+ * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
+ * Mid-Level SCSI request structure.
+ *
+ * The adv_sgblk_t structure is used to handle requests that include
+ * scatter-gather elements.
+ */
+typedef struct adv_sgblk {
+    ADV_SG_BLOCK        sg_block[ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING];
+    uchar               align2[4];       /* Sgblock structure padding. */
+    struct adv_sgblk    *next_sgblkp;    /* Next scatter-gather structure. */
+} adv_sgblk_t;
+
+typedef struct adv_req {
+    ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
+    uchar               align1[4];    /* Request structure padding. */
+    Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
+    adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
+    struct adv_req      *next_reqp;   /* Next Request Structure. */
+} adv_req_t;
+
+/*
  * Structure allocated for each board.
  *
  * This structure is allocated by scsi_register() at the end
@@ -2565,35 +3648,60 @@
  * field. It is guaranteed to be allocated from DMA-able memory.
  */
 typedef struct asc_board {
-    int                  id;                     /* Board Id */
-    uint                 flags;                  /* Board flags */
-    ASC_DVC_VAR          asc_dvc_var;            /* Board configuration */
-    ASC_DVC_CFG          asc_dvc_cfg;            /* Device configuration */
-    asc_queue_t          active;                 /* Active command queue */
-    asc_queue_t          waiting;                /* Waiting command queue */
-    asc_queue_t          done;                   /* Done command queue */
-    ASC_SCSI_BIT_ID_TYPE init_tidmask;           /* Target initialized mask */
-    /* The following three structures must be in DMA-able memory. */
-    ASC_SCSI_REQ_Q       scsireqq;
-    ASC_CAP_INFO         cap_info;
-    ASC_SCSI_INQUIRY     inquiry;
-    Scsi_Device          *device[ASC_MAX_TID+1]; /* Mid-Level Scsi Device */
-    ushort               reqcnt[ASC_MAX_TID+1];  /* Starvation request count */
-    uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
+    int                  id;                    /* Board Id */
+    uint                 flags;                 /* Board flags */
+    union {
+        ASC_DVC_VAR      asc_dvc_var;           /* Narrow board */
+        ADV_DVC_VAR      adv_dvc_var;           /* Wide board */
+    } dvc_var;
+    union {
+        ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
+        ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
+    } dvc_cfg;
+    asc_queue_t          active;                /* Active command queue */
+    asc_queue_t          waiting;               /* Waiting command queue */
+    asc_queue_t          done;                  /* Done command queue */
+    ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
+    Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
+    ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
 #if ASC_QUEUE_FLOW_CONTROL
-    ushort               nerrcnt[ASC_MAX_TID+1]; /* No error request count */
+    ushort               nerrcnt[ADV_MAX_TID+1]; /* No error request count */
 #endif /* ASC_QUEUE_FLOW_CONTROL */
-    ASC_SCSI_BIT_ID_TYPE queue_full;             /* Queue full mask */
-    ushort    queue_full_cnt[ASC_MAX_TID+1];     /* Queue full count */
-    ASCEEP_CONFIG        eep_config;             /* EEPROM configuration */
-    ulong                last_reset;             /* Saved last reset time */
+    ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
+    ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
+    union {
+        ASCEEP_CONFIG    asc_eep;               /* Narrow EEPROM config. */
+        ADVEEP_CONFIG    adv_eep;               /* Wide EEPROM config. */
+    } eep_config;
+    ulong                last_reset;            /* Saved last reset time */
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
     /* /proc/scsi/advansys/[0...] */
-    char                 *prtbuf;                /* Statistics Print Buffer */
+    char                 *prtbuf;               /* Statistics Print Buffer */
 #endif /* version >= v1.3.0 */
 #ifdef ADVANSYS_STATS
-    struct asc_stats     asc_stats;              /* Board statistics */
+    struct asc_stats     asc_stats;             /* Board statistics */
 #endif /* ADVANSYS_STATS */
+    /*
+     * The following fields are used only for Narrow Boards.
+     */
+    /* The following three structures must be in DMA-able memory. */
+    ASC_SCSI_REQ_Q       scsireqq;
+    ASC_CAP_INFO         cap_info;
+    ASC_SCSI_INQUIRY     inquiry;
+    uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
+    /*
+     * The following fields are used only for Wide Boards.
+     */
+    void                 *ioremap_addr;         /* I/O Memory remap address. */
+    ushort               ioport;                /* I/O Port address. */
+    adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
+    adv_req_t            *adv_reqp;             /* Request structures. */
+    adv_sgblk_t          *orig_sgblkp;          /* adv_sgblk_t memory block. */
+    adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
+    ushort               bios_signature;        /* BIOS Signature. */
+    ushort               bios_version;          /* BIOS Version. */
+    ushort               bios_codeseg;          /* BIOS Code Segment. */
+    ushort               bios_codelen;          /* BIOS Code Segment Length. */
 } asc_board_t;
 
 /*
@@ -2655,10 +3763,10 @@
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
 struct proc_dir_entry proc_scsi_advansys =
 {
-    PROC_SCSI_ADVANSYS,                /* unsigned short low_ino */
-    8,                                /* unsigned short namelen */
-    "advansys",                        /* const char *name */
-    S_IFDIR | S_IRUGO | S_IXUGO,    /* mode_t mode */
+    PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
+    8,                               /* unsigned short namelen */
+    "advansys",                      /* const char *name */
+    S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
     2                                /* nlink_t nlink */
 };
 #endif /* version >= v1.3.0 */
@@ -2691,7 +3799,18 @@
  * limit I/O port probing at boot time, cf. advansys_setup().
  */
 STATIC int asc_iopflag = ASC_FALSE;
-STATIC int asc_ioport[ASC_NUM_BOARD_SUPPORTED] = { 0, 0, 0, 0 };
+STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
+
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
+/*
+ * In kernels earlier than v1.3.0, kmalloc() does not work
+ * during driver initialization. Therefore statically declare
+ * 16 elements of each structure. v1.3.0 kernels will probably
+ * not need any more than this number.
+ */
+uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 };
+uchar adv_sgblk_buf[16 * sizeof(adv_sgblk_t)] = { 0 };
+#endif /* version >= v1,3,0 */
 
 #ifdef ADVANSYS_DEBUG
 STATIC char *
@@ -2727,47 +3846,59 @@
 STATIC void         advansys_select_queue_depths(struct Scsi_Host *,
                                                 Scsi_Device *);
 #endif /* version >= v1.3.89 */
-STATIC void         advansys_command_done(Scsi_Cmnd *);
-STATIC void         asc_scsi_done_list(Scsi_Cmnd *);
-STATIC int          asc_execute_scsi_cmnd(Scsi_Cmnd *);
-STATIC void         asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
-STATIC int          asc_init_dev(ASC_DVC_VAR *, Scsi_Cmnd *);
-STATIC int          asc_srch_pci_dev(PCI_DEVICE *);
-STATIC uchar        asc_scan_method(void);
-STATIC int          asc_pci_find_dev(PCI_DEVICE *);
-STATIC void         asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
-STATIC ushort       asc_get_cfg_word(PCI_DATA *);
-STATIC uchar        asc_get_cfg_byte(PCI_DATA *);
-STATIC void         asc_put_cfg_byte(PCI_DATA *, uchar);
-STATIC void         asc_enqueue(asc_queue_t *, REQP, int);
-STATIC REQP         asc_dequeue(asc_queue_t *, int);
-STATIC REQP         asc_dequeue_list(asc_queue_t *, REQP *, int);
-STATIC int          asc_rmqueue(asc_queue_t *, REQP);
-STATIC int          asc_isqueued(asc_queue_t *, REQP);
-STATIC void         asc_execute_queue(asc_queue_t *);
+STATIC void       advansys_command_done(Scsi_Cmnd *);
+STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
+STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
+STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
+STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
+STATIC int        adv_get_sglist(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, Scsi_Cmnd *);
+STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
+STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
+STATIC int        asc_init_dev(ASC_DVC_VAR *, Scsi_Cmnd *);
+STATIC int        asc_srch_pci_dev(PCI_DEVICE *);
+STATIC uchar      asc_scan_method(void);
+STATIC int        asc_pci_find_dev(PCI_DEVICE *);
+STATIC void       asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
+STATIC ushort     asc_get_cfg_word(PCI_DATA *);
+STATIC uchar      asc_get_cfg_byte(PCI_DATA *);
+STATIC void       asc_put_cfg_byte(PCI_DATA *, uchar);
+STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
+STATIC REQP       asc_dequeue(asc_queue_t *, int);
+STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
+STATIC int        asc_rmqueue(asc_queue_t *, REQP);
+STATIC int        asc_isqueued(asc_queue_t *, REQP);
+STATIC void       asc_execute_queue(asc_queue_t *);
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
-STATIC int            asc_prt_board_devices(struct Scsi_Host *, char *, int);
-STATIC int            asc_prt_board_eeprom(struct Scsi_Host *, char *, int);
-STATIC int            asc_prt_driver_conf(struct Scsi_Host *, char *, int);
-STATIC int            asc_prt_board_info(struct Scsi_Host *, char *, int);
-STATIC int            asc_prt_line(char *, int, char *fmt, ...);
+STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
+STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
+STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
+STATIC int        asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
+STATIC int        asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
+STATIC int        asc_prt_driver_conf(struct Scsi_Host *, char *, int);
+STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
+STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
+STATIC int        asc_prt_line(char *, int, char *fmt, ...);
 #endif /* version >= v1.3.0 */
 
 /* Declaration for Asc Library internal functions reference by driver. */
-STATIC int            AscFindSignature(PortAddr);
-STATIC ushort         AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
+STATIC int          AscFindSignature(PortAddr);
+STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
 
 #ifdef ADVANSYS_STATS
-STATIC int            asc_prt_board_stats(struct Scsi_Host *, char *, int);
+STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
 #endif /* ADVANSYS_STATS */
 
 #ifdef ADVANSYS_DEBUG
 STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
 STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
-STATIC void         asc_prt_dvc_cfg(ASC_DVC_CFG *);
-STATIC void         asc_prt_dvc_var(ASC_DVC_VAR *);
-STATIC void         asc_prt_scsi_q(ASC_SCSI_Q *);
-STATIC void         asc_prt_qdone_info(ASC_QDONE_INFO *);
+STATIC void         asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
+STATIC void         asc_prt_asc_dvc_var(ASC_DVC_VAR *);
+STATIC void         asc_prt_asc_scsi_q(ASC_SCSI_Q *);
+STATIC void         asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
+STATIC void         asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
+STATIC void         asc_prt_adv_dvc_var(ADV_DVC_VAR *);
+STATIC void         asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
+STATIC void         asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
 STATIC void         asc_prt_hex(char *f, uchar *, int);
 #endif /* ADVANSYS_DEBUG */
 
@@ -2815,7 +3946,7 @@
     int                 leftlen;
     char                *curbuf;
     off_t               advoffset;
-    Scsi_Device         *scd = NULL;
+    Scsi_Device         *scd;
 
     ASC_DBG(1, "advansys_proc_info: begin\n");
 
@@ -2870,6 +4001,24 @@
     curbuf += cnt;
 
     /*
+     * Display Wide Board BIOS Information.
+     */
+    if (ASC_WIDE_BOARD(boardp)) {
+        cp = boardp->prtbuf;
+        cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
+        ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
+        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
+        totcnt += cnt;
+        leftlen -= cnt;
+        if (leftlen == 0) {
+            ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
+            return totcnt;
+        }
+        advoffset += cplen;
+        curbuf += cnt;
+    }
+
+    /*
      * Display driver information for each device attached to the board.
      */
     cp = boardp->prtbuf;
@@ -2889,7 +4038,13 @@
      * Display target driver information for each device attached
      * to the board.
      */
-    for (scd = scd->host->host_queue; scd; scd = scd->next) {
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75)
+    for (scd = scsi_devices; scd; scd = scd->next)
+#else /* version >= v2.1.75 */
+    for (scd = shp->host_queue; scd; scd = scd->next)
+#endif /* version >= v2.1.75 */
+    {
+        if (scd->host == shp) {
             cp = boardp->prtbuf;
             /*
              * Note: If proc_print_scsidevice() writes more than
@@ -2906,13 +4061,18 @@
             }
             advoffset += cplen;
             curbuf += cnt;
+        }
     }
     
     /*
      * Display EEPROM configuration for the board.
      */
     cp = boardp->prtbuf;
-    cplen = asc_prt_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
+    if (ASC_NARROW_BOARD(boardp)) {
+        cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
+    } else {
+        cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
+    }
     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
     totcnt += cnt;
@@ -2963,7 +4123,11 @@
      * for the board.
      */
     cp = boardp->prtbuf;
-    cplen = asc_prt_board_info(shp, cp, ASC_PRTBUF_SIZE);
+    if (ASC_NARROW_BOARD(boardp)) {
+        cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
+    } else {
+        cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
+    }
     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
     totcnt += cnt;
@@ -2981,7 +4145,6 @@
 }
 #endif /* version >= v1.3.0 */
 
-
 /*
  * advansys_detect()
  *
@@ -3005,17 +4168,19 @@
     int                 bus;
     struct Scsi_Host    *shp;
     asc_board_t         *boardp;
-    ASC_DVC_VAR         *asc_dvc_varp;
+    ASC_DVC_VAR         *asc_dvc_varp = NULL;
+    ADV_DVC_VAR         *adv_dvc_varp = NULL;
     int                 ioport = 0;
     int                 share_irq = FALSE;
     PCI_DEVICE          pciDevice;
     PCI_CONFIG_SPACE    pciConfig;
+    int                 warn_code, err_code;
     int                 ret;
 
     if (detect_called == ASC_FALSE) {
         detect_called = ASC_TRUE;
     } else {
-        printk("AdvanSys SCSI: advansys_detect() mulitple calls ignored\n");
+        printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
         return 0;
     }
 
@@ -3032,7 +4197,7 @@
      * clean-up the 'asc_ioport' list.
      */
     if (asc_iopflag == ASC_TRUE) {
-        for (ioport = 0; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
+        for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
             ASC_DBG2(1, "advansys_detect: asc_ioport[%d] %x\n",
                 ioport, asc_ioport[ioport]);
             if (asc_ioport[ioport] != 0) {
@@ -3042,7 +4207,8 @@
                     }
                 }
                 if (iop == ASC_IOADR_TABLE_MAX_IX) {
-                    printk("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
+                    printk(
+"AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
                         asc_ioport[ioport]);
                     asc_ioport[ioport] = 0;
                 }
@@ -3082,7 +4248,7 @@
                     ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
                 ioport_try_again:
                     iop = 0;
-                    for (; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
+                    for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
                         if ((iop = asc_ioport[ioport]) != 0) {
                             break;
                         }
@@ -3091,12 +4257,14 @@
                         ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
                             iop);
                         if (check_region(iop, ASC_IOADR_GAP) != 0) {
-                            printk("AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
+                            printk(
+"AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
                             /* Don't try this I/O port twice. */
                             asc_ioport[ioport] = 0;
                             goto ioport_try_again;
                         } else if (AscFindSignature(iop) == ASC_FALSE) {
-                            printk("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
+                            printk(
+"AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
                             /* Don't try this I/O port twice. */
                             asc_ioport[ioport] = 0;
                             goto ioport_try_again;
@@ -3142,7 +4310,10 @@
                             pciDevice.slotFound, pciDevice.busNumber);
                         asc_get_pci_cfg(&pciDevice, &pciConfig);
                         iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
-                        ASC_DBG2(2, "advansys_detect: iop %x, irqLine %d\n",
+                        ASC_DBG2(1,
+                            "advansys_detect: vendorID %X, deviceID %X\n",
+                            pciConfig.vendorID, pciConfig.deviceID);
+                        ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
                             iop, pciConfig.irqLine);
                     }
                 break;
@@ -3177,13 +4348,76 @@
             boardp = ASC_BOARDP(shp);
             memset(boardp, 0, sizeof(asc_board_t));
             boardp->id = asc_board_count - 1;
-            asc_dvc_varp = &boardp->asc_dvc_var;
-            asc_dvc_varp->drv_ptr = (ulong) boardp;
-            asc_dvc_varp->cfg = &boardp->asc_dvc_cfg;
-            asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
-            asc_dvc_varp->iop_base = iop;
+
+            /*
+             * Handle both narrow and wide PCI boards.
+             *
+             * If a Wide board was detected, set the board structure
+             * wide board flag. Set-up the board structure based on
+             * the board type.
+             */
+            if ((asc_bus[bus] == ASC_IS_PCI &&
+                 pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300) == 0) {
+                ASC_DBG(1, "advansys_detect: narrow board\n");
+                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
+                asc_dvc_varp->bus_type = asc_bus[bus];
+                asc_dvc_varp->drv_ptr = (ulong) boardp;
+                asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
+                asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
+                asc_dvc_varp->iop_base = iop;
+                asc_dvc_varp->isr_callback = (Ptr2Func) asc_isr_callback;
+            } else {
+                ASC_DBG(1, "advansys_detect: wide board\n");
+                boardp->flags |= ASC_IS_WIDE_BOARD;
+                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
+                adv_dvc_varp->drv_ptr = (ulong) boardp;
+                adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
+                adv_dvc_varp->isr_callback = (Ptr2Func) adv_isr_callback;
+
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
+                adv_dvc_varp->iop_base = iop;
+#else /* version >= v1,3,0 */
+                /*
+                 * Map the board's registers into virtual memory for
+                 * PCI slave access. Only memory accesses are used to
+                 * access the board's registers.
+                 *
+                 * Note: The PCI register base address is not always
+                 * page aligned, but the address passed to ioremap()
+                 * must be page aligned. It is guaranteed that the
+                 * PCI register base address will not cross a page
+                 * boundary.
+                 */
+                if ((boardp->ioremap_addr =
+                    ioremap(pciConfig.baseAddress[1] & PAGE_MASK,
+                         PAGE_SIZE)) == 0) {
+                   ASC_PRINT3(
+"advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",
+                   boardp->id, pciConfig.baseAddress[1], ADV_CONDOR_IOLEN);
+                   scsi_unregister(shp);
+                   asc_board_count--;
+                   continue;
+                }
+                adv_dvc_varp->iop_base = (AdvPortAddr)
+                    (boardp->ioremap_addr +
+                     (pciConfig.baseAddress[1] -
+                      (pciConfig.baseAddress[1] & PAGE_MASK)));
+#endif /* version >= v1,3,0 */
+
+                /*
+                 * Even though it isn't used to access the board in
+                 * kernels greater than or equal to v1.3.0, save
+                 * the I/O Port address so that it can be reported and
+                 * displayed.
+                 */
+                boardp->ioport = iop;
+            }
 
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+            /*
+             * Allocate buffer for printing information from
+             * /proc/scsi/advansys/[0...].
+             */
             if ((boardp->prtbuf =
                 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
                 ASC_PRINT3(
@@ -3195,90 +4429,122 @@
             }
 #endif /* version >= v1.3.0 */
 
-            /*
-             * Set the board bus type and PCI IRQ for AscInitGetConfig().
-             */
-            asc_dvc_varp->bus_type = asc_bus[bus];
-            switch (asc_dvc_varp->bus_type) {
-            case ASC_IS_ISA:
-                shp->unchecked_isa_dma = TRUE;
-                share_irq = FALSE;
-                break;
-            case ASC_IS_VL:
-                shp->unchecked_isa_dma = FALSE;
-                share_irq = FALSE;
-                break;
-            case ASC_IS_EISA:
-                shp->unchecked_isa_dma = FALSE;
-                share_irq = TRUE;
-                break;
-            case ASC_IS_PCI:
-                shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine;
-                asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
-                asc_dvc_varp->cfg->pci_slot_info =
+            if (ASC_NARROW_BOARD(boardp)) {
+                /*
+                 * Set the board bus type and PCI IRQ before
+                 * calling AscInitGetConfig().
+                 */
+                switch (asc_dvc_varp->bus_type) {
+                case ASC_IS_ISA:
+                    shp->unchecked_isa_dma = TRUE;
+                    share_irq = FALSE;
+                    break;
+                case ASC_IS_VL:
+                    shp->unchecked_isa_dma = FALSE;
+                    share_irq = FALSE;
+                    break;
+                case ASC_IS_EISA:
+                    shp->unchecked_isa_dma = FALSE;
+                    share_irq = TRUE;
+                    break;
+                case ASC_IS_PCI:
+                    shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine;
+                    shp->unchecked_isa_dma = FALSE;
+                    share_irq = TRUE;
+                    asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
+                    asc_dvc_varp->cfg->pci_slot_info =
                         ASC_PCI_MKID(pciDevice.busNumber,
-                                     pciDevice.slotFound,
-                                     pciDevice.devFunc);
+                            pciDevice.slotFound,
+                            pciDevice.devFunc);
+                    break;
+                default:
+                    ASC_PRINT2(
+"advansys_detect: board %d: unknown adapter type: %d\n",
+                        boardp->id, asc_dvc_varp->bus_type);
+                    shp->unchecked_isa_dma = TRUE;
+                    share_irq = FALSE;
+                    break;
+                }
+            } else {
+                /*
+                 * For Wide boards set PCI information before calling
+                 * AdvInitGetConfig().
+                 */
+                shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine;
                 shp->unchecked_isa_dma = FALSE;
                 share_irq = TRUE;
-                break;
-            default:
-                ASC_PRINT2(
-"advansys_detect: board %d: unknown adapter type: %d",
-                    boardp->id, asc_dvc_varp->bus_type);
-                shp->unchecked_isa_dma = TRUE;
-                share_irq = FALSE;
-                break;
+                adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
+                adv_dvc_varp->cfg->pci_slot_info =
+                    ASC_PCI_MKID(pciDevice.busNumber,
+                        pciDevice.slotFound,
+                        pciDevice.devFunc);
             }
 
             /*
-             * Get the board configuration.
-             *
-             * NOTE: AscInitGetConfig() may change the board's bus_type
-             * value. The asc_bus[bus] value should no longer be used. If
-             * the bus_type field must be referenced only use the bit-wise
-             * AND operator "&".
+             * Read the board configuration.
              */
-            ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
-            switch(ret = AscInitGetConfig(asc_dvc_varp)) {
-            case 0:    /* No error */
-                break;
-            case ASC_WARN_IO_PORT_ROTATE:
-                ASC_PRINT1(
+            if (ASC_NARROW_BOARD(boardp)) {
+                 /*
+                  * NOTE: AscInitGetConfig() may change the board's
+                  * bus_type value. The asc_bus[bus] value should no
+                  * longer be used. If the bus_type field must be
+                  * referenced only use the bit-wise AND operator "&".
+                  */
+                 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
+                switch(ret = AscInitGetConfig(asc_dvc_varp)) {
+                case 0:    /* No error */
+                    break;
+                case ASC_WARN_IO_PORT_ROTATE:
+                    ASC_PRINT1(
 "AscInitGetConfig: board %d: I/O port address modified\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_AUTO_CONFIG:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_AUTO_CONFIG:
+                    ASC_PRINT1(
 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_EEPROM_CHKSUM:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_EEPROM_CHKSUM:
+                    ASC_PRINT1(
 "AscInitGetConfig: board %d: EEPROM checksum error\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_IRQ_MODIFIED:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_IRQ_MODIFIED:
+                    ASC_PRINT1(
 "AscInitGetConfig: board %d: IRQ modified\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_CMD_QNG_CONFLICT:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_CMD_QNG_CONFLICT:
+                    ASC_PRINT1(
 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
-                    boardp->id);
-                break;
-            default:
-                ASC_PRINT2(
+                        boardp->id);
+                    break;
+                default:
+                    ASC_PRINT2(
 "AscInitGetConfig: board %d: unknown warning: %x\n",
-                    boardp->id, ret);
-                break;
-            }
-            if (asc_dvc_varp->err_code != 0) {
-                ASC_PRINT3(
+                        boardp->id, ret);
+                    break;
+                }
+                if ((err_code = asc_dvc_varp->err_code) != 0) {
+                    ASC_PRINT3(
 "AscInitGetConfig: board %d error: init_state %x, err_code %x\n",
-                    boardp->id, asc_dvc_varp->init_state,
-                    asc_dvc_varp->err_code);
+                        boardp->id, asc_dvc_varp->init_state,
+                        asc_dvc_varp->err_code);
+                }
+            } else {
+                ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
+                if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
+                    ASC_PRINT2("AdvInitGetConfig: board %d: warning: %x\n",
+                        boardp->id, ret);
+                }
+                if ((err_code = adv_dvc_varp->err_code) != 0) {
+                    ASC_PRINT2(
+"AdvInitGetConfig: board %d error: err_code %x\n",
+                        boardp->id, adv_dvc_varp->err_code);
+                }
+            }
+        
+            if (err_code != 0) {
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                 kfree(boardp->prtbuf);
 #endif /* version >= v1.3.0 */
@@ -3288,110 +4554,180 @@
             }
 
             /*
-             * Set the adapter's target id bit in the init_tidmask field.
+             * Save the EEPROM configuration so that it can be displayed
+             * from /proc/scsi/advansys/[0...].
              */
-            boardp->init_tidmask |=
-                ASC_TIX_TO_TARGET_ID(asc_dvc_varp->cfg->chip_scsi_id);
+            if (ASC_NARROW_BOARD(boardp)) {
 
-            /*
-             * Save EEPROM settings for the board.
-             */
-            boardp->eep_config.init_sdtr = asc_dvc_varp->init_sdtr;
-            boardp->eep_config.disc_enable = asc_dvc_varp->cfg->disc_enable;
-            boardp->eep_config.use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
-            boardp->eep_config.isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed;
-            boardp->eep_config.start_motor = asc_dvc_varp->start_motor;
-            boardp->eep_config.cntl = asc_dvc_varp->dvc_cntl;
-            boardp->eep_config.no_scam = asc_dvc_varp->no_scam;
-            boardp->eep_config.max_total_qng = asc_dvc_varp->max_total_qng;
-            boardp->eep_config.chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id;
-            /* 'max_tag_qng' is set to the same value for every device. */
-            boardp->eep_config.max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
+                ASCEEP_CONFIG *ep;
 
-            /*
-             * Modify board configuration.
-             */
-            asc_dvc_varp->isr_callback = (Ptr2Func) asc_isr_callback;
-            asc_dvc_varp->exe_callback = (Ptr2Func) NULL;
+                /*
+                 * Set the adapter's target id bit in the 'init_tidmask' field.
+                 */
+                boardp->init_tidmask |=
+                    ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
 
-            ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
-            switch (ret = AscInitSetConfig(asc_dvc_varp)) {
-            case 0:    /* No error. */
-                break;
-            case ASC_WARN_IO_PORT_ROTATE:
-                ASC_PRINT1(
+                /*
+                 * Save EEPROM settings for the board.
+                 */
+                ep = &boardp->eep_config.asc_eep;
+
+                ep->init_sdtr = asc_dvc_varp->init_sdtr;
+                ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
+                ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
+                ep->isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed;
+                ep->start_motor = asc_dvc_varp->start_motor;
+                ep->cntl = asc_dvc_varp->dvc_cntl;
+                ep->no_scam = asc_dvc_varp->no_scam;
+                ep->max_total_qng = asc_dvc_varp->max_total_qng;
+                ep->chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id;
+                /* 'max_tag_qng' is set to the same value for every device. */
+                ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
+                ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
+                ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
+                ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
+                ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
+                ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
+                ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
+                ep->adapter_info[6] = asc_dvc_varp->cfg->adapter_info[6];
+
+               /*
+                * Modify board configuration.
+                */
+                ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
+                switch (ret = AscInitSetConfig(asc_dvc_varp)) {
+                case 0:    /* No error. */
+                    break;
+                case ASC_WARN_IO_PORT_ROTATE:
+                    ASC_PRINT1(
 "AscInitSetConfig: board %d: I/O port address modified\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_AUTO_CONFIG:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_AUTO_CONFIG:
+                    ASC_PRINT1(
 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_EEPROM_CHKSUM:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_EEPROM_CHKSUM:
+                    ASC_PRINT1(
 "AscInitSetConfig: board %d: EEPROM checksum error\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_IRQ_MODIFIED:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_IRQ_MODIFIED:
+                    ASC_PRINT1(
 "AscInitSetConfig: board %d: IRQ modified\n",
-                    boardp->id);
-                break;
-            case ASC_WARN_CMD_QNG_CONFLICT:
-                ASC_PRINT1(
+                        boardp->id);
+                    break;
+                case ASC_WARN_CMD_QNG_CONFLICT:
+                    ASC_PRINT1(
 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
-                    boardp->id);
-                break;
-            default:
-                ASC_PRINT2(
+                        boardp->id);
+                    break;
+                default:
+                    ASC_PRINT2(
 "AscInitSetConfig: board %d: unknown warning: %x\n",
-                    boardp->id, ret);
-                break;
-            }
-            if (asc_dvc_varp->err_code != 0) {
-                ASC_PRINT3(
+                        boardp->id, ret);
+                    break;
+                }
+                if (asc_dvc_varp->err_code != 0) {
+                    ASC_PRINT3(
 "AscInitSetConfig: board %d error: init_state %x, err_code %x\n",
-                    boardp->id, asc_dvc_varp->init_state,
-                    asc_dvc_varp->err_code);
+                        boardp->id, asc_dvc_varp->init_state,
+                        asc_dvc_varp->err_code);
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
-                kfree(boardp->prtbuf);
+                    kfree(boardp->prtbuf);
 #endif /* version >= v1.3.0 */
-                scsi_unregister(shp);
-                asc_board_count--;
-                continue;
-            }
+                    scsi_unregister(shp);
+                    asc_board_count--;
+                    continue;
+                }
 
-            /*
-             * Finish initializing the 'Scsi_Host' structure.
-             */
+                /*
+                 * Finish initializing the 'Scsi_Host' structure.
+                 */
+                /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
+                if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
+                    shp->irq = asc_dvc_varp->irq_no;
+                }
+            } else {
+
+                ADVEEP_CONFIG *ep;
+
+                /*
+                 * Save Wide EEP Configuration Information.
+                 */
+                ep = &boardp->eep_config.adv_eep;
+
+                ep->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
+                ep->max_host_qng = adv_dvc_varp->max_host_qng;
+                ep->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
+                ep->termination = adv_dvc_varp->cfg->termination;
+                ep->disc_enable = adv_dvc_varp->cfg->disc_enable;
+                ep->bios_ctrl = adv_dvc_varp->bios_ctrl;
+                ep->wdtr_able = adv_dvc_varp->wdtr_able;
+                ep->sdtr_able = adv_dvc_varp->sdtr_able;
+                ep->ultra_able = adv_dvc_varp->ultra_able;
+                ep->tagqng_able = adv_dvc_varp->tagqng_able;
+                ep->start_motor = adv_dvc_varp->start_motor;
+                ep->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
+                ep->bios_boot_delay = adv_dvc_varp->cfg->bios_boot_wait;
+                ep->serial_number_word1 = adv_dvc_varp->cfg->serial1;
+                ep->serial_number_word2 = adv_dvc_varp->cfg->serial2;
+                ep->serial_number_word3 = adv_dvc_varp->cfg->serial3;
+
+                /*
+                 * Set the adapter's target id bit in the 'init_tidmask' field.
+                 */
+                boardp->init_tidmask |=
+                    ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
 
-            /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
-            if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
-                shp->irq = asc_dvc_varp->irq_no;
+                /*
+                 * Finish initializing the 'Scsi_Host' structure.
+                 */
+                shp->irq = adv_dvc_varp->irq_no;
             }
 
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
             /*
-             * One host supports one channel. There are two different
-             * hosts for each channel of a dual channel board.
+             * Channels are numbered beginning with 0. For AdvanSys One host
+             * structure supports one channel. Multi-channel boards have a
+             * separate host structure for each channel. 
              */
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
             shp->max_channel = 0;
 #endif /* version >= v1.3.89 */
-            shp->max_id = ASC_MAX_TID + 1;
-            shp->max_lun = ASC_MAX_LUN + 1;
+            if (ASC_NARROW_BOARD(boardp)) {
+                shp->max_id = ASC_MAX_TID + 1;
+                shp->max_lun = ASC_MAX_LUN + 1;
+
+                shp->io_port = asc_dvc_varp->iop_base;
+                shp->n_io_port = ASC_IOADR_GAP;
+                shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
+
+                /* Set maximum number of queues the adapter can handle. */
+                shp->can_queue = asc_dvc_varp->max_total_qng;
+            } else {
+                shp->max_id = ADV_MAX_TID + 1;
+                shp->max_lun = ADV_MAX_LUN + 1;
+
+                /*
+                 * Save the I/O Port address and length even though the
+                 * in v1.3.0 and greater kernels the region is not used
+                 * by a Wide board. Instead the board is accessed with
+                 * Memory Mapped I/O.
+                 */
+                shp->io_port = iop;
+                shp->n_io_port = ADV_CONDOR_IOLEN;
 
-            shp->io_port = asc_dvc_varp->iop_base;
-            shp->n_io_port = ASC_IOADR_GAP;
-            shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
+                shp->this_id = adv_dvc_varp->chip_scsi_id;
 
-            /* Maximum number of queues this adapter can handle. */
-            shp->can_queue = asc_dvc_varp->max_total_qng;
+                /* Set maximum number of queues the adapter can handle. */
+                shp->can_queue = adv_dvc_varp->max_host_qng;
+            }
 
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
             /*
-             * Set a conservative 'cmd_per_lun' value to prevent memory
-             * allocation failures.
+             * In old kernels without tag queuing support and with memory
+             * allocation problems set a conservative 'cmd_per_lun' value.
              */
 #ifdef MODULE
             shp->cmd_per_lun = 1;
@@ -3401,54 +4737,54 @@
             ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
 #else /* version >= v1.3.89 */
             /*
-             * Use the host 'select_queue_depths' function to determine
-             * the number of commands to queue per device.
+             * Following v1.3.89, 'cmd_per_lun' is no longer needed
+             * and should be set to zero.
+             *
+             * But because of a bug introduced in v1.3.89 if the driver is
+             * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
+             * SCSI function 'allocate_device' will panic. To allow the driver
+             * to work as a module in these kernels set 'cmd_per_lun' to 1.
              */
-            shp->select_queue_depths = advansys_select_queue_depths;
-
 #ifdef MODULE
-	    /*
-	     * FIXME(eric) - this is completely bogus.  We need to
-	     * figure out what exactly the real problem is and deal
-	     * with it.
-	     */
-	    /*
-	     * Following v1.3.89, 'cmd_per_lun' is no longer needed
-	     * and should be set to zero. But because of a bug introduced
-	     * in v1.3.89 if the driver is compiled as a module and
-	     * 'cmd_per_lun' is zero, the Mid-Level SCSI function
-	     * 'scsi_allocate_device' will panic. To allow the driver to
-	     * work as a module in these kernels set 'cmd_per_lun' to 1.
-	     */
-	    shp->cmd_per_lun = 1;
+            shp->cmd_per_lun = 1;
 #else /* MODULE */
             shp->cmd_per_lun = 0;
 #endif /* MODULE */
+            /*
+             * Use the host 'select_queue_depths' function to determine
+             * the number of commands to queue per device.
+             */
+            shp->select_queue_depths = advansys_select_queue_depths;
 #endif /* version >= v1.3.89 */
 
             /*
-             * Set the maximum number of scatter-gather elements adapter
-             * can handle.
+             * Set the maximum number of scatter-gather elements the
+             * adapter can handle.
              */
+            if (ASC_NARROW_BOARD(boardp)) {
+                /*
+                 * Allow two commands with 'sg_tablesize' scatter-gather
+                 * elements to be executed simultaneously. This value is
+                 * the theoretical hardware limit. It may be decreased
+                 * below.
+                 */
+                shp->sg_tablesize =
+                    (((asc_dvc_varp->max_total_qng - 2) / 2) *
+                    ASC_SG_LIST_PER_Q) + 1;
+            } else {
+                shp->sg_tablesize = ADV_MAX_SG_LIST;
+            }
 
 #ifdef MODULE
             /*
-             * If the driver is compiled as a module, set a conservative
+             * If the driver is compiled as a module, set a limit on the
              * 'sg_tablesize' value to prevent memory allocation failures.
              * Memory allocation errors are more likely to occur at module
              * load time, then at driver initialization time.
              */
-            shp->sg_tablesize = 8;
-#else /* MODULE */
-            /*
-             * Allow two commands with 'sg_tablesize' scatter-gather
-             * elements to be executed simultaneously. This value is
-             * the theoretical hardware limit. It may be decreased
-             * below.
-             */
-            shp->sg_tablesize =
-                (((asc_dvc_varp->max_total_qng - 2) / 2) *
-                ASC_SG_LIST_PER_Q) + 1;
+            if (shp->sg_tablesize > 64) {
+                shp->sg_tablesize = 64;
+            }
 #endif /* MODULE */
 
             /*
@@ -3465,52 +4801,96 @@
                 shp->sg_tablesize);
 
             /* BIOS start address. */
-            shp->base = (char *) ((ulong) AscGetChipBiosAddress(
+            if (ASC_NARROW_BOARD(boardp)) {
+                shp->base = (char *) ((ulong) AscGetChipBiosAddress(
                                                 asc_dvc_varp->iop_base,
                                                 asc_dvc_varp->bus_type));
+            } else {
+                /*
+                 * Fill-in BIOS board variables. The Wide BIOS saves
+                 * information in LRAM that is used by the driver.
+                 */
+                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
+                    boardp->bios_signature);
+                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
+                    boardp->bios_version);
+                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
+                    boardp->bios_codeseg);
+                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
+                    boardp->bios_codelen);
+
+                ASC_DBG2(1,
+                    "advansys_detect: bios_signature %x, bios_version %x\n",
+                    boardp->bios_signature, boardp->bios_version);
+
+                ASC_DBG2(1,
+                    "advansys_detect: bios_codeseg %x, bios_codelen %x\n",
+                    boardp->bios_codeseg, boardp->bios_codelen);
+
+                /*
+                 * If the BIOS saved a valid signature, then fill in
+                 * the BIOS code segment base address.
+                 */
+                if (boardp->bios_signature == 0x55AA) {
+                    /*
+                     * Convert x86 realmode code segment to a linear
+                     * address by shifting left 4.
+                     */
+                    shp->base = (uchar *) (boardp->bios_codeseg << 4);
+                } else {
+                    shp->base = 0;
+                }
+            }
 
             /*
              * Register Board Resources - I/O Port, DMA, IRQ
              */
 
-            /* Register I/O port range */
+            /* Register I/O port range. */
             ASC_DBG(2, "advansys_detect: request_region()\n");
             request_region(shp->io_port, shp->n_io_port, "advansys");
 
-            /* Register DMA channel for ISA bus. */
-            if ((asc_dvc_varp->bus_type & ASC_IS_ISA) == 0) {
-                shp->dma_channel = NO_ISA_DMA;
-            } else {
-                shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
-                if ((ret = request_dma(shp->dma_channel, "advansys")) != 0) {
-                    ASC_PRINT3(
+            /* Register DMA Channel for Narrow boards. */
+            shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
+            if (ASC_NARROW_BOARD(boardp)) {
+                /* Register DMA channel for ISA bus. */
+                if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
+                    shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
+                    if ((ret =
+                         request_dma(shp->dma_channel, "advansys")) != 0) {
+                        ASC_PRINT3(
 "advansys_detect: board %d: request_dma() %d failed %d\n",
-                        boardp->id, shp->dma_channel, ret);
-                    release_region(shp->io_port, shp->n_io_port);
+                            boardp->id, shp->dma_channel, ret);
+                        release_region(shp->io_port, shp->n_io_port);
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
-                    kfree(boardp->prtbuf);
+                        kfree(boardp->prtbuf);
 #endif /* version >= v1.3.0 */
-                    scsi_unregister(shp);
-                    asc_board_count--;
-                    continue;
+                        scsi_unregister(shp);
+                        asc_board_count--;
+                        continue;
+                    }
+                    AscEnableIsaDma(shp->dma_channel);
                 }
-                AscEnableIsaDma(shp->dma_channel);
             }
 
             /* Register IRQ Number. */
             ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
             if ((ret = request_irq(shp->irq, advansys_interrupt,
-                            SA_INTERRUPT, "advansys")) != 0) {
+                            SA_INTERRUPT, "advansys")) != 0)
 #else /* version >= v1.3.70 */
             if ((ret = request_irq(shp->irq, advansys_interrupt,
                             SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
-                            "advansys", boardp)) != 0) {
+                            "advansys", boardp)) != 0)
 #endif /* version >= v1.3.70 */
+            {
                 ASC_PRINT2(
 "advansys_detect: board %d: request_irq() failed %d\n",
                     boardp->id, ret);
                 release_region(shp->io_port, shp->n_io_port);
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+                iounmap(boardp->ioremap_addr);
+#endif /* version >= v1,3,0 */
                 if (shp->dma_channel != NO_ISA_DMA) {
                     free_dma(shp->dma_channel);
                 }
@@ -3525,13 +4905,146 @@
             /*
              * Initialize board RISC chip and enable interrupts.
              */
-            ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
-            if (AscInitAsc1000Driver(asc_dvc_varp)) {
-                ASC_PRINT3(
-"AscInitAsc1000Driver: board %d: error: init_state %x, err_code %x\n",
-                    boardp->id, asc_dvc_varp->init_state,
-                    asc_dvc_varp->err_code);
+            if (ASC_NARROW_BOARD(boardp)) {
+                ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
+                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
+                err_code = asc_dvc_varp->err_code;
+
+                if (warn_code || err_code) {
+                    ASC_PRINT4(
+"AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n",
+                        boardp->id, asc_dvc_varp->init_state,
+                        warn_code, err_code);
+                }
+            } else {
+                int             req_cnt;
+                adv_req_t       *reqp = NULL;
+                int             sg_cnt;
+                adv_sgblk_t     *sgp = NULL;
+
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
+                req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
+                sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
+                reqp = (adv_req_t *) &adv_req_buf[0];
+                sgp = (adv_sgblk_t *) &adv_sgblk_buf[0];
+#else /* version >= v1.3.0 */
+                /*
+                 * Allocate up to 'max_host_qng' request structures for
+                 * the Wide board.
+                 */
+                for (req_cnt = adv_dvc_varp->max_host_qng;
+                    req_cnt > 0; req_cnt--) {
+
+                    reqp = (adv_req_t *)
+                        kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
+
+                    ASC_DBG3(1,
+                        "advansys_detect: reqp %x, req_cnt %d, bytes %d\n",
+                        (unsigned) reqp, req_cnt, sizeof(adv_req_t) * req_cnt);
+
+                    if (reqp != NULL) {
+                        break;
+                    }
+                }
+
+                /*
+                 * Allocate up to ADV_TOT_SG_LIST request structures for
+                 * the Wide board.
+                 */
+                for (sg_cnt = ADV_TOT_SG_LIST; sg_cnt > 0; sg_cnt--) {
+
+                    sgp = (adv_sgblk_t *)
+                        kmalloc(sizeof(adv_sgblk_t) * sg_cnt, GFP_ATOMIC);
+
+                    ASC_DBG3(1,
+                        "advansys_detect: sgp %x, sg_cnt %d, bytes %d\n",
+                        (unsigned) sgp, sg_cnt, sizeof(adv_sgblk_t) * sg_cnt);
+
+                    if (sgp != NULL) {
+                        break;
+                    }
+                }
+#endif /* version >= v1.3.0 */
+
+                /*
+                 * If no request structures or scatter-gather structures could
+                 * be allocated, then return an error. Otherwise continue with
+                 * initialization.
+                 */
+                if (reqp == NULL) {
+                    ASC_PRINT1(
+"advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",
+                        boardp->id);
+                    err_code = ADV_ERROR;
+                } else if (sgp == NULL) {
+                    kfree(reqp);
+                    ASC_PRINT1(
+"advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n",
+                        boardp->id);
+                    err_code = ADV_ERROR;
+                } else {
+                    
+                    /*
+                     * Save original pointer for kfree() in case the
+                     * driver is built as a module and can be unloaded.
+                     */
+                    boardp->orig_reqp = reqp;
+
+                    /*
+                     * Point 'adv_reqp' to the request structures and
+                     * link them together.
+                     */
+                    req_cnt--;
+                    reqp[req_cnt].next_reqp = NULL;
+                    for (; req_cnt > 0; req_cnt--) {
+                        reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
+                    }
+                    boardp->adv_reqp = &reqp[0];
+
+                    /*
+                     * Save original pointer for kfree() in case the
+                     * driver is built as a module and can be unloaded.
+                     */
+                    boardp->orig_sgblkp = sgp;
+
+                    /*
+                     * Point 'adv_sgblkp' to the request structures and
+                     * link them together.
+                     */
+                    sg_cnt--;
+                    sgp[sg_cnt].next_sgblkp = NULL;
+                    for (; sg_cnt > 0; sg_cnt--) {
+                        sgp[sg_cnt - 1].next_sgblkp = &sgp[sg_cnt];
+                    }
+                    boardp->adv_sgblkp = &sgp[0];
+
+                    ASC_DBG(2, "advansys_detect: AdvInitAsc3550Driver()\n");
+                    warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
+                    err_code = adv_dvc_varp->err_code;
+
+                    if (warn_code || err_code) {
+                        ASC_PRINT3(
+"AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n",
+                            boardp->id, warn_code, adv_dvc_varp->err_code);
+                    }
+                }
+            }
+
+            if (err_code != 0) {
                 release_region(shp->io_port, shp->n_io_port);
+                if (ASC_WIDE_BOARD(boardp)) {
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+                    iounmap(boardp->ioremap_addr);
+#endif /* version >= v1,3,0 */
+                    if (boardp->orig_reqp) {
+                        kfree(boardp->orig_reqp);
+                        boardp->orig_reqp = boardp->adv_reqp = NULL;
+                    }
+                    if (boardp->orig_sgblkp) {
+                        kfree(boardp->orig_sgblkp);
+                        boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
+                    }
+                }
                 if (shp->dma_channel != NO_ISA_DMA) {
                     free_dma(shp->dma_channel);
                 }
@@ -3576,6 +5089,19 @@
         free_dma(shp->dma_channel);
     }
     release_region(shp->io_port, shp->n_io_port);
+    if (ASC_WIDE_BOARD(boardp)) {
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+        iounmap(boardp->ioremap_addr);
+#endif /* version >= v1,3,0 */
+        if (boardp->orig_reqp) {
+            kfree(boardp->orig_reqp);
+            boardp->orig_reqp = boardp->adv_reqp = NULL;
+        }
+        if (boardp->orig_sgblkp) {
+            kfree(boardp->orig_sgblkp);
+            boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
+        }
+    }
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
     ASC_ASSERT(boardp->prtbuf != NULL);
     kfree(boardp->prtbuf);
@@ -3600,49 +5126,79 @@
     static char     info[ASC_INFO_SIZE];
     asc_board_t     *boardp;
     ASC_DVC_VAR     *asc_dvc_varp;
+    ADV_DVC_VAR     *adv_dvc_varp;
     char            *busname;
 
     boardp = ASC_BOARDP(shp);
-    asc_dvc_varp = &boardp->asc_dvc_var;
-    ASC_DBG(1, "advansys_info: begin\n");
-    if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
-        if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
-            busname = "ISA PnP";
+    if (ASC_NARROW_BOARD(boardp)) {
+        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
+        ASC_DBG(1, "advansys_info: begin\n");
+        if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
+            if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
+                busname = "ISA PnP";
+            } else {
+                busname = "ISA";
+            }
+            sprintf(info,
+"AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u, DMA %u",
+                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
+                (unsigned) shp->base,
+                shp->io_port, shp->n_io_port - 1,
+                shp->irq, shp->dma_channel);
+        } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
+            if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
+                == ASC_IS_PCI_ULTRA) {
+                busname = "PCI Ultra";
+            } else {
+                busname = "PCI";
+            }
+            sprintf(info,
+                "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u",
+                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
+                shp->io_port, shp->n_io_port - 1, shp->irq);
         } else {
-            busname = "ISA";
+            if (asc_dvc_varp->bus_type & ASC_IS_VL) {
+                busname = "VL";
+            } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
+                busname = "EISA";
+            } else {
+                busname = "?";
+                ASC_PRINT2(
+    "advansys_info: board %d: unknown bus type %d\n",
+                    boardp->id, asc_dvc_varp->bus_type);
+            }
+            sprintf(info,
+                "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u",
+                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
+                (unsigned) shp->base, shp->io_port - 1,
+                shp->n_io_port, shp->irq);
         }
-        sprintf(info,
-            "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X-%X, IRQ %u, DMA %u",
-            ASC_VERSION, busname, boardp->asc_dvc_var.max_total_qng,
-            (unsigned) shp->base, shp->io_port,
-            shp->io_port + (shp->n_io_port - 1), shp->irq, shp->dma_channel);
-    } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
-        if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
-            == ASC_IS_PCI_ULTRA) {
-            busname = "PCI Ultra";
-        } else {
-            busname = "PCI";
-        }
-        sprintf(info,
-            "AdvanSys SCSI %s: %s %u CDB: IO %X-%X, IRQ %u",
-            ASC_VERSION, busname, boardp->asc_dvc_var.max_total_qng,
-            shp->io_port, shp->io_port + (shp->n_io_port - 1), shp->irq);
-    } else {
-        if (asc_dvc_varp->bus_type & ASC_IS_VL) {
-            busname = "VL";
-        } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
-            busname = "EISA";
+    } else {
+        /*
+         * Wide Adapter Information
+         *
+         * Memory-mapped I/O is used instead of I/O space to access
+         * the adapter, but display the I/O Port range. The Memory
+         * I/O address is displayed through the driver /proc file.
+         */
+        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
+        if (boardp->bios_signature == 0x55AA) {
+            sprintf(info,
+"AdvanSys SCSI %s: PCI Ultra-Wide: BIOS %X/%X, IO %X/%X, IRQ %u",
+                ASC_VERSION,
+                boardp->bios_codeseg << 4,
+                boardp->bios_codelen > 0 ?
+                (boardp->bios_codelen << 9) - 1 : 0,
+                (unsigned) boardp->ioport, ADV_CONDOR_IOLEN - 1,
+                shp->irq);
         } else {
-            busname = "?";
-            ASC_PRINT2(
-"advansys_info: board %d: unknown bus type %d\n",
-                boardp->id, asc_dvc_varp->bus_type);
+            sprintf(info,
+"AdvanSys SCSI %s: PCI Ultra-Wide: IO %X/%X, IRQ %u",
+                ASC_VERSION,
+                (unsigned) boardp->ioport,
+                (ADV_CONDOR_IOLEN - 1),
+                shp->irq);
         }
-        sprintf(info,
-            "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X-%X, IRQ %u",
-            ASC_VERSION, busname, boardp->asc_dvc_var.max_total_qng,
-            (unsigned) shp->base, shp->io_port,
-            shp->io_port + (shp->n_io_port - 1), shp->irq);
     }
     ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
     ASC_DBG(1, "advansys_info: end\n");
@@ -3650,10 +5206,10 @@
 }
 
 /*
- * advansys_command()
+ * advansys_command() - polled I/O entrypoint.
  *
- * Polled-I/O. Apparently host drivers shouldn't return until
- * command is finished.
+ * Apparently host drivers shouldn't return until the command
+ * is finished.
  *
  * Note: This is an old interface that is no longer used by the SCSI
  * mid-level driver. The new interface, advansys_queuecommand(),
@@ -3666,10 +5222,6 @@
     ASC_STATS(scp->host, command);
     scp->SCp.Status = 0; /* Set to a known state */
     advansys_queuecommand(scp, advansys_command_done);
-    /*
-     * XXX - Can host drivers block here instead of spinning on
-     * command status?
-     */
     while (scp->SCp.Status == 0) {
         continue;
     }
@@ -3678,7 +5230,7 @@
 }
 
 /*
- * advansys_queuecommand()
+ * advansys_queuecommand() - interrupt-driven I/O entrypoint.
  *
  * This function always returns 0. Command return status is saved
  * in the 'scp' result field.
@@ -3782,6 +5334,7 @@
     struct Scsi_Host    *shp;
     asc_board_t         *boardp;
     ASC_DVC_VAR         *asc_dvc_varp;
+    ADV_DVC_VAR         *adv_dvc_varp;
     int                 flags;
     int                 do_scsi_done;
     int                 scp_found;
@@ -3842,10 +5395,10 @@
         do_scsi_done = ASC_TRUE;
         if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
             /*
-              * If asc_rmqueue() found the command on the waiting
+             * If asc_rmqueue() found the command on the waiting
              * queue, it had not been sent to the device. After
              * the queue is removed, no other handling is required.
-              */
+             */
             ASC_DBG1(1, "advansys_abort: scp %x found on waiting queue\n",
                 (unsigned) scp);
             scp_found = ASC_TRUE;
@@ -3853,35 +5406,72 @@
             ret = SCSI_ABORT_SUCCESS;
         } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE) {
             /*
-              * If asc_isqueued() found the command on the active
+             * If asc_isqueued() found the command on the active
              * queue, it has been sent to the device. The command
-             * should be returned through the interrupt handler after
-             * calling AscAbortSRB().
-              */
-            asc_dvc_varp = &boardp->asc_dvc_var;
-            scp->result = HOST_BYTE(DID_ABORT);
+             * will be returned through the interrupt handler after
+             * it has been aborted.
+             */
 
-            sti(); /* Enable interrupts for AscAbortSRB(). */
-            ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n",
-                (unsigned) scp);
-            switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) {
-            case ASC_TRUE:
-                /* asc_isr_callback() will be called */
-                ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
-                ret = SCSI_ABORT_PENDING;
-                break;
-            case ASC_FALSE:
-                /* Request has apparently already completed. */
-                ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
-                ret = SCSI_ABORT_NOT_RUNNING;
-                break;
-            case ASC_ERROR:
-            default:
-                ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
-                ret = SCSI_ABORT_ERROR;
-                break;
+            if (ASC_NARROW_BOARD(boardp)) {
+                /*
+                 * Narrow Board
+                 */
+                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
+                scp->result = HOST_BYTE(DID_ABORT);
+
+                sti(); /* Enable interrupts for AscAbortSRB(). */
+                ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n",
+                    (unsigned) scp);
+                switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) {
+                case ASC_TRUE:
+                    /* asc_isr_callback() will be called */
+                    ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
+                    ret = SCSI_ABORT_PENDING;
+                    break;
+                case ASC_FALSE:
+                    /* Request has apparently already completed. */
+                    ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
+                    ret = SCSI_ABORT_NOT_RUNNING;
+                    break;
+                case ASC_ERROR:
+                default:
+                    ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
+                    ret = SCSI_ABORT_ERROR;
+                    break;
+                }
+                cli();
+            } else {
+                /*
+                 * Wide Board
+                 */
+                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
+                scp->result = HOST_BYTE(DID_ABORT);
+
+                ASC_DBG1(1, "advansys_abort: before AdvAbortSRB(), scp %x\n",
+                    (unsigned) scp);
+                switch (AdvAbortSRB(adv_dvc_varp, (ulong) scp)) {
+                case ASC_TRUE:
+                    /* asc_isr_callback() will be called */
+                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() TRUE\n");
+                    ret = SCSI_ABORT_PENDING;
+                    break;
+                case ASC_FALSE:
+                    /* Request has apparently already completed. */
+                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() FALSE\n");
+                    ret = SCSI_ABORT_NOT_RUNNING;
+                    break;
+                case ASC_ERROR:
+                default:
+                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() ERROR\n");
+                    ret = SCSI_ABORT_ERROR;
+                    break;
+                }
+                /*
+                 * Ensure all requests completed by the microcode have
+                 * been processed by calling AdvISR().
+                 */
+                (void) AdvISR(adv_dvc_varp);
             }
-            cli();
 
             /*
              * The request will either still be on the active queue
@@ -3983,6 +5573,7 @@
     struct Scsi_Host     *shp;
     asc_board_t          *boardp;
     ASC_DVC_VAR          *asc_dvc_varp;
+    ADV_DVC_VAR          *adv_dvc_varp;
     int                  flags;
     Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
     Scsi_Cmnd            *tscp, *new_last_scp;
@@ -3991,6 +5582,7 @@
     int                  status;
     int                  target;
     int                  ret;
+    int                  device_reset = ASC_FALSE;
 
     /* Save current flags and disable interrupts. */
     save_flags(flags);
@@ -4056,8 +5648,6 @@
         scp->result = HOST_BYTE(DID_ERROR);
         ret = SCSI_RESET_ERROR;
     } else {
-        int device_reset = ASC_FALSE;
-
         do_scsi_done = ASC_TRUE;
 
         /* Set reset flag to avoid nested reset or abort requests. */
@@ -4080,83 +5670,166 @@
             scp_found = ASC_FALSE;
         }
 
-        /*
-         * If the suggest reset bus flags are set, reset the bus.
-         * Otherwise only reset the device.
-         */
-        asc_dvc_varp = &boardp->asc_dvc_var;
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-        if (reset_flags &
-            (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET)) {
-#endif /* version >= v1.3.89 */
 
+        if (ASC_NARROW_BOARD(boardp)) {
             /*
-             * Reset the target's SCSI bus.
+             * Narrow Board
+             *
+             * If the suggest reset bus flags are set, then reset the bus.
+             * Otherwise only reset the device.
              */
-            ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
-            sti();    /* Enable interrupts for AscResetSB(). */
-            status = AscResetSB(asc_dvc_varp);
-            cli();
-            switch (status) {
-            case ASC_TRUE:
-                ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
-                ret = SCSI_RESET_SUCCESS;
-                break;
-            case ASC_ERROR:
-            default:
-                ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
-                ret = SCSI_RESET_ERROR;
-                break;
-            }
-
+            asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-        } else {
-            /*
-             * Reset the specified device. If the device reset fails,
-             * then reset the SCSI bus.
-             */
-
-            ASC_DBG1(1, "advansys_reset: before AscResetDevice(), target %d\n",
-                scp->target);
-            sti();    /* Enable interrupts for AscResetDevice(). */
-            status = AscResetDevice(asc_dvc_varp, scp->target);
-            cli();
-
-            /*
-             * If the device has been reset, try to initialize it.
-             */
-            if (status == ASC_TRUE) {
-                status = asc_init_dev(asc_dvc_varp, scp);
-            }
+            if (reset_flags &
+                (SCSI_RESET_SUGGEST_BUS_RESET |
+                 SCSI_RESET_SUGGEST_HOST_RESET)) {
+#endif /* version >= v1.3.89 */
 
-            switch (status) {
-            case ASC_TRUE:
-                ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
-                device_reset = ASC_TRUE;
-                ret = SCSI_RESET_SUCCESS;
-                break;
-            case ASC_ERROR:
-            default:
-                ASC_DBG(1,
-"advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
+                /*
+                 * Reset the target's SCSI bus.
+                 */
+                ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
                 sti();    /* Enable interrupts for AscResetSB(). */
                 status = AscResetSB(asc_dvc_varp);
                 cli();
                 switch (status) {
                 case ASC_TRUE:
-                    ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
+                    ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
                     ret = SCSI_RESET_SUCCESS;
                     break;
                 case ASC_ERROR:
                 default:
-                    ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
+                    ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
                     ret = SCSI_RESET_ERROR;
                     break;
                 }
-                break;
+
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
+            } else {
+                /*
+                 * Reset the specified device. If the device reset fails,
+                 * then reset the SCSI bus.
+                 */
+
+                ASC_DBG1(1,
+                    "advansys_reset: before AscResetDevice(), target %d\n",
+                    scp->target);
+                sti();    /* Enable interrupts for AscResetDevice(). */
+                status = AscResetDevice(asc_dvc_varp, scp->target);
+                cli();
+
+                /*
+                 * If the device has been reset, try to initialize it.
+                 */
+                if (status == ASC_TRUE) {
+                    status = asc_init_dev(asc_dvc_varp, scp);
+                }
+
+                switch (status) {
+                case ASC_TRUE:
+                    ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
+                    device_reset = ASC_TRUE;
+                    ret = SCSI_RESET_SUCCESS;
+                    break;
+                case ASC_ERROR:
+                default:
+                    ASC_DBG(1,
+"advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
+                    sti();    /* Enable interrupts for AscResetSB(). */
+                    status = AscResetSB(asc_dvc_varp);
+                    cli();
+                    switch (status) {
+                    case ASC_TRUE:
+                        ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
+                        ret = SCSI_RESET_SUCCESS;
+                        break;
+                    case ASC_ERROR:
+                    default:
+                        ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
+                        ret = SCSI_RESET_ERROR;
+                        break;
+                    }
+                    break;
+                }
+            }
+#endif /* version >= v1.3.89 */
+        } else {
+            /*
+             * Wide Board
+             *
+             * If the suggest reset bus flags are set, then reset the bus.
+             * Otherwise only reset the device.
+             */
+            adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
+            if (reset_flags &
+                (SCSI_RESET_SUGGEST_BUS_RESET |
+                 SCSI_RESET_SUGGEST_HOST_RESET)) {
+#endif /* version >= v1.3.89 */
+
+                /*
+                 * Reset the target's SCSI bus.
+                 */
+                ASC_DBG(1, "advansys_reset: before AdvResetSB()\n");
+                switch (AdvResetSB(adv_dvc_varp)) {
+                case ASC_TRUE:
+                    ASC_DBG(1, "advansys_reset: AdvResetSB() success\n");
+                    ret = SCSI_RESET_SUCCESS;
+                    break;
+                case ASC_FALSE:
+                default:
+                    ASC_DBG(1, "advansys_reset: AdvResetSB() failed\n");
+                    ret = SCSI_RESET_ERROR;
+                    break;
+                }
+                /*
+                 * Ensure all requests completed by the microcode have
+                 * been processed by calling AdvISR().
+                 */
+                (void) AdvISR(adv_dvc_varp);
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
+            } else {
+                /*
+                 * Reset the specified device. If the device reset fails,
+                 * then reset the SCSI bus.
+                 */
+
+                ASC_DBG1(1,
+                    "advansys_reset: before AdvResetDevice(), target %d\n",
+                    scp->target);
+                
+                switch (AdvResetDevice(adv_dvc_varp, scp->target)) {
+                case ASC_TRUE:
+                    ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n");
+                    device_reset = ASC_TRUE;
+                    ret = SCSI_RESET_SUCCESS;
+                    break;
+                case ASC_FALSE:
+                default:
+                    ASC_DBG(1,
+"advansys_reset: AdvResetDevice() failed; Calling AdvResetSB()\n");
+                    
+                    switch (AdvResetSB(adv_dvc_varp)) {
+                    case ASC_TRUE:
+                        ASC_DBG(1, "advansys_reset: AdvResetSB() TRUE\n");
+                        ret = SCSI_RESET_SUCCESS;
+                        break;
+                    case ASC_FALSE:
+                    default:
+                        ASC_DBG(1, "advansys_reset: AdvResetSB() ERROR\n");
+                        ret = SCSI_RESET_ERROR;
+                        break;
+                    }
+                    break;
+                }
+                /*
+                 * Ensure all requests completed by the microcode have
+                 * been processed by calling AdvISR().
+                 */
+                (void) AdvISR(adv_dvc_varp);
             }
-        }
 #endif /* version >= v1.3.89 */
+        }
 
         /*
          * Because the ASC_HOST_IN_RESET flag causes both
@@ -4299,15 +5972,29 @@
 advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
 #endif /* version >= v1.3.0 */
 {
+    asc_board_t     *boardp;
+
     ASC_DBG(1, "advansys_biosparam: begin\n");
     ASC_STATS(dp->device->host, biosparam);
-    if ((ASC_BOARDP(dp->device->host)->asc_dvc_var.dvc_cntl &
-         ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
-            ip[0] = 255;
-            ip[1] = 63;
+    boardp = ASC_BOARDP(dp->device->host);
+    if (ASC_NARROW_BOARD(boardp)) {
+        if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
+             ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
+                ip[0] = 255;
+                ip[1] = 63;
+        } else {
+                ip[0] = 64;
+                ip[1] = 32;
+        }
     } else {
-            ip[0] = 64;
-            ip[1] = 32;
+        if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
+             BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
+                ip[0] = 255;
+                ip[1] = 63;
+        } else {
+                ip[0] = 64;
+                ip[1] = 32;
+        }
     }
     ip[2] = dp->capacity / (ip[0] * ip[1]);
     ASC_DBG(1, "advansys_biosparam: end\n");
@@ -4328,7 +6015,7 @@
  * only affects searching for ISA and VL boards.
  *
  * If ADVANSYS_DEBUG is defined the driver debug level may
- * be set using the 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port.
+ * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
  *
  * Examples:
  * 1. Eliminate I/O port scanning:
@@ -4362,15 +6049,15 @@
 
     asc_iopflag = ASC_TRUE;
 
-    if (ints[0] > ASC_NUM_BOARD_SUPPORTED) {
+    if (ints[0] > ASC_NUM_IOPORT_PROBE) {
 #ifdef ADVANSYS_DEBUG
-        if ((ints[0] == ASC_NUM_BOARD_SUPPORTED + 1) &&
-            (ints[ASC_NUM_BOARD_SUPPORTED + 1] >> 4 == 0xdeb)) {
-            asc_dbglvl = ints[ASC_NUM_BOARD_SUPPORTED + 1] & 0xf;
+        if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
+            (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
+            asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
         } else {
 #endif /* ADVANSYS_DEBUG */
             printk("AdvanSys SCSI: only %d I/O ports accepted\n",
-                ASC_NUM_BOARD_SUPPORTED);
+                ASC_NUM_IOPORT_PROBE);
 #ifdef ADVANSYS_DEBUG
         }
 #endif /* ADVANSYS_DEBUG */
@@ -4384,7 +6071,7 @@
     ASC_DBG(1, "\n");
 #endif /* ADVANSYS_DEBUG */
 
-    for (i = 1; i <= ints[0] && i <= ASC_NUM_BOARD_SUPPORTED; i++) {
+    for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
         asc_ioport[i-1] = ints[i];
         ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
             i - 1, asc_ioport[i-1]);
@@ -4433,17 +6120,32 @@
     cli();
 
     ASC_DBG(1, "advansys_interrupt: begin\n");
+
     /*
      * Check for interrupts on all boards.
      * AscISR() will call asc_isr_callback().
      */
     for (i = 0; i < asc_board_count; i++) {
-        ASC_STATS(asc_host[i], check_interrupt);
         boardp = ASC_BOARDP(asc_host[i]);
-        while (AscIsIntPending(asc_host[i]->io_port)) {
-            ASC_STATS(asc_host[i], interrupt);
-            ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
-            AscISR(&boardp->asc_dvc_var);
+        ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
+            i, (ulong) boardp)            
+        if (ASC_NARROW_BOARD(boardp)) {
+            /*
+             * Narrow Board
+             */
+            if (AscIsIntPending(asc_host[i]->io_port)) {
+                ASC_STATS(asc_host[i], interrupt);
+                ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
+                AscISR(&boardp->dvc_var.asc_dvc_var);
+            }
+        } else {
+            /*
+             * Wide Board
+             */
+            ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
+            if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
+                ASC_STATS(asc_host[i], interrupt);
+            }
         }
 
         /*
@@ -4454,6 +6156,9 @@
          * it has completed.
          */
         if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) {
+            ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
+                (ulong) done_scp, (ulong) last_scp);
+
             /* Start any waiting commands for the board. */
             if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
                 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
@@ -4461,8 +6166,12 @@
             }
 
              /*
-             * Add to the list of requests that must be completed.
-             */
+              * Add to the list of requests that must be completed.
+              *
+              * 'done_scp' will always be NULL on the first iteration
+              * of this loop. 'last_scp' is set at the same time as
+              * 'done_scp'.
+              */
             if (done_scp == NULL) {
                 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
                     ASC_TID_ALL);
@@ -4506,6 +6215,7 @@
     asc_board_t        *boardp;
 
     boardp = ASC_BOARDP(shp);
+    boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
     for (device = devicelist; device != NULL; device = device->next) {
         if (device->host != shp) {
             continue;
@@ -4515,7 +6225,13 @@
          * queue depth.
          */
         boardp->device[device->id] = device;
-        device->queue_depth = boardp->asc_dvc_var.max_dvc_qng[device->id];
+        if (ASC_NARROW_BOARD(boardp)) {
+            device->queue_depth =
+                boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
+        } else {
+            device->queue_depth =
+                boardp->dvc_var.adv_dvc_var.max_dvc_qng;
+        }
         ASC_DBG3(1, "advansys_select_queue_depths: shp %x, id %d, depth %d\n",
             (unsigned) shp, device->id, device->queue_depth);
     }
@@ -4544,7 +6260,9 @@
 {
     Scsi_Cmnd    *tscp;
 
+    ASC_DBG(2, "asc_scsi_done_list: begin\n");
     while (scp != NULL) {
+        ASC_DBG1(3, "asc_scsi_done_list: scp %x\n", (unsigned) scp);
         tscp = REQPNEXT(scp);
         REQPNEXT(scp) = NULL;
         ASC_STATS(scp->host, done);
@@ -4552,6 +6270,7 @@
         scp->scsi_done(scp);
         scp = tscp;
     }
+    ASC_DBG(2, "asc_scsi_done_list: done\n");
     return;
 }
 
@@ -4567,28 +6286,29 @@
  *  target - target of device
  *  lun - lun of device
  *  cmd_len - length of SCSI CDB
- *    cmnd - buffer for SCSI 8, 10, or 12 byte CDB
+ *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
  *
- *  if (use_sg == 0)
- *        request_buffer - buffer address for request
- *        request_bufflen - length of request buffer
- *  else
- *        request_buffer - pointer to scatterlist structure
+ *  if (use_sg == 0) {
+ *    request_buffer - buffer address for request
+ *    request_bufflen - length of request buffer
+ *  } else {
+ *    request_buffer - pointer to scatterlist structure
+ *  }
  *
  *  sense_buffer - sense command buffer
  *
  *  result (4 bytes of an int):
- *   Byte Meaning
- *   0      SCSI Status Byte Code
- *   1      SCSI One Byte Message Code
- *   2       Host Error Code
- *   3      Mid-Level Error Code
+ *    Byte Meaning
+ *    0 SCSI Status Byte Code
+ *    1 SCSI One Byte Message Code
+ *    2 Host Error Code
+ *    3 Mid-Level Error Code
  *
  *  host driver fields:
- *  SCp - Scsi_Pointer used for command processing status
- *  scsi_done - used to save caller's done function
- *     host_scribble - used for pointer to another Scsi_Cmnd
+ *    SCp - Scsi_Pointer used for command processing status
+ *    scsi_done - used to save caller's done function
+ *    host_scribble - used for pointer to another Scsi_Cmnd
  *
  * If this function returns ASC_NOERROR or ASC_ERROR the request
  * has been enqueued on the board's 'done' queue and must be
@@ -4602,6 +6322,8 @@
 {
     asc_board_t        *boardp;
     ASC_DVC_VAR        *asc_dvc_varp;
+    ADV_DVC_VAR        *adv_dvc_varp;
+    ADV_SCSI_REQ_Q     *adv_scsiqp;
     Scsi_Device        *device;
     int                ret;
 
@@ -4610,22 +6332,199 @@
         (unsigned) scp, (unsigned) scp->scsi_done);
 
     boardp = ASC_BOARDP(scp->host);
-    asc_dvc_varp = &boardp->asc_dvc_var;
     device = boardp->device[scp->target];
 
-    /*
-     * If this is the first command, then initialize the device. If
-     * no device is found set 'DID_BAD_TARGET' and return.
-     */
-    if ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(scp->target)) == 0) {
-        if (asc_init_dev(asc_dvc_varp, scp) == ASC_FALSE) {
-            scp->result = HOST_BYTE(DID_BAD_TARGET);
+    if (ASC_NARROW_BOARD(boardp)) {
+        /*
+         * Build and execute Narrow Board request.
+         */
+
+        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
+
+        /*
+         * Narrow Board - Asc Library requires special device initialization.
+         *
+         * If this is the first command, then initialize the device. If
+         * no device is found set 'DID_BAD_TARGET' and return.
+         */
+        if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0) {
+            if (asc_init_dev(asc_dvc_varp, scp) == ASC_FALSE) {
+                scp->result = HOST_BYTE(DID_BAD_TARGET);
+                asc_enqueue(&boardp->done, scp, ASC_BACK);
+                return ASC_ERROR;
+            }
+            boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
+        }
+
+        /*
+         * Build Asc Library request structure using the
+         * global structures 'asc_scsi_req' and 'asc_sg_head'.
+         *
+         * asc_build_req() can not return ASC_BUSY.
+         */
+        if (asc_build_req(boardp, scp) == ASC_ERROR) {
+            ASC_STATS(scp->host, build_error);
+            return ASC_ERROR;
+        }
+
+        /*
+         * Execute the command. If there is no error, add the command
+         * to the active queue.
+         */
+        switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
+        case ASC_NOERROR:
+            ASC_STATS(scp->host, exe_noerror);
+            /*
+             * Increment monotonically increasing per device successful
+             * request counter. Wrapping doesn't matter.
+             */
+            boardp->reqcnt[scp->target]++;
+
+#if ASC_QUEUE_FLOW_CONTROL
+            /*
+             * Conditionally increment the device queue depth.
+             *
+             * If no error occurred and there have been 100 consecutive
+             * successful requests and the current queue depth is less
+             * than the maximum queue depth, then increment the current
+             * queue depth.
+             */
+            if (boardp->nerrcnt[scp->target]++ > 100) {
+                boardp->nerrcnt[scp->target] = 0;
+                if (device != NULL &&
+                    (device->queue_curr_depth < device->queue_depth) &&
+                    (!(boardp->queue_full &
+                       ADV_TID_TO_TIDMASK(scp->target)) ||
+                     (boardp->queue_full_cnt[scp->target] >
+                      device->queue_curr_depth))) {
+                    device->queue_curr_depth++;
+                }
+            }
+#endif /* ASC_QUEUE_FLOW_CONTROL */
+            asc_enqueue(&boardp->active, scp, ASC_BACK);
+            ASC_DBG(1,
+                "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
+            break;
+        case ASC_BUSY:
+            /* Caller must enqueue request and retry later. */
+            ASC_STATS(scp->host, exe_busy);
+#if ASC_QUEUE_FLOW_CONTROL
+            /*
+             * Clear consecutive no error counter and if possible decrement
+             * queue depth.
+             */
+            boardp->nerrcnt[scp->target] = 0;
+            if (device != NULL && device->queue_curr_depth > 1) {
+                device->queue_curr_depth--;
+            }
+#endif /* ASC_QUEUE_FLOW_CONTROL */
+            break;
+        case ASC_ERROR:
+            ASC_PRINT2(
+"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
+                boardp->id, asc_dvc_varp->err_code);
+            ASC_STATS(scp->host, exe_error);
+#if ASC_QUEUE_FLOW_CONTROL
+            /* Clear consecutive no error counter. */
+            boardp->nerrcnt[scp->target] = 0;
+#endif /* ASC_QUEUE_FLOW_CONTROL */
+            scp->result = HOST_BYTE(DID_ERROR);
+            asc_enqueue(&boardp->done, scp, ASC_BACK);
+            break;
+        default:
+            ASC_PRINT2(
+"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
+                boardp->id, asc_dvc_varp->err_code);
+            ASC_STATS(scp->host, exe_unknown);
+#if ASC_QUEUE_FLOW_CONTROL
+            /* Clear consecutive no error counter. */
+            boardp->nerrcnt[scp->target] = 0;
+#endif /* ASC_QUEUE_FLOW_CONTROL */
+            scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
+            break;
+        }
+    } else {
+        /*
+         * Build and execute Wide Board request.
+         */
+        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
+
+        /*
+         * Build and get a pointer to an Adv Library request structure.
+         *
+         * If the request is successfully built then send  it below,
+         * otherwise return with an error.
+         */
+        switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
+        case ASC_NOERROR:
+            ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
+            break;
+        case ASC_BUSY:
+            ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
+            return ASC_BUSY;
+        case ASC_ERROR:
+        default:
+            ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
+            ASC_STATS(scp->host, build_error);
             return ASC_ERROR;
         }
-        boardp->init_tidmask |= ASC_TIX_TO_TARGET_ID(scp->target);
+    
+        /*
+         * Execute the command. If there is no error, add the command
+         * to the active queue.
+         */
+        switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
+        case ASC_NOERROR:
+            ASC_STATS(scp->host, exe_noerror);
+            /*
+             * Increment monotonically increasing per device successful
+             * request counter. Wrapping doesn't matter.
+             */
+            boardp->reqcnt[scp->target]++;
+            asc_enqueue(&boardp->active, scp, ASC_BACK);
+            ASC_DBG(1,
+                "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
+            break;
+        case ASC_BUSY:
+            /* Caller must enqueue request and retry later. */
+            ASC_STATS(scp->host, exe_busy);
+            break;
+        case ASC_ERROR:
+            ASC_PRINT2(
+"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",
+                boardp->id, adv_dvc_varp->err_code);
+            ASC_STATS(scp->host, exe_error);
+            scp->result = HOST_BYTE(DID_ERROR);
+            asc_enqueue(&boardp->done, scp, ASC_BACK);
+            break;
+        default:
+            ASC_PRINT2(
+"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",
+                boardp->id, adv_dvc_varp->err_code);
+            ASC_STATS(scp->host, exe_unknown);
+            scp->result = HOST_BYTE(DID_ERROR);
+            asc_enqueue(&boardp->done, scp, ASC_BACK);
+            break;
+        }
     }
 
+    ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
+    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    return ret;
+}
+
+/*
+ * Build a request structure for the Asc Library (Narrow Board).
+ *
+ * The global structures 'asc_scsi_q' and 'asc_sg_head' are
+ * used to build the request.
+ *
+ * If an error occurs, then return ASC_ERROR.
+ */
+STATIC int
+asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
+{
     /*
      * Mutually exclusive access is required to 'asc_scsi_q' and
      * 'asc_sg_head' until after the request is started.
@@ -4640,6 +6539,10 @@
     /*
      * Build the ASC_SCSI_Q request.
      */
+    ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
+    if (scp->cmd_len > ASC_MAX_CDB_LEN) {
+        scp->cmd_len = ASC_MAX_CDB_LEN;
+    }
     asc_scsi_q.cdbptr = &scp->cmnd[0];
     asc_scsi_q.q2.cdb_len = scp->cmd_len;
     asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
@@ -4663,7 +6566,7 @@
      * started request.
      * 
      */
-    if ((asc_dvc_varp->cur_dvc_qng[scp->target] > 0) &&
+    if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
         (boardp->reqcnt[scp->target] % 255) == 0) {
         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
     } else {
@@ -4693,12 +6596,12 @@
         /*
          * CDB scatter-gather request list.
          */
-        int                    sgcnt;
-        struct scatterlist    *slp;
+        int                     sgcnt;
+        struct scatterlist      *slp;
 
         if (scp->use_sg > scp->host->sg_tablesize) {
             ASC_PRINT3(
-"asc_execute_scsi_cmnd: board %d: use_sg %d > sg_tablesize %d\n",
+"asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
@@ -4708,8 +6611,8 @@
         ASC_STATS(scp->host, sg_cnt);
 
         /*
-         * Allocate a ASC_SG_HEAD structure and set the ASC_SCSI_Q
-         * to point to it.
+         * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
+         * structure to point to it.
          */
         memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
 
@@ -4735,91 +6638,262 @@
         }
     }
 
-    ASC_DBG_PRT_SCSI_Q(2, &asc_scsi_q);
+    ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
 
+    return ASC_NOERROR;
+}
+
+/*
+ * Build a request structure for the Adv Library (Wide Board).
+ *
+ * If an adv_req_t can not be allocated to issue the request,
+ * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
+ */
+STATIC int
+adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
+    ADV_SCSI_REQ_Q **adv_scsiqpp)
+{
+    adv_req_t           *reqp;
+    ADV_SCSI_REQ_Q      *scsiqp;
+    int                 i;
+
     /*
-     * Execute the command. If there is no error, add the command
-     * to the active queue.
+     * Allocate an adv_req_t structure from the board to execute
+     * the command.
      */
-    switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
-    case ASC_NOERROR:
-        ASC_STATS(scp->host, asc_noerror);
-        /*
-         * Increment monotonically increasing per device successful
-         * request counter. Wrapping doesn't matter.
-         */
-        boardp->reqcnt[scp->target]++;
-
-#if ASC_QUEUE_FLOW_CONTROL
+    if (boardp->adv_reqp == NULL) {
+        ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
+        ASC_STATS(scp->host, adv_build_noreq);
+        return ASC_BUSY;
+    } else {
+        reqp = boardp->adv_reqp;
+        boardp->adv_reqp = reqp->next_reqp;
+        reqp->next_reqp = NULL;
+    }
+
+    /*
+     * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
+     */
+    scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
+    memset(scsiqp, 0, sizeof(ADV_SCSI_REQ_Q));
+
+    /*
+     * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
+     */
+    scsiqp->srb_ptr = (ulong) reqp;
+
+    /*
+     * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
+     */
+    reqp->cmndp = scp;
+
+    /*
+     * Build the ADV_SCSI_REQ_Q request.
+     */
+
+    /*
+     * Set CDB length and copy it to the request structure.
+     */
+    ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
+    if (scp->cmd_len > ASC_MAX_CDB_LEN) {
+        scp->cmd_len = ASC_MAX_CDB_LEN;
+    }
+    scsiqp->cdb_len = scp->cmd_len;
+    for (i = 0; i < scp->cmd_len; i++) {
+        scsiqp->cdb[i] = scp->cmnd[i];
+    }
+
+    scsiqp->target_id = scp->target;
+    scsiqp->target_lun = scp->lun;
+
+    scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0];
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
+    scsiqp->sense_addr = (ulong) &scp->sense_buffer[0];
+#else /* version >= v2.0.0 */
+    scsiqp->sense_addr = virt_to_bus(&scp->sense_buffer[0]);
+#endif /* version >= v2.0.0 */
+    scsiqp->sense_len = sizeof(scp->sense_buffer);
+
+    /*
+     * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
+     * buffer command.
+     */
+    scsiqp->data_cnt = scp->request_bufflen;
+    scsiqp->vdata_addr = (ulong) scp->request_buffer;
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
+    scsiqp->data_addr = (ulong) scp->request_buffer;
+#else /* version >= v2.0.0 */
+    scsiqp->data_addr = virt_to_bus(scp->request_buffer);
+#endif /* version >= v2.0.0 */
+
+    if (scp->use_sg == 0) {
         /*
-         * Conditionally increment the device queue depth.
-         *
-          * If no error occurred and there have been 100 consecutive
-         * successfull requests and the current queue depth is less
-         * than the maximum queue depth, then increment the current
-         * queue depth.
+         * CDB request of single contiguous buffer.
          */
-        if (boardp->nerrcnt[scp->target]++ > 100) {
-            boardp->nerrcnt[scp->target] = 0;
-            if ((device->queue_curr_depth < device->queue_depth) &&
-                (!(boardp->queue_full & ASC_TIX_TO_TARGET_ID(scp->target)) ||
-                 (boardp->queue_full_cnt[scp->target] >
-                  device->queue_curr_depth))) {
-                device->queue_curr_depth++;
-            }
+        reqp->sgblkp = NULL;
+        scsiqp->sg_list_ptr = NULL;
+        ASC_STATS(scp->host, cont_cnt);
+        ASC_STATS_ADD(scp->host, cont_xfer,
+                      ASC_CEILING(scp->request_bufflen, 512));
+    } else {
+        /*
+         * CDB scatter-gather request list.
+         */
+        if (scp->use_sg > ADV_MAX_SG_LIST) {
+            ASC_PRINT3(
+"adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
+                boardp->id, scp->use_sg, scp->host->sg_tablesize);
+            scp->result = HOST_BYTE(DID_ERROR);
+            asc_enqueue(&boardp->done, scp, ASC_BACK);
+
+            /*
+             * Free the 'adv_req_t' structure by adding it back to the
+             * board free list.
+             */
+            reqp->next_reqp = boardp->adv_reqp;
+            boardp->adv_reqp = reqp;
+
+            return ASC_ERROR;
         }
-#endif /* ASC_QUEUE_FLOW_CONTROL */
-        asc_enqueue(&boardp->active, scp, ASC_BACK);
-        ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
-        break;
-    case ASC_BUSY:
-        /* Caller must enqueue request and retry later. */
-        ASC_STATS(scp->host, asc_busy);
-#if ASC_QUEUE_FLOW_CONTROL
+
         /*
-         * Clear consecutive no error counter and if possbile decrement
-         * queue depth.
+         * Allocate an 'adv_sgblk_t' structure from the board to
+         * execute the command.
+         */
+        if (boardp->adv_sgblkp == NULL) {
+            ASC_DBG(1, "adv_build_req: no free adv_sgblk_t\n");
+            ASC_STATS(scp->host, adv_build_nosg);
+            /*
+             * Free the 'adv_req_t' structure by adding it back to the
+             * board free list.
+             */
+            reqp->next_reqp = boardp->adv_reqp;
+            boardp->adv_reqp = reqp;
+            return ASC_BUSY;
+        } else {
+            reqp->sgblkp = boardp->adv_sgblkp;
+            boardp->adv_sgblkp = reqp->sgblkp->next_sgblkp;
+            reqp->sgblkp->next_sgblkp = NULL;
+        }
+
+        /*
+         * Build scatter-gather list.
          */
-        boardp->nerrcnt[scp->target] = 0;
-        if (device->queue_curr_depth > 1) {
-            device->queue_curr_depth--;
+        scsiqp->sg_list_ptr = (ADV_SG_BLOCK *)
+            ADV_DWALIGN(&reqp->sgblkp->sg_block[0]);
+
+        memset(scsiqp->sg_list_ptr, 0, sizeof(ADV_SG_BLOCK) *
+            (ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING));
+         
+        if (adv_get_sglist(&boardp->dvc_var.adv_dvc_var, scsiqp, scp) ==
+            ADV_ERROR) {
+
+            /*
+             * Free the adv_sgblk_t structure, if any, by adding it back
+             * to the board free list.
+             */
+            ASC_ASSERT(reqp->sgblkp != NULL);
+            reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
+            boardp->adv_sgblkp = reqp->sgblkp;
+
+            /*
+             * Free the adv_req_t structure by adding it back to the
+             * board free list.
+             */
+            reqp->next_reqp = boardp->adv_reqp;
+            boardp->adv_reqp = reqp;
+
+            return ADV_ERROR;
         }
-#endif /* ASC_QUEUE_FLOW_CONTROL */
-        break;
-    case ASC_ERROR:
-        ASC_PRINT2(
-"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
-            boardp->id, asc_dvc_varp->err_code);
-        ASC_STATS(scp->host, asc_error);
-#if ASC_QUEUE_FLOW_CONTROL
-        /* Clear consecutive no error counter. */
-        boardp->nerrcnt[scp->target] = 0;
-#endif /* ASC_QUEUE_FLOW_CONTROL */
-        scp->result = HOST_BYTE(DID_ERROR);
-        asc_enqueue(&boardp->done, scp, ASC_BACK);
-        break;
-    default:
-        ASC_PRINT2(
-"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
-            boardp->id, asc_dvc_varp->err_code);
-        ASC_STATS(scp->host, asc_unknown);
-#if ASC_QUEUE_FLOW_CONTROL
-        /* Clear consecutive no error counter. */
-        boardp->nerrcnt[scp->target] = 0;
-#endif /* ASC_QUEUE_FLOW_CONTROL */
-        scp->result = HOST_BYTE(DID_ERROR);
-        asc_enqueue(&boardp->done, scp, ASC_BACK);
-        break;
+
+        ASC_STATS(scp->host, sg_cnt);
+        ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
     }
 
-    ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
-    return ret;
+    ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
+    ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
+
+    *adv_scsiqpp = scsiqp;
+
+    return ASC_NOERROR;
+}
+
+/*
+ * Build scatter-gather list for Adv Library (Wide Board).
+ *
+ * Return:
+ *      ADV_SUCCESS(1) - SG List successfully created
+ *      ADV_ERROR(-1) - SG List creation failed
+ */
+STATIC int
+adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
+    Scsi_Cmnd *scp)
+{
+    ADV_SG_BLOCK        *sg_block;              /* virtual address of a SG */
+    ulong               sg_block_next_addr;     /* block and its next */
+    ulong               sg_block_physical_addr;
+    int                 sg_block_index, i;      /* how many SG entries */
+    struct scatterlist  *slp;
+    int                 sg_elem_cnt;
+
+    slp = (struct scatterlist *) scp->request_buffer;
+    sg_elem_cnt = scp->use_sg;
+
+    sg_block = scsiqp->sg_list_ptr;
+    sg_block_next_addr = (ulong) sg_block;    /* allow math operation */
+    sg_block_physical_addr =
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
+        (ulong) scsiqp->sg_list_ptr;
+#else /* version >= v2.0.0 */
+        virt_to_bus(scsiqp->sg_list_ptr);
+#endif /* version >= v2.0.0 */
+    ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
+                   sg_block_physical_addr);
+    scsiqp->sg_real_addr = sg_block_physical_addr;
+
+    sg_block_index = 0;
+    do
+    {
+        sg_block->first_entry_no = sg_block_index;
+        for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
+        {
+            sg_block->sg_list[i].sg_addr =
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
+                (ulong) slp->address;
+#else /* version >= v2.0.0 */
+                virt_to_bus(slp->address);
+#endif /* version >= v2.0.0 */
+            sg_block->sg_list[i].sg_count = slp->length;
+            ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
+
+            if (--sg_elem_cnt == 0)
+            {   /* last entry, get out */
+                scsiqp->sg_entry_cnt = sg_block_index + i + 1;
+                sg_block->last_entry_no = sg_block_index + i;
+                sg_block->sg_ptr = 0L;    /* next link = NULL */
+                return ADV_SUCCESS;
+            }
+            slp++;
+        } 
+        sg_block_next_addr += sizeof(ADV_SG_BLOCK);
+        sg_block_physical_addr += sizeof(ADV_SG_BLOCK);
+        ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
+                       sg_block_physical_addr);
+
+        sg_block_index += NO_OF_SG_PER_BLOCK;
+        sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr;
+        sg_block->last_entry_no = sg_block_index - 1;
+        sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */
+    }
+    while (1);
+    /* NOTREACHED */
 }
 
 /*
  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
+ *
+ * Interrupt callback function for the Narrow SCSI Asc Library.
  */
 STATIC void
 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
@@ -4827,12 +6901,13 @@
     asc_board_t         *boardp;
     Scsi_Cmnd           *scp;
     struct Scsi_Host    *shp;
+    int            underrun = ASC_FALSE;
     int                 i;
 
     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
     ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %x, qdonep %x\n",
         (unsigned) asc_dvc_varp, (unsigned) qdonep);
-    ASC_DBG_PRT_QDONE_INFO(2, qdonep);
+    ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
 
     /*
      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
@@ -4840,12 +6915,12 @@
      */
     scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
     ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
-    ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
 
     if (scp == NULL) {
         ASC_PRINT("asc_isr_callback: scp is NULL\n");
         return;
     }
+    ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
 
     /*
      * If the request's host pointer is not valid, display a
@@ -4879,6 +6954,16 @@
     }
 
     /*
+     * Check for an underrun condition.
+     */
+    if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && 
+    qdonep->remain_bytes <= scp->request_bufflen != 0) {
+        ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
+        (unsigned) qdonep->remain_bytes);
+        underrun = ASC_TRUE;
+    }
+
+    /*
      * 'qdonep' contains the command's ending status.
      */
     switch (qdonep->d3.done_stat) {
@@ -4893,6 +6978,13 @@
             scp->result = HOST_BYTE(DID_ERROR);
             break;
         }
+    /*
+     * If there was an underrun without any other error,
+     * set DID_ERROR to indicate the underrun error.
+     */
+    if (scp->result == 0 && underrun == ASC_TRUE) {
+            scp->result = HOST_BYTE(DID_UNDERRUN);
+    }
         break;
 
     case QD_WITH_ERROR:
@@ -4955,115 +7047,320 @@
 }
 
 /*
- * asc_init_dev()
+ * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
  *
- * Perform one-time initialization of a device.
+ * Callback function for the Wide SCSI Adv Library.
  */
-STATIC int
-asc_init_dev(ASC_DVC_VAR *asc_dvc_varp, Scsi_Cmnd *scp)
+STATIC void
+adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
 {
-    asc_board_t             *boardp;
-    ASC_SCSI_REQ_Q          *scsireqq;
-    ASC_CAP_INFO            *cap_info;
-    ASC_SCSI_INQUIRY        *inquiry;
-    int                     found;
-    ASC_SCSI_BIT_ID_TYPE    save_use_tagged_qng;
-    ASC_SCSI_BIT_ID_TYPE    save_can_tagged_qng;
-    int                     ret;
-#ifdef ADVANSYS_DEBUG
-    ASC_SCSI_BIT_ID_TYPE    tidmask; /* target id bit mask: 1 - 128 */
-#endif /* ADVANSYS_DEBUG */
-
-    ASC_DBG1(1, "asc_init_dev: target %d\n", (unsigned) scp->target);
-
-    /* The host's target id is set in init_tidmask during initialization. */
-    ASC_ASSERT(asc_dvc_varp->cfg->chip_scsi_id != scp->target);
+    asc_board_t         *boardp;
+    adv_req_t           *reqp;
+    Scsi_Cmnd           *scp;
+    struct Scsi_Host    *shp;
+    int            underrun = ASC_FALSE;
+    int                 i;
 
-    boardp = ASC_BOARDP(scp->host);
+    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %x, scsiqp %x\n",
+        (unsigned) adv_dvc_varp, (unsigned) scsiqp);
+    ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
 
-    /* Set-up AscInitPollTarget() arguments. */
-    scsireqq = &boardp->scsireqq;
-    memset(scsireqq, 0, sizeof(ASC_SCSI_REQ_Q));
-    cap_info = &boardp->cap_info;
-    memset(cap_info, 0, sizeof(ASC_CAP_INFO));
-    inquiry = &boardp->inquiry;
-    memset(inquiry, 0, sizeof(ASC_SCSI_INQUIRY));
+    /*
+     * Get the adv_req_t structure for the command that has been
+     * completed. The adv_req_t structure actually contains the
+     * completed ADV_SCSI_REQ_Q structure.
+     */
+    reqp = (adv_req_t *) scsiqp->srb_ptr;
+    ASC_DBG1(1, "adv_isr_callback: reqp %x\n", (unsigned) reqp);
+    if (reqp == NULL) {
+        ASC_PRINT("adv_isr_callback: reqp is NULL\n");
+        return;
+    }
 
     /*
-     * XXX - AscInitPollBegin() re-initializes these fields to
-     * zero. 'Or' in the new values and restore them before calling 
-     * AscInitPollEnd(). Normally all targets are initialized within
-     * a call to AscInitPollBegin() and AscInitPollEnd().
+     * Get the Scsi_Cmnd structure and Scsi_Host structure for the
+     * command that has been completed.
+     *
+     * Note: The adv_req_t request structure and adv_sgblk_t structure,
+     * if any, * dropped, because a board structure pointer can not be
+     * determined.
      */
-    save_use_tagged_qng = asc_dvc_varp->use_tagged_qng;
-    save_can_tagged_qng = asc_dvc_varp->cfg->can_tagged_qng;
-
-    ASC_DBG(2, "asc_init_dev: AscInitPollBegin()\n");
-    if (AscInitPollBegin(asc_dvc_varp)) {
-        ASC_PRINT1("asc_init_dev: board %d: AscInitPollBegin() failed\n",
-            boardp->id);
-        return ASC_FALSE;
+    scp = reqp->cmndp;
+    ASC_DBG1(1, "adv_isr_callback: scp %x\n", (unsigned) scp);
+    if (scp == NULL) {
+        ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
+        return;
     }
+    ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
 
-    scsireqq->sense_ptr = &scsireqq->sense[0];
-    scsireqq->r1.sense_len = ASC_MIN_SENSE_LEN;
-    scsireqq->r1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
-    scsireqq->r1.target_lun = 0;
-    scsireqq->r2.target_ix = ASC_TIDLUN_TO_IX(scp->target, 0);
-
-    found = ASC_FALSE;
-    ASC_DBG(2, "asc_init_dev: AscInitPollTarget()\n");
-    switch (ret = AscInitPollTarget(asc_dvc_varp, scsireqq, inquiry,
-        cap_info)) {
-    case ASC_TRUE:
-        found = ASC_TRUE;
-#ifdef ADVANSYS_DEBUG
-        tidmask = ASC_TIX_TO_TARGET_ID(scp->target);
-        ASC_DBG2(1, "asc_init_dev: lba %lu, blk_size %lu\n",
-            cap_info->lba, cap_info->blk_size);
-        ASC_DBG1(1, "asc_init_dev: peri_dvc_type %x\n",
-            inquiry->byte0.peri_dvc_type);
-        if (asc_dvc_varp->use_tagged_qng & tidmask) {
-            ASC_DBG1(1, "asc_init_dev: command queuing enabled: %d\n",
-                asc_dvc_varp->max_dvc_qng[scp->target]);
-        } else {
-            ASC_DBG(1, "asc_init_dev: command queuing disabled\n");
-        }
-        if (asc_dvc_varp->init_sdtr & tidmask) {
-            ASC_DBG(1, "asc_init_dev: synchronous transfers enabled\n");
-        } else {
-            ASC_DBG(1, "asc_init_dev: synchronous transfers disabled\n");
-        }
-        /* Set bit means fix disabled. */
-        if (asc_dvc_varp->pci_fix_asyn_xfer & tidmask) {
-            ASC_DBG(1, "asc_init_dev: synchronous transfer fix disabled\n");
-        } else {
-            ASC_DBG(1, "asc_init_dev: synchronous transfer fix enabled\n");
+    /*
+     * If the request's host pointer is not valid, display a message
+     * and return.
+     */
+    shp = scp->host;
+    for (i = 0; i < asc_board_count; i++) {
+        if (asc_host[i] == shp) {
+            break;
         }
-#endif /* ADVANSYS_DEBUG */
-        break;
-    case ASC_FALSE:
-        ASC_DBG(1, "asc_init_dev: no device found\n");
-        break;
-    case ASC_ERROR:
-        ASC_PRINT1("asc_init_dev: board %d: AscInitPollTarget() ASC_ERROR\n",
-                boardp->id);
-        break;
-    default:
-        ASC_PRINT2(
-"asc_init_dev: board %d: AscInitPollTarget() unknown ret %d\n",
-                boardp->id, ret);
-        break;
+    }
+    /*
+     * Note: If the host structure is not found, the adv_req_t request
+     * structure and adv_sgblk_t structure, if any, is dropped.
+     */
+    if (i == asc_board_count) {
+        ASC_PRINT2("adv_isr_callback: scp %x has bad host pointer, host %x\n",
+            (unsigned) scp, (unsigned) shp);
+        return;
     }
 
-    /* XXX - 'Or' in original tag bits. */
-    asc_dvc_varp->use_tagged_qng |= save_use_tagged_qng;
-    asc_dvc_varp->cfg->can_tagged_qng |= save_can_tagged_qng;
-
-    ASC_DBG(2, "asc_init_dev: AscInitPollEnd()\n");
-    AscInitPollEnd(asc_dvc_varp);
+    ASC_STATS(shp, callback);
+    ASC_DBG1(1, "adv_isr_callback: shp %x\n", (unsigned) shp);
 
-    ASC_DBG1(1, "asc_init_dev: found %d\n", found); 
+    /*
+     * If the request isn't found on the active queue, it may have been
+     * removed to handle a reset or abort request. Display a message and
+     * return.
+     *
+     * Note: Because the structure may still be in use don't attempt
+     * to free the adv_req_t and adv_sgblk_t, if any, structures.
+     */
+    boardp = ASC_BOARDP(shp);
+    if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
+        ASC_PRINT2("adv_isr_callback: board %d: scp %x not on active queue\n",
+            boardp->id, (unsigned) scp);
+        return;
+    }
+
+    /*
+     * Check for an underrun condition.
+     */
+    if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0) {
+        ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
+        scsiqp->data_cnt);
+        underrun = ASC_TRUE;
+    }
+
+    /*
+     * 'done_status' contains the command's ending status.
+     */
+    switch (scsiqp->done_status) {
+    case QD_NO_ERROR:
+        ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
+        switch (scsiqp->host_status) {
+        case QHSTA_NO_ERROR:
+            scp->result = 0;
+            break;
+        default:
+            /* QHSTA error occurred. */
+            ASC_DBG1(2, "adv_isr_callback: host_status %x\n",
+                scsiqp->host_status);
+            scp->result = HOST_BYTE(DID_ERROR);
+            break;
+        }
+    /*
+     * If there was an underrun without any other error,
+     * set DID_ERROR to indicate the underrun error.
+     */
+    if (scp->result == 0 && underrun == ASC_TRUE) {
+            scp->result = HOST_BYTE(DID_UNDERRUN);
+    }
+        break;
+
+    case QD_WITH_ERROR:
+        ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
+        switch (scsiqp->host_status) {
+        case QHSTA_NO_ERROR:
+            if (scsiqp->scsi_status == SS_CHK_CONDITION) {
+                ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
+                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
+                    sizeof(scp->sense_buffer));
+                /*
+                 * Note: The 'status_byte()' macro used by target drivers
+                 * defined in scsi.h shifts the status byte returned by
+                 * host drivers right by 1 bit. This is why target drivers
+                 * also use right shifted status byte definitions. For
+                 * instance target drivers use CHECK_CONDITION, defined to
+                 * 0x1, instead of the SCSI defined check condition value
+                 * of 0x2. Host drivers are supposed to return the status
+                 * byte as it is defined by SCSI.
+                 */
+                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
+                    STATUS_BYTE(scsiqp->scsi_status);
+            } else {
+                scp->result = STATUS_BYTE(scsiqp->scsi_status);
+            }
+            break;
+
+        default:
+            /* Some other QHSTA error occurred. */
+            ASC_DBG1(2, "adv_isr_callback: host_status %x\n",
+                scsiqp->host_status);
+            scp->result = HOST_BYTE(DID_BAD_TARGET);
+            break;
+        }
+        break;
+
+    case QD_ABORTED_BY_HOST:
+        ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
+        scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
+        break;
+
+    default:
+        ASC_PRINT1("adv_isr_callback: done_status %x\n", scsiqp->done_status);
+        scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
+        break;
+    }
+
+    /*
+     * If the 'init_tidmask' bit isn't already set for the target and the
+     * current request did not finish with a Selection Timeout, then set
+     * the bit for the target to indicate that a device is present.
+     */
+    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
+        scsiqp->done_status == QD_NO_ERROR &&
+        scsiqp->host_status == QHSTA_NO_ERROR) {
+        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
+    }
+
+    /* 
+     * Because interrupts may be enabled by the 'Scsi_Cmnd' done
+     * function, add the command to the end of the board's done queue.
+     * The done function for the command will be called from
+     * advansys_interrupt().
+     */
+    asc_enqueue(&boardp->done, scp, ASC_BACK);
+
+    /*
+     * Free the adv_sgblk_t structure, if any, by adding it back
+     * to the board free list.
+     */
+    if (reqp->sgblkp != NULL) {
+        reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
+        boardp->adv_sgblkp = reqp->sgblkp;
+    }
+
+    /*
+     * Free the adv_req_t structure used with the command by adding
+     * it back to the board free list.
+     */
+    reqp->next_reqp = boardp->adv_reqp;
+    boardp->adv_reqp = reqp;
+
+    ASC_DBG(1, "adv_isr_callback: done\n");
+
+    return;
+}
+
+/*
+ * asc_init_dev() - Narrow Board initialization function. 
+ *
+ * Perform one-time initialization of a device for Asc Library
+ */
+STATIC int
+asc_init_dev(ASC_DVC_VAR *asc_dvc_varp, Scsi_Cmnd *scp)
+{
+    asc_board_t             *boardp;
+    ASC_SCSI_REQ_Q          *scsireqq;
+    ASC_CAP_INFO            *cap_info;
+    ASC_SCSI_INQUIRY        *inquiry;
+    int                     found;
+    ASC_SCSI_BIT_ID_TYPE    save_use_tagged_qng;
+    ASC_SCSI_BIT_ID_TYPE    save_can_tagged_qng;
+    int                     ret;
+#ifdef ADVANSYS_DEBUG
+    ASC_SCSI_BIT_ID_TYPE    tidmask; /* target id bit mask: 1 - 128 */
+#endif /* ADVANSYS_DEBUG */
+
+    ASC_DBG1(1, "asc_init_dev: target %d\n", (unsigned) scp->target);
+
+    /* The host's target id is set in init_tidmask during initialization. */
+    ASC_ASSERT(asc_dvc_varp->cfg->chip_scsi_id != scp->target);
+
+    boardp = ASC_BOARDP(scp->host);
+
+    /* Set-up AscInitPollTarget() arguments. */
+    scsireqq = &boardp->scsireqq;
+    memset(scsireqq, 0, sizeof(ASC_SCSI_REQ_Q));
+    cap_info = &boardp->cap_info;
+    memset(cap_info, 0, sizeof(ASC_CAP_INFO));
+    inquiry = &boardp->inquiry;
+    memset(inquiry, 0, sizeof(ASC_SCSI_INQUIRY));
+
+    /*
+     * AscInitPollBegin() re-initializes these bitmask fields to zero.
+     * Save the current bitmask value and 'or' them back in after calling
+     * AscInitPollEnd() below..
+     */
+    save_use_tagged_qng = asc_dvc_varp->use_tagged_qng;
+    save_can_tagged_qng = asc_dvc_varp->cfg->can_tagged_qng;
+
+    ASC_DBG(2, "asc_init_dev: AscInitPollBegin()\n");
+    if (AscInitPollBegin(asc_dvc_varp)) {
+        ASC_PRINT1("asc_init_dev: board %d: AscInitPollBegin() failed\n",
+            boardp->id);
+        return ASC_FALSE;
+    }
+
+    scsireqq->sense_ptr = &scsireqq->sense[0];
+    scsireqq->r1.sense_len = ASC_MIN_SENSE_LEN;
+    scsireqq->r1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
+    scsireqq->r1.target_lun = 0;
+    scsireqq->r2.target_ix = ASC_TIDLUN_TO_IX(scp->target, 0);
+
+    found = ASC_FALSE;
+    ASC_DBG(2, "asc_init_dev: AscInitPollTarget()\n");
+    switch (ret = AscInitPollTarget(asc_dvc_varp, scsireqq, inquiry,
+        cap_info)) {
+    case ASC_TRUE:
+        found = ASC_TRUE;
+#ifdef ADVANSYS_DEBUG
+        tidmask = ADV_TID_TO_TIDMASK(scp->target);
+        ASC_DBG2(1, "asc_init_dev: lba %lu, blk_size %lu\n",
+            cap_info->lba, cap_info->blk_size);
+        ASC_DBG1(1, "asc_init_dev: peri_dvc_type %x\n",
+            inquiry->byte0.peri_dvc_type);
+        if (asc_dvc_varp->use_tagged_qng & tidmask) {
+            ASC_DBG1(1, "asc_init_dev: command queuing enabled: %d\n",
+                asc_dvc_varp->max_dvc_qng[scp->target]);
+        } else {
+            ASC_DBG(1, "asc_init_dev: command queuing disabled\n");
+        }
+        if (asc_dvc_varp->init_sdtr & tidmask) {
+            ASC_DBG(1, "asc_init_dev: synchronous transfers enabled\n");
+        } else {
+            ASC_DBG(1, "asc_init_dev: synchronous transfers disabled\n");
+        }
+        /* Set bit means fix disabled. */
+        if (asc_dvc_varp->pci_fix_asyn_xfer & tidmask) {
+            ASC_DBG(1, "asc_init_dev: synchronous transfer fix disabled\n");
+        } else {
+            ASC_DBG(1, "asc_init_dev: synchronous transfer fix enabled\n");
+        }
+#endif /* ADVANSYS_DEBUG */
+        break;
+    case ASC_FALSE:
+        ASC_DBG(1, "asc_init_dev: no device found\n");
+        break;
+    case ASC_ERROR:
+        ASC_PRINT1("asc_init_dev: board %d: AscInitPollTarget() ASC_ERROR\n",
+                boardp->id);
+        break;
+    default:
+        ASC_PRINT2(
+"asc_init_dev: board %d: AscInitPollTarget() unknown ret %d\n",
+                boardp->id, ret);
+        break;
+    }
+
+    /* Restore previously set bits in the bitmask fields. */
+    asc_dvc_varp->use_tagged_qng |= save_use_tagged_qng;
+    asc_dvc_varp->cfg->can_tagged_qng |= save_can_tagged_qng;
+
+    ASC_DBG(2, "asc_init_dev: AscInitPollEnd()\n");
+    AscInitPollEnd(asc_dvc_varp);
+
+    ASC_DBG1(1, "asc_init_dev: found %d\n", found); 
 
     return found;
 }
@@ -5169,7 +7466,8 @@
             if ((vendorid == ASC_PCI_VENDORID) &&
                 ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
                  (deviceid == ASC_PCI_DEVICE_ID_1200) ||
-                 (deviceid == ASC_PCI_DEVICE_ID_1300))) {
+                 (deviceid == ASC_PCI_DEVICE_ID_1300) ||
+                 (deviceid == ASC_PCI_DEVICE_ID_2300))) {
                 pciDevice->slotFound = lslot;
                 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
                 return PCI_DEVICE_FOUND;
@@ -5483,13 +7781,13 @@
 {
     int        tid;
 
-    ASC_DBG3(2, "asc_enqueue: ascq %x, reqp %x, flag %d\n",
+    ASC_DBG3(3, "asc_enqueue: ascq %x, reqp %x, flag %d\n",
         (unsigned) ascq, (unsigned) reqp, flag);
     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
     tid = REQPTID(reqp);
-    ASC_ASSERT(tid >= 0 && tid <= ASC_MAX_TID);
+    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
     if (flag == ASC_FRONT) {
         REQPNEXT(reqp) = ascq->q_first[tid];
         ascq->q_first[tid] = reqp;
@@ -5509,19 +7807,19 @@
         }
     }
     /* The queue has at least one entry, set its bit. */
-    ascq->q_tidmask |= ASC_TIX_TO_TARGET_ID(tid);
+    ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
 #ifdef ADVANSYS_STATS
     /* Maintain request queue statistics. */
     ascq->q_tot_cnt[tid]++;
     ascq->q_cur_cnt[tid]++;
     if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
         ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
-        ASC_DBG2(1, "asc_enqueue: new q_max_cnt[%d] %d\n",
+        ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
             tid, ascq->q_max_cnt[tid]);
     }
     REQPTIME(reqp) = REQTIMESTAMP();
 #endif /* ADVANSYS_STATS */
-    ASC_DBG1(1, "asc_enqueue: reqp %x\n", (unsigned) reqp);
+    ASC_DBG1(3, "asc_enqueue: reqp %x\n", (unsigned) reqp);
     return;
 }
 
@@ -5537,15 +7835,15 @@
 {
     REQP    reqp;
 
-    ASC_DBG2(1, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid);
+    ASC_DBG2(3, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid);
     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
-    ASC_ASSERT(tid >= 0 && tid <= ASC_MAX_TID);
+    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
     if ((reqp = ascq->q_first[tid]) != NULL) {
-        ASC_ASSERT(ascq->q_tidmask & ASC_TIX_TO_TARGET_ID(tid));
+        ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
         ascq->q_first[tid] = REQPNEXT(reqp);
         /* If the queue is empty, clear its bit and the last pointer. */
         if (ascq->q_first[tid] == NULL) {
-            ascq->q_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
+            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
             ASC_ASSERT(ascq->q_last[tid] == reqp);
             ascq->q_last[tid] = NULL;
         }
@@ -5556,7 +7854,7 @@
         REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
 #endif /* ADVANSYS_STATS */
     }
-    ASC_DBG1(1, "asc_dequeue: reqp %x\n", (unsigned) reqp);
+    ASC_DBG1(3, "asc_dequeue: reqp %x\n", (unsigned) reqp);
     return reqp;
 }
 
@@ -5586,9 +7884,9 @@
     REQP    firstp, lastp;
     int     i;
 
-    ASC_DBG2(1, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid);
+    ASC_DBG2(3, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid);
     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
-    ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ASC_MAX_TID));
+    ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
 
     /*
      * If 'tid' is not ASC_TID_ALL, return requests only for
@@ -5597,14 +7895,14 @@
      */
     if (tid != ASC_TID_ALL) {
         /* Return all requests for the specified 'tid'. */
-        if ((ascq->q_tidmask & ASC_TIX_TO_TARGET_ID(tid)) == 0) {
+        if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
             /* List is empty; Set first and last return pointers to NULL. */
             firstp = lastp = NULL;
         } else {
             firstp = ascq->q_first[tid];
             lastp = ascq->q_last[tid];
             ascq->q_first[tid] = ascq->q_last[tid] = NULL;
-            ascq->q_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
+            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
 #ifdef ADVANSYS_STATS
             {
                 REQP reqp;
@@ -5618,8 +7916,8 @@
     } else {
         /* Return all requests for all tids. */
         firstp = lastp = NULL;
-        for (i = 0; i <= ASC_MAX_TID; i++) {
-            if (ascq->q_tidmask & ASC_TIX_TO_TARGET_ID(i)) {
+        for (i = 0; i <= ADV_MAX_TID; i++) {
+            if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
                 if (firstp == NULL) {
                     firstp = ascq->q_first[i];
                     lastp = ascq->q_last[i];
@@ -5629,7 +7927,7 @@
                     lastp = ascq->q_last[i];
                 }
                 ascq->q_first[i] = ascq->q_last[i] = NULL;
-                ascq->q_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
+                ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
 #ifdef ADVANSYS_STATS
                 ascq->q_cur_cnt[i] = 0;
 #endif /* ADVANSYS_STATS */
@@ -5647,7 +7945,7 @@
     if (lastpp) {
         *lastpp = lastp;
     }
-    ASC_DBG1(1, "asc_dequeue_list: firstp %x\n", (unsigned) firstp);
+    ASC_DBG1(3, "asc_dequeue_list: firstp %x\n", (unsigned) firstp);
     return firstp;
 }
 
@@ -5668,13 +7966,13 @@
     int         tid;
     int         ret = ASC_FALSE;
 
-    ASC_DBG2(1, "asc_rmqueue: ascq %x, reqp %x\n",
+    ASC_DBG2(3, "asc_rmqueue: ascq %x, reqp %x\n",
         (unsigned) ascq, (unsigned) reqp);
     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
 
     tid = REQPTID(reqp);
-    ASC_ASSERT(tid >= 0 && tid <= ASC_MAX_TID);
+    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
 
     /*
      * Handle the common case of 'reqp' being the first
@@ -5685,7 +7983,7 @@
         ascq->q_first[tid] = REQPNEXT(reqp);
         /* If the queue is now empty, clear its bit and the last pointer. */
         if (ascq->q_first[tid] == NULL) {
-            ascq->q_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
+            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
             ASC_ASSERT(ascq->q_last[tid] == reqp);
             ascq->q_last[tid] = NULL;
         }
@@ -5721,7 +8019,7 @@
     }
     ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
 #endif /* ADVANSYS_STATS */
-    ASC_DBG2(1, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret);
+    ASC_DBG2(3, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret);
     return ret;
 }
 
@@ -5736,22 +8034,22 @@
     int            tid;
     int            ret = ASC_FALSE;
 
-    ASC_DBG2(1, "asc_isqueued: ascq %x, reqp %x\n",
+    ASC_DBG2(3, "asc_isqueued: ascq %x, reqp %x\n",
         (unsigned) ascq, (unsigned) reqp);
     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
 
     tid = REQPTID(reqp);
-    ASC_ASSERT(tid >= 0 && tid <= ASC_MAX_TID);
+    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
 
     for (treqp = ascq->q_first[tid]; treqp; treqp = REQPNEXT(treqp)) {
-        ASC_ASSERT(ascq->q_tidmask & ASC_TIX_TO_TARGET_ID(tid));
+        ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
         if (treqp == reqp) {
             ret = ASC_TRUE;
             break;
         }
     }
-    ASC_DBG1(1, "asc_isqueued: ret %x\n", ret);
+    ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
     return ret;
 }
 
@@ -5763,9 +8061,9 @@
 STATIC void
 asc_execute_queue(asc_queue_t *ascq)
 {
-    ASC_SCSI_BIT_ID_TYPE    scan_tidmask;
+    ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
     REQP                    reqp;
-    int                        i;
+    int                     i;
 
     ASC_DBG1(1, "asc_execute_queue: ascq %x\n", (unsigned) ascq);
     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
@@ -5775,13 +8073,13 @@
      */
     scan_tidmask = ascq->q_tidmask;
     do {
-        for (i = 0; i <= ASC_MAX_TID; i++) {
-            if (scan_tidmask & ASC_TIX_TO_TARGET_ID(i)) {
+        for (i = 0; i <= ADV_MAX_TID; i++) {
+            if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
-                    scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
+                    scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
                             == ASC_BUSY) {
-                    scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
+                    scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                     /* Put the request back at front of the list. */
                     asc_enqueue(ascq, reqp, ASC_FRONT);
                 }
@@ -5810,6 +8108,7 @@
     int                leftlen;
     int                totlen;
     int                len;
+    int                chip_scsi_id;
     int                i;
 
     boardp = ASC_BOARDP(shp);
@@ -5820,25 +8119,166 @@
 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
     ASC_PRT_NEXT();
 
-    len = asc_prt_line(cp, leftlen, "Target Ids Detected:");
+    if (ASC_NARROW_BOARD(boardp)) {
+        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
+    } else {
+        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
+    }
+
+    len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
     ASC_PRT_NEXT();
-    for (i = 0; i <= ASC_MAX_TID; i++) {
-        if (boardp->asc_dvc_cfg.chip_scsi_id == i) {
-            continue;
-        } else if (boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) {
-            len = asc_prt_line(cp, leftlen, " %d,", i);
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
+            len = asc_prt_line(cp, leftlen, " %X,", i);
             ASC_PRT_NEXT();
         }
     }
-    len = asc_prt_line(cp, leftlen, " (%d=Host Adapter)\n",
-                       boardp->asc_dvc_cfg.chip_scsi_id);
+    len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
     ASC_PRT_NEXT();
 
-     return totlen;
+    return totlen;
+}
+
+/*
+ * Display Wide Board BIOS Information.
+ */
+STATIC int
+asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
+{
+    asc_board_t        *boardp;
+    int                leftlen;
+    int                totlen;
+    int                len;
+    int                upgrade = ASC_FALSE;
+    ushort             major, minor, letter;
+
+    boardp = ASC_BOARDP(shp);
+    leftlen = cplen;
+    totlen = len = 0;
+
+    len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
+    ASC_PRT_NEXT();
+
+    /*
+     * If the BIOS saved a valid signature, then fill in
+     * the BIOS code segment base address.
+     */
+    if (boardp->bios_signature != 0x55AA) {
+        len = asc_prt_line(cp, leftlen, "Pre-3.1\n");
+        ASC_PRT_NEXT();
+        upgrade = ASC_TRUE;
+    } else {
+        major = (boardp->bios_version >> 12) & 0xF;
+        minor = (boardp->bios_version >> 8) & 0xF;
+        letter = (boardp->bios_version & 0xFF);
+
+        len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
+            major, minor, letter >= 26 ? '?' : letter + 'A');
+        ASC_PRT_NEXT();
+
+        /* Current available ROM BIOS release is 3.1E. */
+        if (major < 3 || (major <= 3 && minor < 1) ||
+            (major <= 3 && minor <= 1 && letter < ('E'- 'A'))) {
+            upgrade = ASC_TRUE;
+        }
+    }
+    if (upgrade == ASC_TRUE) {
+        len = asc_prt_line(cp, leftlen,
+"Newer version of ROM BIOS available: ftp://ftp.advansys.com/pub\n");
+            ASC_PRT_NEXT();
+    }
+
+    return totlen;
+}
+
+/*
+ * Add serial number to information bar if signature AAh
+ * is found in at bit 15-9 (7 bits) of word 1.
+ *
+ * Serial Number consists 12 alpha-numeric digits.
+ *
+ *       1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
+ *       2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
+ *     3-4 - Product ID (0-99)        Word0: 10-0 (11 bits)
+ *       5 - Product revision         Word0:  "         "
+ *
+ *         Signature                Word1: 15-9 (7 bits)
+ *       6 - Year (4-9)               Word1: 8-6 (3 bits)
+ *     7-8 - Week of the year         Word1: 5-0 (6 bits)
+ *
+ *    9-12 - Serial Number            Word2: 15-0 (16 bits)
+ *
+ * Note 1: Only production cards will have a serial number.
+ *
+ * Note 2: Signature is most significant 7 bits (0xFE).
+ *
+ * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
+ */
+STATIC int
+asc_get_eeprom_string(ushort *serialnum, uchar *cp)
+{
+    ushort      w, num;
+
+    if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
+        return ASC_FALSE;
+    } else {
+        /*
+         * First word - 6 digits.
+         */
+        w = serialnum[0];
+
+        /* Product type - 1st digit. */
+        *cp++ = 'A' + ((w & 0xE000) >> 13);
+
+        /* Manufacturing location - 2nd digit. */
+        *cp++ = 'A' + ((w & 0x1C00) >> 10);
+
+        /* Product ID - 3rd, 4th digits. */
+        num = w & 0x3FF;
+        *cp++ = '0' + (num / 100);
+        num %= 100;
+        *cp++ = '0' + (num / 10);
+
+        /* Product revision - 5th digit. */
+        *cp++ = 'A' + (num % 10);
+
+        /*
+         * Second word
+         */
+        w = serialnum[1];
+
+        /* Year - 6th digit. */
+        *cp++ = '0' + ((w & 0x1C0) >> 6);
+
+        /* Week of year - 7th, 8th digits. */
+        num = w & 0x003F;
+        *cp++ = '0' + num / 10;
+        num %= 10;
+        *cp++ = '0' + num;
+
+        /*
+         * Third word
+         */
+        w = serialnum[2];
+
+        /* Serial number - 9th digit. */
+        *cp++ = 'A' + (w / 1000);
+
+        /* 10th, 11th, 12th digits. */
+        num = w % 1000;
+        *cp++ = '0' + num / 100;
+        num %= 100;
+        *cp++ = '0' + num / 10;
+        num %= 10;
+        *cp++ = '0' + num;
+
+        *cp = '\0';     /* Null Terminate the string. */
+        return ASC_TRUE;
+    }
 }
 
 /*
- * asc_prt_board_eeprom()
+ * asc_prt_asc_board_eeprom()
  *
  * Print board EEPROM configuration.
  *
@@ -5849,7 +8289,7 @@
  * 'cplen' characters will be copied to 'cp'.
  */
 STATIC int
-asc_prt_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
+asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
 {
     asc_board_t        *boardp;
     ASC_DVC_VAR        *asc_dvc_varp;
@@ -5859,10 +8299,11 @@
     ASCEEP_CONFIG      *ep;
     int                i;
     int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
+    uchar              serialstr[13];
 
     boardp = ASC_BOARDP(shp);
-    asc_dvc_varp = &boardp->asc_dvc_var;
-    ep = &boardp->eep_config;
+    asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
+    ep = &boardp->eep_config.asc_eep;
 
     leftlen = cplen;
     totlen = len = 0;
@@ -5871,17 +8312,48 @@
 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
     ASC_PRT_NEXT();
 
-    len = asc_prt_line(cp, leftlen,
-" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
-        ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
-    ASC_PRT_NEXT();
-
-    len = asc_prt_line(cp, leftlen,
-" Disconnects:         ");
+    if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
+        ASC_TRUE) {
+        len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
+        ASC_PRT_NEXT();
+    } else {
+        if (ep->adapter_info[5] == 0xBB) {
+            len = asc_prt_line(cp, leftlen,
+                " Default Settings Used for EEPROM-less Adapter.\n");
+            ASC_PRT_NEXT();
+        } else {
+            len = asc_prt_line(cp, leftlen,
+                " Serial Number Signature Not Present.\n");
+            ASC_PRT_NEXT();
+        }
+    }
+
+    len = asc_prt_line(cp, leftlen,
+" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+        ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" cntl %x, no_scam %x\n",
+        ep->cntl, ep->no_scam);
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Target ID:           ");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        len = asc_prt_line(cp, leftlen, " %d:%c",
-            i, (ep->disc_enable & ASC_TIX_TO_TARGET_ID(i)) ? 'Y' : 'N');
+        len = asc_prt_line(cp, leftlen, " %d", i);
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Disconnects:         ");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ASC_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -5891,8 +8363,8 @@
 " Command Queuing:     ");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        len = asc_prt_line(cp, leftlen, " %d:%c",
-            i, (ep->use_cmd_qng & ASC_TIX_TO_TARGET_ID(i)) ? 'Y' : 'N');
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -5902,8 +8374,8 @@
 " Start Motor:         ");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        len = asc_prt_line(cp, leftlen, " %d:%c",
-            i, (ep->start_motor & ASC_TIX_TO_TARGET_ID(i)) ? 'Y' : 'N');
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -5913,8 +8385,8 @@
 " Synchronous Transfer:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        len = asc_prt_line(cp, leftlen, " %d:%c",
-            i, (ep->init_sdtr & ASC_TIX_TO_TARGET_ID(i)) ? 'Y' : 'N');
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -5931,6 +8403,156 @@
 }
 
 /*
+ * asc_prt_adv_board_eeprom()
+ *
+ * Print board EEPROM configuration.
+ *
+ * Note: no single line should be greater than ASC_PRTLINE_SIZE,
+ * cf. asc_prt_line().
+ *
+ * Return the number of characters copied into 'cp'. No more than
+ * 'cplen' characters will be copied to 'cp'.
+ */
+STATIC int
+asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
+{
+    asc_board_t        *boardp;
+    ADV_DVC_VAR        *adv_dvc_varp;
+    int                leftlen;
+    int                totlen;
+    int                len;
+    int                i;
+    char               *termstr;
+    uchar              serialstr[13];
+    ADVEEP_CONFIG      *ep;
+
+    boardp = ASC_BOARDP(shp);
+    adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
+    ep = &boardp->eep_config.adv_eep;
+
+    leftlen = cplen;
+    totlen = len = 0;
+
+    len = asc_prt_line(cp, leftlen,
+"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
+    ASC_PRT_NEXT();
+
+    if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) ==
+        ASC_TRUE) {
+        len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
+        ASC_PRT_NEXT();
+    } else {
+        len = asc_prt_line(cp, leftlen,
+            " Serial Number Signature Not Present.\n");
+        ASC_PRT_NEXT();
+    }
+
+    len = asc_prt_line(cp, leftlen,
+" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+        ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng);
+    ASC_PRT_NEXT();
+
+    switch (ep->termination) {
+        case 1:
+            termstr = "Low Off/High Off";
+            break;
+        case 2:
+            termstr = "Low Off/High On";
+            break;
+        case 3:
+            termstr = "Low On/High On";
+            break;
+        default:
+        case 0:
+            termstr = "Automatic";
+            break;
+    }
+
+    len = asc_prt_line(cp, leftlen,
+" termination: %u (%s), bios_ctrl: %x\n",
+        ep->termination, termstr, ep->bios_ctrl);
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Target ID:           ");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %X", i);
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Disconnects:         ");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Command Queuing:     ");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Start Motor:         ");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Synchronous Transfer:");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Ultra Transfer:      ");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Wide Transfer:       ");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        len = asc_prt_line(cp, leftlen, " %c",
+            (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    return totlen;
+}
+
+/*
  * asc_prt_driver_conf()
  *
  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
@@ -5946,6 +8568,7 @@
     int                    leftlen;
     int                    totlen;
     int                    len;
+    int                    chip_scsi_id;
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
     int                    i;
 #endif /* version >= v1.3.89 */
@@ -5992,65 +8615,82 @@
 #endif /* version >= v1.3.57 */
     ASC_PRT_NEXT();
 
-    len = asc_prt_line(cp, leftlen,
-" flags %x, last_reset %x, jiffies %x\n",
-        ASC_BOARDP(shp)->flags, ASC_BOARDP(shp)->last_reset, jiffies);
+    len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
+        boardp->flags, boardp->last_reset, jiffies);
     ASC_PRT_NEXT();
 
+    if (ASC_NARROW_BOARD(boardp)) {
+        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
+    } else {
+        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
+    }
+
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-    len = asc_prt_line(cp, leftlen,
-" queue_depth:     ");
-    ASC_PRT_NEXT();
-    for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
-            continue;
+    if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
+        len = asc_prt_line(cp, leftlen, " queue_depth:");
+        ASC_PRT_NEXT();
+        for (i = 0; i <= ADV_MAX_TID; i++) {
+            if ((chip_scsi_id == i) ||
+                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+                continue;
+            }
+            if (boardp->device[i] == NULL) {
+                continue;
+            }
+            len = asc_prt_line(cp, leftlen, " %X:%d",
+                i, boardp->device[i]->queue_depth);
+            ASC_PRT_NEXT();
         }
-        len = asc_prt_line(cp, leftlen, " %d:%d",
-            i, boardp->device[i]->queue_depth);
+        len = asc_prt_line(cp, leftlen, "\n");
         ASC_PRT_NEXT();
     }
-    len = asc_prt_line(cp, leftlen, "\n");
-    ASC_PRT_NEXT();
 #endif /* version >= v1.3.89 */
 
 #if ASC_QUEUE_FLOW_CONTROL
-    len = asc_prt_line(cp, leftlen,
-" queue_curr_depth:");
-    ASC_PRT_NEXT();
-    for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
-            continue;
+    if (ASC_NARROW_BOARD(boardp)) {
+        len = asc_prt_line(cp, leftlen, " queue_curr_depth:");
+        ASC_PRT_NEXT();
+        /* Use ASC_MAX_TID for Narrow Board. */
+        for (i = 0; i <= ASC_MAX_TID; i++) {
+            if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
+                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+                continue;
+            }
+            if (boardp->device[i] == NULL) {
+                continue;
+            }
+            len = asc_prt_line(cp, leftlen, " %d:%d",
+                i, boardp->device[i]->queue_curr_depth);
+            ASC_PRT_NEXT();
         }
-        len = asc_prt_line(cp, leftlen, " %d:%d",
-            i, boardp->device[i]->queue_curr_depth);
+        len = asc_prt_line(cp, leftlen, "\n");
         ASC_PRT_NEXT();
-    }
-    len = asc_prt_line(cp, leftlen, "\n");
-    ASC_PRT_NEXT();
 
-    len = asc_prt_line(cp, leftlen,
-" queue_count:     ");
-    ASC_PRT_NEXT();
-    for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
-            continue;
+        len = asc_prt_line(cp, leftlen, " queue_count:");
+        ASC_PRT_NEXT();
+        /* Use ASC_MAX_TID for Narrow Board. */
+        for (i = 0; i <= ASC_MAX_TID; i++) {
+            if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
+                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+                continue;
+            }
+            if (boardp->device[i] == NULL) {
+                continue;
+            }
+            len = asc_prt_line(cp, leftlen, " %d:%d",
+                i, boardp->device[i]->queue_count);
+            ASC_PRT_NEXT();
         }
-        len = asc_prt_line(cp, leftlen, " %d:%d",
-            i, boardp->device[i]->queue_count);
+        len = asc_prt_line(cp, leftlen, "\n");
         ASC_PRT_NEXT();
     }
-    len = asc_prt_line(cp, leftlen, "\n");
-    ASC_PRT_NEXT();
 #endif /* ASC_QUEUE_FLOW_CONTROL */
 
-     return totlen;
+    return totlen;
 }
 
 /*
- * asc_prt_board_info()
+ * asc_prt_asc_board_info()
  *
  * Print dynamic board configuration information.
  *
@@ -6061,7 +8701,7 @@
  * 'cplen' characters will be copied to 'cp'.
  */
 STATIC int
-asc_prt_board_info(struct Scsi_Host *shp, char *cp, int cplen)
+asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 {
     asc_board_t            *boardp;
     int                    leftlen;
@@ -6072,8 +8712,8 @@
     int                    i;
 
     boardp = ASC_BOARDP(shp);
-    v = &boardp->asc_dvc_var;
-    c = &boardp->asc_dvc_cfg;
+    v = &boardp->dvc_var.asc_dvc_var;
+    c = &boardp->dvc_cfg.asc_dvc_cfg;
 
     leftlen = cplen;
     totlen = len = 0;
@@ -6084,30 +8724,30 @@
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" chip_version %u, lib_version %u, lib_serial_no %u, mcode_date %u\n",
+" chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
         c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" mcode_version %u, err_code %u\n",
+" mcode_version %x, err_code %u\n",
          c->mcode_version, v->err_code);
     ASC_PRT_NEXT();
 
     /* Current number of commands waiting for the host. */
     len = asc_prt_line(cp, leftlen,
-" Total Command Pending:    %d\n", v->cur_total_qng);
+" Total Command Pending: %d\n", v->cur_total_qng);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" Command Queuing:         ");
+" Command Queuing:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
+        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
         len = asc_prt_line(cp, leftlen, " %d:%c",
-            i, (v->use_tagged_qng & ASC_TIX_TO_TARGET_ID(i)) ? 'Y' : 'N');
+            i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -6115,11 +8755,11 @@
 
     /* Current number of commands waiting for a device. */
     len = asc_prt_line(cp, leftlen,
-" Command Queue Pending:   ");
+" Command Queue Pending:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
+        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]);
@@ -6130,11 +8770,11 @@
 
     /* Current limit on number of commands that can be sent to a device. */
     len = asc_prt_line(cp, leftlen,
-" Command Queue Limit:     ");
+" Command Queue Limit:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
+        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]);
@@ -6145,14 +8785,14 @@
 
     /* Indicate whether the device has returned queue full status. */
     len = asc_prt_line(cp, leftlen,
-" Command Queue Full:      ");
+" Command Queue Full:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
+        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
-        if (boardp->queue_full & ASC_TIX_TO_TARGET_ID(i)) {
+        if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
             len = asc_prt_line(cp, leftlen, " %d:Y-%d",
                 i, boardp->queue_full_cnt[i]);
         } else {
@@ -6164,15 +8804,15 @@
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" Synchronous Transfer:    ");
+" Synchronous Transfer:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
+        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
         len = asc_prt_line(cp, leftlen, " %d:%c",
-            i, (v->sdtr_done & ASC_TIX_TO_TARGET_ID(i)) ? 'Y' : 'N');
+            i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -6181,15 +8821,15 @@
     for (i = 0; i <= ASC_MAX_TID; i++) {
         uchar syn_period_ix;
 
-        if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ASC_TIX_TO_TARGET_ID(i)) == 0)) {
+        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
-        if ((v->sdtr_done & ASC_TIX_TO_TARGET_ID(i)) == 0) {
+        if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
             continue;
         }
         syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
-        len = asc_prt_line(cp, leftlen, "   %d:", i);
+        len = asc_prt_line(cp, leftlen, "  %d:", i);
         ASC_PRT_NEXT();
 
         len = asc_prt_line(cp, leftlen,
@@ -6204,78 +8844,265 @@
         ASC_PRT_NEXT();
     }
 
-     return totlen;
-}
-
-/*
- * asc_proc_copy() 
- *
- * Copy proc information to a read buffer taking into account the current
- * read offset in the file and the remaining space in the read buffer.
- */
-STATIC int
-asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
-              char *cp, int cplen)
-{
-    int cnt = 0;
-    
-    ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
-            (unsigned) offset, (unsigned) advoffset, cplen);
-    if (offset <= advoffset) {
-        /* Read offset below current offset, copy everything. */
-        cnt = ASC_MIN(cplen, leftlen);
-        ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
-                (unsigned) curbuf, (unsigned) cp, cnt);
-        memcpy(curbuf, cp, cnt);
-    } else if (offset < advoffset + cplen) {
-        /* Read offset within current range, partial copy. */
-        cnt = (advoffset + cplen) - offset;
-        cp = (cp + cplen) - cnt;
-        cnt = ASC_MIN(cnt, leftlen);
-        ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
-                (unsigned) curbuf, (unsigned) cp, cnt);
-        memcpy(curbuf, cp, cnt);
-    }
-    return cnt;
+    return totlen;
 }
 
 /*
- * asc_prt_line()
+ * asc_prt_adv_board_info()
  *
- * If 'cp' is NULL print to the console, otherwise print to a buffer.
+ * Print dynamic board configuration information.
  *
- * Return 0 if printing to the console, otherwise return the number of
- * bytes written to the buffer.
+ * Note: no single line should be greater than ASC_PRTLINE_SIZE,
+ * cf. asc_prt_line().
  *
- * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
- * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
+ * Return the number of characters copied into 'cp'. No more than
+ * 'cplen' characters will be copied to 'cp'.
  */
 STATIC int
-asc_prt_line(char *buf, int buflen, char *fmt, ...)
+asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 {
-    va_list        args;
-    int            ret;
-    char        s[ASC_PRTLINE_SIZE];
+    asc_board_t            *boardp;
+    int                    leftlen;
+    int                    totlen;
+    int                    len;
+    int                    i;
+    ADV_DVC_VAR            *v;
+    ADV_DVC_CFG            *c;
+    AdvPortAddr            iop_base;
+    ushort                 chip_scsi_id;
+    ushort                 lramword;
+    uchar                  lrambyte;
+    ushort                 sdtr_able;
+    ushort                 period;
 
-    va_start(args, fmt);
-    ret = vsprintf(s, fmt, args);
-    ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
-    if (buf == NULL) {
-        (void) printk(s);
-        ret = 0;
-    } else {
-        ret = ASC_MIN(buflen, ret);
-        memcpy(buf, s, ret);
-    }
-    va_end(args);
-    return ret;
-}
-#endif /* version >= v1.3.0 */
+    boardp = ASC_BOARDP(shp);
+    v = &boardp->dvc_var.adv_dvc_var;
+    c = &boardp->dvc_cfg.adv_dvc_cfg;
+    iop_base = v->iop_base;
+    chip_scsi_id = v->chip_scsi_id;
 
+    leftlen = cplen;
+    totlen = len = 0;
 
-/*
- * --- Functions Required by the Asc Library
- */
+    len = asc_prt_line(cp, leftlen,
+"\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
+    shp->host_no);
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n",
+         v->iop_base,
+         AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
+         v->err_code, v->idle_cmd_done);
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
+        c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
+    ASC_PRT_NEXT();
+
+    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword);
+    len = asc_prt_line(cp, leftlen,
+" Queuing Enabled:");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+            continue;
+        }
+
+        len = asc_prt_line(cp, leftlen, " %X:%c",
+            i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Queue Limit:");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+            continue;
+        }
+
+        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
+
+        len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Command Pending:");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+            continue;
+        }
+
+        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
+
+        len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword);
+    len = asc_prt_line(cp, leftlen,
+" Wide Enabled:");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+            continue;
+        }
+
+        len = asc_prt_line(cp, leftlen, " %X:%c",
+            i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    len = asc_prt_line(cp, leftlen,
+" Transfer Bit Width:");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+            continue;
+        }
+
+        AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
+            lramword);
+        len = asc_prt_line(cp, leftlen, " %X:%d",
+            i, (lramword & 0x8000) ? 16 : 8);
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    len = asc_prt_line(cp, leftlen,
+" Synchronous Enabled:");
+    ASC_PRT_NEXT();
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+            continue;
+        }
+
+        len = asc_prt_line(cp, leftlen, " %X:%c",
+            i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+    }
+    len = asc_prt_line(cp, leftlen, "\n");
+    ASC_PRT_NEXT();
+
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+
+        AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
+            lramword);
+        lramword &= ~0x8000;
+
+        if ((chip_scsi_id == i) ||
+            ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0) ||
+            (lramword == 0)) {
+            continue;
+        }
+
+        len = asc_prt_line(cp, leftlen, "  %X:", i);
+        ASC_PRT_NEXT();
+        
+        period = (((lramword >> 8) * 25) + 50)/4;
+
+        len = asc_prt_line(cp, leftlen,
+            " Transfer Period Factor: %d (%d.%d Mhz),",
+            period, 250/period, ASC_TENTHS(250, period));
+        ASC_PRT_NEXT();
+
+        len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
+            lramword & 0x1F);
+        ASC_PRT_NEXT();
+    }
+
+    return totlen;
+}
+
+/*
+ * asc_proc_copy() 
+ *
+ * Copy proc information to a read buffer taking into account the current
+ * read offset in the file and the remaining space in the read buffer.
+ */
+STATIC int
+asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
+              char *cp, int cplen)
+{
+    int cnt = 0;
+    
+    ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
+            (unsigned) offset, (unsigned) advoffset, cplen);
+    if (offset <= advoffset) {
+        /* Read offset below current offset, copy everything. */
+        cnt = ASC_MIN(cplen, leftlen);
+        ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
+                (unsigned) curbuf, (unsigned) cp, cnt);
+        memcpy(curbuf, cp, cnt);
+    } else if (offset < advoffset + cplen) {
+        /* Read offset within current range, partial copy. */
+        cnt = (advoffset + cplen) - offset;
+        cp = (cp + cplen) - cnt;
+        cnt = ASC_MIN(cnt, leftlen);
+        ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
+                (unsigned) curbuf, (unsigned) cp, cnt);
+        memcpy(curbuf, cp, cnt);
+    }
+    return cnt;
+}
+
+/*
+ * asc_prt_line()
+ *
+ * If 'cp' is NULL print to the console, otherwise print to a buffer.
+ *
+ * Return 0 if printing to the console, otherwise return the number of
+ * bytes written to the buffer.
+ *
+ * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
+ * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
+ */
+STATIC int
+asc_prt_line(char *buf, int buflen, char *fmt, ...)
+{
+    va_list        args;
+    int            ret;
+    char        s[ASC_PRTLINE_SIZE];
+
+    va_start(args, fmt);
+    ret = vsprintf(s, fmt, args);
+    ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
+    if (buf == NULL) {
+        (void) printk(s);
+        ret = 0;
+    } else {
+        ret = ASC_MIN(buflen, ret);
+        memcpy(buf, s, ret);
+    }
+    va_end(args);
+    return ret;
+}
+#endif /* version >= v1.3.0 */
+
+
+/*
+ * --- Functions Required by the Asc Library
+ */
 
 /*
  * Delay for 'n' milliseconds. Don't use the 'jiffies'
@@ -6413,7 +9240,6 @@
         *inbuf = inpw(iop_base);
 }
 
-
 /*
  * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
  *
@@ -6531,6 +9357,81 @@
 
 
 /*
+ * --- Functions Required by the Adv Library
+ */
+
+/*
+ * DvcGetPhyAddr()
+ *
+ * Return the physical address of 'vaddr' and set '*lenp' to the
+ * number of physically contiguous bytes that follow 'vaddr'.
+ * 'flag' indicates the type of structure whose physical address
+ * is being translated.
+ *
+ * Note: Because Linux currently doesn't page the kernel and all
+ * kernel buffers are physically contiguous, leave '*lenp' unchanged.
+ */
+ulong
+DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
+        uchar *vaddr, long *lenp, int flag)
+{
+    ulong                paddr;
+
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
+    paddr = (ulong) vaddr;
+#else /* version >= v2.0.0 */
+    paddr = virt_to_bus(vaddr);
+#endif /* version >= v2.0.0 */
+
+    ASC_DBG4(4,
+        "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", 
+        (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), paddr);
+
+    return paddr;
+}
+
+/*
+ * Read a PCI configuration byte.
+ */
+ASC_INITFUNC(
+STATIC uchar
+DvcAdvReadPCIConfigByte(
+        ADV_DVC_VAR *asc_dvc, 
+        ushort offset)
+)
+{
+    PCI_DATA    pciData;
+
+    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
+    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
+    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
+    pciData.offset = offset;
+    pciData.type = pci_scan_method;
+    return asc_get_cfg_byte(&pciData);
+}
+
+/*
+ * Write a PCI configuration byte.
+ */
+ASC_INITFUNC(
+STATIC void
+DvcAdvWritePCIConfigByte(
+        ADV_DVC_VAR *asc_dvc, 
+        ushort offset, 
+        uchar  byte_data)
+)
+{
+    PCI_DATA    pciData;
+
+    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
+    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
+    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
+    pciData.offset = offset;
+    pciData.type = pci_scan_method;
+    asc_put_cfg_byte(&pciData, byte_data);
+}
+
+/*
  * --- Tracing and Debugging Functions
  */
 
@@ -6550,15 +9451,19 @@
     int                    leftlen;
     int                    totlen;
     int                    len;
-    struct asc_stats    *s;
+    struct asc_stats       *s;
     int                    i;
+    ushort                 chip_scsi_id;
+    asc_board_t            *boardp;
     asc_queue_t            *active;
     asc_queue_t            *waiting;
 
     leftlen = cplen;
     totlen = len = 0;
 
-    s = &ASC_BOARDP(shp)->asc_stats;
+    boardp = ASC_BOARDP(shp);
+    s = &boardp->asc_stats;
+
     len = asc_prt_line(cp, leftlen,
 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
     ASC_PRT_NEXT();
@@ -6569,13 +9474,24 @@
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" check_interrupt %lu, interrupt %lu, callback %lu, done %lu\n",
-        s->check_interrupt, s->interrupt, s->callback, s->done);
+" interrupt %lu, callback %lu, done %lu\n",
+        s->interrupt, s->callback, s->done);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" asc_noerror %lu, asc_busy %lu, asc_error %lu, asc_unknown %lu\n",
-        s->asc_noerror, s->asc_busy, s->asc_error, s->asc_unknown);
+" exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
+        s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
+    ASC_PRT_NEXT();
+
+    if (ASC_NARROW_BOARD(boardp)) {
+        len = asc_prt_line(cp, leftlen,
+" build_error %lu\n",
+         s->build_error);
+    } else {
+        len = asc_prt_line(cp, leftlen,
+" build_error %lu, build_noreq %lu, build_nosg %lu\n",
+         s->build_error, s->adv_build_noreq, s->adv_build_nosg);
+    }
     ASC_PRT_NEXT();
 
     /*
@@ -6629,12 +9545,25 @@
      * Display request queuing statistics.
      */
     len = asc_prt_line(cp, leftlen,
-" Active and Waiting Request Queues (time unit: %d HZ):\n", HZ);
+" Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
     ASC_PRT_NEXT();
 
     active = &ASC_BOARDP(shp)->active;
     waiting = &ASC_BOARDP(shp)->waiting;
-    for (i = 0; i < ASC_MAX_TID + 1; i++) {
+
+    if (ASC_NARROW_BOARD(boardp)) {
+        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
+    } else {
+        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
+    }
+
+    for (i = 0; i <= ADV_MAX_TID; i++) {
+
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+            continue;
+        }
+
         if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
             len = asc_prt_line(cp, leftlen, " target %d\n", i);
             ASC_PRT_NEXT();
@@ -6674,22 +9603,20 @@
 STATIC void 
 asc_prt_scsi_host(struct Scsi_Host *s)
 {
+    asc_board_t         *boardp;
+
+    boardp = ASC_BOARDP(s);
+
     printk("Scsi_Host at addr %x\n", (unsigned) s);
     printk(
 " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
         (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
         (unsigned) s->last_reset);
 
-#ifdef ERIC_neverdef /* { */
-	/*
-	 * This information is private to the mid-layer scsi and the
-	 * the low-level drivers shouldn't even be aware that it is there.
-	 */
     printk(
 " host_wait %x, host_queue %x, hostt %x, block %x,\n",
         (unsigned) s->host_wait, (unsigned) s->host_queue,
         (unsigned) s->hostt, (unsigned) s->block);
-#endif /* ERIC_neverdef */ /* } */
 
     printk(
 " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
@@ -6704,8 +9631,13 @@
         s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
         s->loaded_as_module);
 
-    asc_prt_dvc_var(&ASC_BOARDP(s)->asc_dvc_var);
-    asc_prt_dvc_cfg(&ASC_BOARDP(s)->asc_dvc_cfg);
+    if (ASC_NARROW_BOARD(boardp)) {
+        asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
+        asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
+    } else {
+        asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
+        asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
+    }
 }
 
 /*
@@ -6763,10 +9695,10 @@
 }
 
 /*
- * asc_prt_dvc_var()
+ * asc_prt_asc_dvc_var()
  */
 STATIC void 
-asc_prt_dvc_var(ASC_DVC_VAR *h)
+asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
 {
     printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
 
@@ -6805,10 +9737,10 @@
 }
 
 /*
- * asc_prt_dvc_cfg()
+ * asc_prt_asc_dvc_cfg()
  */
 STATIC void 
-asc_prt_dvc_cfg(ASC_DVC_CFG *h)
+asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
 {
     printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
 
@@ -6822,7 +9754,7 @@
              h->chip_version);
 
     printk(
-" pci_device_id %d, lib_serial_no %d, lib_version %d, mcode_date %d,\n",
+" pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
           h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
 
     printk(
@@ -6831,10 +9763,10 @@
 }
 
 /*
- * asc_prt_scsi_q()
+ * asc_prt_asc_scsi_q()
  */
 STATIC void 
-asc_prt_scsi_q(ASC_SCSI_Q *q)
+asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
 {
     ASC_SG_HEAD    *sgp;
     int i;
@@ -6869,10 +9801,10 @@
 }
 
 /*
- * asc_prt_qdone_info()
+ * asc_prt_asc_qdone_info()
  */
 STATIC void 
-asc_prt_qdone_info(ASC_QDONE_INFO *q)
+asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
 {
     printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
     printk(
@@ -6885,33 +9817,185 @@
 }
 
 /*
- * asc_prt_hex()
+ * asc_prt_adv_dvc_var()
  *
- * Print hexadecimal output in 4 byte groupings 32 bytes 
- * or 8 double-words per line.
+ * Display an ADV_DVC_VAR structure.
  */
 STATIC void 
-asc_prt_hex(char *f, uchar *s, int l)
+asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
 {
-    int            i;
-    int            j;
-    int            k;
-    int            m;
+    printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
 
-    printk("%s: (%d bytes)\n", f, l);
+    printk(
+"  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
+        (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
 
-    for (i = 0; i < l; i += 32) {
-        
-        /* Display a maximum of 8 double-words per line. */
-        if ((k = (l - i) / 4) >= 8) {
-            k = 8;
-            m = 0;
-        } else {
-            m = (l - i) % 4 ;
-        }
+    printk(
+"  isr_callback 0x%x, sdtr_able 0x%x, wdtr_able 0x%x\n",
+        (unsigned) h->isr_callback, (unsigned) h->wdtr_able,
+        (unsigned) h->sdtr_able);
 
-        for (j = 0; j < k; j++) {
-            printk(" %2.2X%2.2X%2.2X%2.2X",
+    printk(
+"  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
+        (unsigned) h->start_motor,
+        (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
+
+    printk(
+"  max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n",
+        (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng,
+        (unsigned) h->max_dvc_qng);
+
+    printk(
+"  no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n",
+        (unsigned) h->no_scam, (unsigned) h->tagqng_able,
+        (unsigned) h->chip_scsi_id, (ulong) h->cfg);
+
+}
+
+/*
+ * asc_prt_adv_dvc_cfg()
+ *
+ * Display an ADV_DVC_CFG structure.
+ */
+STATIC void 
+asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
+{
+    printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
+
+    printk(
+"  disc_enable 0x%x, termination 0x%x\n",
+        h->disc_enable, h->termination);
+
+    printk(
+"  chip_version 0x%x, mcode_date 0x%x\n",
+        h->chip_version, h->mcode_date);
+
+    printk(
+"  mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
+       h->mcode_version, h->pci_device_id, h->lib_version);
+
+    printk(
+"  control_flag 0x%x, pci_slot_info 0x%x\n",
+       h->control_flag, h->pci_slot_info);
+}
+
+/*
+ * asc_prt_adv_scsi_req_q()
+ *
+ * Display an ADV_SCSI_REQ_Q structure.
+ */
+STATIC void 
+asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
+{
+    int                 i;
+    struct asc_sg_block *sg_ptr;
+
+    printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q);
+
+    printk(
+"  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
+            q->target_id, q->target_lun, q->srb_ptr, q->a_flag);
+
+    printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
+            q->cntl, q->data_addr, q->vdata_addr);
+
+    printk(
+"  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
+            q->data_cnt, q->sense_addr, q->sense_len);
+
+    printk(
+"  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
+            q->cdb_len, q->done_status, q->host_status, q->scsi_status);
+
+    printk(
+"  vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n",
+            (ulong) q->vsense_addr, (ulong) q->scsiq_ptr,
+            (ulong) q->ux_wk_data_cnt);
+
+    printk(
+"  sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n",
+            (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt);
+
+    printk(
+"  ux_sg_ix %u, orig_sense_len %u\n",
+            q->ux_sg_ix, q->orig_sense_len);
+
+    /* Display the request's ADV_SG_BLOCK structures. */
+    for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL;
+        sg_ptr = sg_ptr->sg_ptr, i++) {
+        /*
+         * 'sg_ptr' is a physical address. Convert it to a virtual
+         * address by indexing 'i' into the virtual address array
+         * 'sg_list_ptr'.
+         *
+         * At the end of the each iteration of the loop 'sg_ptr' is
+         * converted back into a physical address by setting 'sg_ptr'
+         *  to the next pointer 'sg_ptr->sg_ptr'.
+         */
+        sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]);
+        asc_prt_adv_sgblock(i, sg_ptr);
+    }
+}
+
+/*
+ * asc_prt_adv_sgblock()
+ *
+ * Display an ADV_SG_BLOCK structure.
+ */
+STATIC void
+asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
+{
+    int i, s;
+
+    /* Calculate starting entry number for the current block. */
+    s = sgblockno * NO_OF_SG_PER_BLOCK;
+
+    printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n",
+        (ulong) b, (ulong) sgblockno);
+    printk(
+"  first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n",
+        (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr);
+    ASC_ASSERT(b->first_entry_no - s >= 0);
+    ASC_ASSERT(b->last_entry_no - s >= 0);
+    ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK);
+    ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
+    ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
+    ASC_ASSERT(b->first_entry_no - s <= b->last_entry_no - s);
+    for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) {
+        printk("  [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n",
+            (ulong) i, (ulong) b->sg_list[i].sg_addr,
+            (ulong) b->sg_list[i].sg_count);
+    }
+}
+
+/*
+ * asc_prt_hex()
+ *
+ * Print hexadecimal output in 4 byte groupings 32 bytes 
+ * or 8 double-words per line.
+ */
+STATIC void 
+asc_prt_hex(char *f, uchar *s, int l)
+{
+    int            i;
+    int            j;
+    int            k;
+    int            m;
+
+    printk("%s: (%d bytes)\n", f, l);
+
+    for (i = 0; i < l; i += 32) {
+        
+        /* Display a maximum of 8 double-words per line. */
+        if ((k = (l - i) / 4) >= 8) {
+            k = 8;
+            m = 0;
+        } else {
+            m = (l - i) % 4 ;
+        }
+
+        for (j = 0; j < k; j++) {
+            printk(" %2.2X%2.2X%2.2X%2.2X",
                 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
                 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
         }
@@ -6975,6 +10059,7 @@
 )
 {
     PortAddr            eisa_cfg_iop;
+
     eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
       (PortAddr) (ASC_EISA_CFG_IOP_MASK);
     return (inpw(eisa_cfg_iop));
@@ -6989,6 +10074,7 @@
 )
 {
     ushort              cfg_lsw;
+
     if (AscGetChipScsiID(iop_base) == new_host_id) {
         return (new_host_id);
     }
@@ -7007,6 +10093,7 @@
 )
 {
     uchar               sc;
+
     AscSetBank(iop_base, 1);
     sc = inp(iop_base + IOP_REG_SC);
     AscSetBank(iop_base, 0);
@@ -7040,6 +10127,7 @@
 )
 {
     ushort              chip_ver;
+
     chip_ver = AscGetChipVerNo(iop_base);
     if (
            (chip_ver >= ASC_CHIP_MIN_VER_VL)
@@ -7079,6 +10167,7 @@
     ulong               chksum;
     ushort              mcode_word_size;
     ushort              mcode_chksum;
+
     mcode_word_size = (ushort) (mcode_size >> 1);
     AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
     AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
@@ -7099,6 +10188,7 @@
 )
 {
     ushort              sig_word;
+
     if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
         sig_word = AscGetChipSignatureWord(iop_base);
         if ((sig_word == (ushort) ASC_1000_ID0W) ||
@@ -7162,6 +10252,7 @@
 {
     int                 i;
     PortAddr            iop_base;
+
     for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
         if (_asc_def_iop_base[i] > s_addr) {
             break;
@@ -7216,6 +10307,7 @@
 {
     ushort              cfg_lsw;
     uchar               chip_irq;
+
     if ((bus_type & ASC_IS_EISA) != 0) {
         cfg_lsw = AscGetEisaChipCfg(iop_base);
         chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
@@ -7232,11 +10324,6 @@
             (chip_irq == 7)) {
             return (0);
         }
-#if CC_PLEXTOR_VL
-        if (chip_irq == 5) {
-            return (9);
-        }
-#endif
         return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
     }
     cfg_lsw = AscGetChipCfgLsw(iop_base);
@@ -7256,13 +10343,9 @@
 )
 {
     ushort              cfg_lsw;
+
     if ((bus_type & ASC_IS_VL) != 0) {
         if (irq_no != 0) {
-#if CC_PLEXTOR_VL
-            if (irq_no == 9) {
-                irq_no = 14;
-            }
-#endif
             if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
                 irq_no = 0;
             } else {
@@ -7473,7 +10556,6 @@
 
         q_cntl |= QC_REQ_SENSE;
 
-#if CC_CHK_COND_REDO_SDTR
         if ((asc_dvc->init_sdtr & target_id) != 0) {
 
             asc_dvc->sdtr_done &= ~target_id;
@@ -7485,7 +10567,6 @@
                            (uchar) (asc_dvc->max_sdtr_index - 1)],
                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
         }
-#endif
 
         AscWriteLramByte(iop_base,
                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
@@ -7577,7 +10658,8 @@
                     boardp->queue_full |= target_id;
                     boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
 #if ASC_QUEUE_FLOW_CONTROL
-                    if (boardp->device[tid_no]->queue_curr_depth >
+                    if (boardp->device[tid_no] != NULL &&
+                        boardp->device[tid_no]->queue_curr_depth >
                         cur_dvc_qng) {
                         boardp->device[tid_no]->queue_curr_depth =
                             cur_dvc_qng;
@@ -7602,13 +10684,11 @@
 {
     ushort              _val;
     uchar               sg_queue_cnt;
+
     DvcGetQinfo(iop_base,
                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
                 (ushort *) scsiq,
               (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
-#if !CC_LITTLE_ENDIAN_HOST
-    AscAdjEndianQDoneInfo(scsiq);
-#endif
     _val = AscReadLramWord(iop_base,
                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
     scsiq->q_status = (uchar) _val;
@@ -7649,6 +10729,7 @@
     REG ASC_QDONE_INFO *scsiq;
     int                 false_overrun;
     ASC_ISR_CALLBACK    asc_isr_callback;
+
     iop_base = asc_dvc->iop_base;
     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
     n_q_used = 1;
@@ -7731,18 +10812,13 @@
                     AscStopChip(iop_base);
                     AscSetChipControl(iop_base,
                         (uchar) (CC_SCSI_RESET | CC_HALT));
-                    DvcDelayNanoSecond(asc_dvc, 30000);
+                    DvcDelayNanoSecond(asc_dvc, 60000);
                     AscSetChipControl(iop_base, CC_HALT);
                     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
                     AscSetChipStatus(iop_base, 0);
                     AscSetChipControl(iop_base, 0);
                 }
             }
-#if CC_CLEAR_LRAM_SRB_PTR
-            AscWriteLramDWord(iop_base,
-                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
-                              asc_dvc->int_count);
-#endif
             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
                 (*asc_isr_callback) (asc_dvc, scsiq);
             } else {
@@ -7781,6 +10857,7 @@
     int                 int_pending;
     int                 status;
     uchar               host_flag;
+
     iop_base = asc_dvc->iop_base;
     int_pending = FALSE;
     if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
@@ -7819,12 +10896,10 @@
         ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
                      (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
-#if CC_ASCISR_CHECK_INT_PENDING
     if ((chipstat & CSW_INT_PENDING)
         || (int_pending)
 ) {
         AscAckInterrupt(iop_base);
-#endif
         int_pending = TRUE;
         if ((chipstat & CSW_HALTED) &&
             (ctrl_reg & CC_SINGLE_STEP)) {
@@ -7848,9 +10923,7 @@
             if ((status & 0x80) != 0)
                 int_pending = ERR;
         }
-#if CC_ASCISR_CHECK_INT_PENDING
     }
-#endif
     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
     AscSetChipLramAddr(iop_base, saved_ram_addr);
     AscSetChipControl(iop_base, saved_ctrl_reg);
@@ -7867,6 +10940,7 @@
 )
 {
     ulong               phy_addr;
+
     scsiq->r1.cntl = 0;
     scsiq->r1.sg_queue_cnt = 0;
     scsiq->r1.q_no = 0;
@@ -7901,155 +10975,156 @@
     return (0);
 }
 
-STATIC uchar _mcode_buf[] ASC_INITDATA =
+STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
 {
-    0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x79, 0x0D, 0x09, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x23, 0x00, 0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
-    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x88, 0x00, 0x00, 0x00, 0x00,
-    0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
-    0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
-    0x08, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x32, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
-    0x4F, 0x00, 0xF5, 0x00, 0x32, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
-    0x92, 0x80, 0x00, 0x46, 0x17, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
-    0x00, 0xA3, 0xD6, 0x00, 0x90, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xD8, 0x84, 0xD2, 0xC1,
-    0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xE2, 0x01, 0x90, 0x97, 0xCE, 0x81, 0x00, 0x33,
-    0x02, 0x00, 0xAA, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0x02, 0x01, 0x4F, 0x00,
-    0x6E, 0x97, 0x07, 0xA6, 0x0C, 0x01, 0x00, 0x33, 0x03, 0x00, 0xAA, 0x88, 0x03, 0x03, 0x03, 0xDE,
-    0x00, 0x33, 0x05, 0x00, 0xAA, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60,
-    0x00, 0xA2, 0x80, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x2C, 0x01, 0x80, 0x81, 0x03, 0x03, 0x80, 0x63,
-    0xE2, 0x00, 0x07, 0xA6, 0x3C, 0x01, 0x00, 0x33, 0x04, 0x00, 0xAA, 0x88, 0x03, 0x07, 0x02, 0x01,
-    0x04, 0xCA, 0x0D, 0x23, 0x52, 0x98, 0x4D, 0x04, 0xF6, 0x84, 0x05, 0xD8, 0x0D, 0x23, 0x52, 0x98,
-    0xCD, 0x04, 0x15, 0x23, 0xE0, 0x88, 0xFB, 0x23, 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03,
-    0x06, 0xA3, 0x6A, 0x01, 0x00, 0x33, 0x0A, 0x00, 0xAA, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x76, 0x01,
-    0x00, 0x33, 0x0B, 0x00, 0xAA, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xAA, 0x88,
-    0x50, 0x04, 0x90, 0x81, 0x06, 0xAB, 0x8A, 0x01, 0x90, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x9A, 0x01,
-    0x50, 0x00, 0x00, 0xA3, 0x44, 0x01, 0x00, 0x05, 0x84, 0x81, 0x30, 0x97, 0x02, 0x01, 0x05, 0xC6,
-    0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xC6, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01,
-    0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xBC, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D,
-    0x00, 0x33, 0x1B, 0x00, 0xAA, 0x88, 0x06, 0x23, 0x52, 0x98, 0xCD, 0x04, 0xD8, 0x84, 0x06, 0x01,
-    0x00, 0xA2, 0xDC, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xE2, 0x01, 0xD8, 0x84, 0x80, 0x23, 0xA0, 0x01,
-    0xD8, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x08, 0x02, 0x04, 0x01, 0x0C, 0xDE,
-    0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x6E, 0x97, 0x04, 0x82, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
-    0x4F, 0x00, 0x4C, 0x97, 0x48, 0x04, 0x84, 0x80, 0xDA, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0,
-    0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x67, 0xEB,
-    0x11, 0x23, 0xE0, 0x88, 0xEE, 0x97, 0xF4, 0x80, 0x80, 0x73, 0x80, 0x77, 0x06, 0xA6, 0x36, 0x02,
-    0x00, 0x33, 0x31, 0x00, 0xAA, 0x88, 0x04, 0x01, 0x03, 0xD8, 0x9C, 0x98, 0x44, 0x96, 0x48, 0x82,
-    0xD4, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x72, 0x02, 0x07, 0xA6,
-    0x60, 0x02, 0x06, 0xA6, 0x64, 0x02, 0x03, 0xA6, 0x68, 0x02, 0x00, 0x33, 0x10, 0x00, 0xAA, 0x88,
-    0x6E, 0x95, 0x4A, 0x82, 0x3A, 0x96, 0x4A, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01,
-    0x2E, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04,
-    0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B,
-    0x1C, 0x01, 0x02, 0xA6, 0xB0, 0x02, 0x07, 0xA6, 0x60, 0x02, 0x06, 0xA6, 0x64, 0x02, 0x03, 0xA6,
-    0x12, 0x04, 0x01, 0xA6, 0xBA, 0x02, 0x00, 0xA6, 0xBA, 0x02, 0x00, 0x33, 0x12, 0x00, 0xAA, 0x88,
-    0x00, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x92, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC,
-    0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38,
-    0x00, 0x3F, 0x00, 0x00, 0xF0, 0x82, 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE8, 0x02, 0x04, 0x01,
-    0x98, 0xC8, 0x00, 0x33, 0x1F, 0x00, 0xAA, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D,
-    0x68, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x1A, 0x03, 0x00, 0xA6, 0x1A, 0x03, 0x07, 0xA6, 0x12, 0x03,
-    0x06, 0xA6, 0x16, 0x03, 0x03, 0xA6, 0x12, 0x04, 0x02, 0xA6, 0x72, 0x02, 0x00, 0x33, 0x33, 0x00,
-    0xAA, 0x88, 0x6E, 0x95, 0xF4, 0x82, 0x3A, 0x96, 0xF4, 0x82, 0x6C, 0x98, 0x80, 0x42, 0x68, 0x98,
-    0x60, 0xE4, 0x04, 0x01, 0x29, 0xC8, 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x5A, 0x03, 0x00, 0x43,
-    0x87, 0x01, 0x05, 0x05, 0x70, 0x98, 0x68, 0x98, 0x00, 0xA6, 0x1C, 0x03, 0x07, 0xA6, 0x52, 0x03,
-    0x03, 0xA6, 0x2E, 0x04, 0x06, 0xA6, 0x56, 0x03, 0x01, 0xA6, 0x1C, 0x03, 0x00, 0x33, 0x25, 0x00,
-    0xAA, 0x88, 0x6E, 0x95, 0x38, 0x83, 0x3A, 0x96, 0x38, 0x83, 0x04, 0x01, 0x0C, 0xCE, 0x03, 0xC8,
-    0x00, 0x33, 0x42, 0x00, 0xAA, 0x88, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x78, 0x03, 0xB1, 0x01,
-    0x08, 0x23, 0xB2, 0x01, 0x34, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x98, 0x03, 0xEC, 0x00,
-    0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x94, 0x03, 0x00, 0xA6,
-    0x94, 0x03, 0x08, 0x84, 0x80, 0x42, 0x68, 0x98, 0x01, 0xA6, 0xA2, 0x03, 0x00, 0xA6, 0xBA, 0x03,
-    0x08, 0x84, 0x90, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA2, 0x03, 0x07, 0xA6, 0xB0, 0x03, 0xD2, 0x83,
-    0x6E, 0x95, 0xA6, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xAA, 0x88, 0x90, 0x98, 0x80, 0x42, 0x00, 0xA6,
-    0xBA, 0x03, 0x07, 0xA6, 0xC8, 0x03, 0xD2, 0x83, 0x6E, 0x95, 0xBE, 0x83, 0x00, 0x33, 0x26, 0x00,
-    0xAA, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01,
-    0x08, 0x84, 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33, 0x20, 0x00, 0xAA, 0x88, 0x03, 0xA6, 0x06, 0x04,
-    0x07, 0xA6, 0xFE, 0x03, 0x06, 0xA6, 0x02, 0x04, 0x00, 0x33, 0x17, 0x00, 0xAA, 0x88, 0x6E, 0x95,
-    0xEC, 0x83, 0x3A, 0x96, 0xEC, 0x83, 0x12, 0x84, 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33, 0x20, 0x00,
-    0xAA, 0x88, 0xB6, 0x2D, 0x03, 0xA6, 0x2E, 0x04, 0x07, 0xA6, 0x26, 0x04, 0x06, 0xA6, 0x2A, 0x04,
-    0x00, 0x33, 0x30, 0x00, 0xAA, 0x88, 0x6E, 0x95, 0x12, 0x84, 0x3A, 0x96, 0x12, 0x84, 0x1D, 0x01,
-    0x06, 0xCC, 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D,
-    0x80, 0x63, 0x07, 0xA6, 0x4C, 0x04, 0x00, 0x33, 0x18, 0x00, 0xAA, 0x88, 0x03, 0x03, 0x80, 0x63,
-    0xA3, 0x01, 0x07, 0xA4, 0x56, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x78, 0x04, 0x0A, 0xA0, 0x68, 0x04,
-    0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, 0xAA, 0x88, 0x0B, 0xA0, 0x74, 0x04, 0xE0, 0x00, 0x00, 0x33,
-    0x1E, 0x00, 0xAA, 0x88, 0x42, 0x23, 0xE0, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xD8, 0x04, 0x08, 0x23,
-    0x22, 0xA3, 0x94, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xA0, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xB6, 0x04,
-    0x42, 0x23, 0xE0, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xA0, 0x04, 0x45, 0x23, 0xE0, 0x88,
-    0xEE, 0x97, 0x00, 0xA2, 0xB2, 0x04, 0x9C, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62,
-    0xF0, 0x81, 0x47, 0x23, 0xE0, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0xEE, 0x97, 0x9C, 0x98, 0x00, 0x33,
-    0x00, 0x81, 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x08, 0x02, 0x43, 0x23, 0xE0, 0x88,
-    0x04, 0x23, 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xE6, 0x04,
-    0x00, 0x33, 0x27, 0x00, 0xAA, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23,
-    0xA0, 0x01, 0xEE, 0x97, 0x18, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3,
-    0x14, 0x05, 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x0E, 0x05, 0xFC, 0x84, 0x30, 0x97,
-    0xCD, 0x04, 0x16, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01,
-    0x26, 0x85, 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x32, 0x05, 0x1D, 0x01,
-    0x04, 0xD6, 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00,
-    0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04,
-    0x80, 0x01, 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x52, 0x05, 0x77, 0x04, 0x01, 0x23,
-    0xEA, 0x00, 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4,
-    0xD2, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x80, 0x05, 0xCE, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xAA, 0x88,
-    0x04, 0xA0, 0xA6, 0x05, 0x80, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x92, 0x05, 0x1D, 0x01,
-    0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x4C, 0x97, 0xF6, 0x84, 0x04, 0x23,
-    0x02, 0x41, 0x82, 0x01, 0xF6, 0x84, 0x08, 0xA0, 0xAC, 0x05, 0xCE, 0x85, 0x03, 0xA0, 0xB2, 0x05,
-    0xCE, 0x85, 0x01, 0xA0, 0xBC, 0x05, 0x88, 0x00, 0x80, 0x63, 0xAA, 0x86, 0x07, 0xA0, 0xC8, 0x05,
-    0x06, 0x23, 0x52, 0x98, 0x48, 0x23, 0xE0, 0x88, 0x07, 0x23, 0x80, 0x00, 0xF0, 0x86, 0x80, 0x63,
-    0x6E, 0x85, 0x00, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x10, 0x06, 0x1D, 0x01, 0x18, 0xD4,
-    0xC0, 0x23, 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0xF2, 0x05, 0x00, 0x33, 0x37, 0x00,
-    0xAA, 0x88, 0x1D, 0x01, 0x02, 0xD6, 0x46, 0x23, 0xE0, 0x88, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63,
-    0x06, 0xA6, 0x0A, 0x06, 0x00, 0x33, 0x38, 0x00, 0xAA, 0x88, 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63,
-    0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x28, 0x06, 0x1D, 0x01,
-    0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83,
-    0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, 0x80, 0x67, 0x08, 0x23, 0x83, 0x03,
-    0x80, 0x63, 0x00, 0x63, 0x06, 0xA6, 0x56, 0x06, 0x07, 0xA6, 0x6E, 0x05, 0x02, 0xA6, 0xE4, 0x06,
-    0x00, 0x33, 0x39, 0x00, 0xAA, 0x88, 0x00, 0x00, 0x01, 0xA0, 0xFE, 0x06, 0xD4, 0x95, 0x83, 0x03,
-    0x80, 0x63, 0x06, 0xA6, 0x6A, 0x06, 0x07, 0xA6, 0x6E, 0x05, 0x00, 0x00, 0x01, 0xA0, 0xFE, 0x06,
-    0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0x86, 0x06, 0x07, 0xA6, 0x6E, 0x05,
-    0x00, 0x33, 0x3A, 0x00, 0xAA, 0x88, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x78, 0x06,
-    0x06, 0xA6, 0x9E, 0x06, 0x07, 0xA6, 0x6E, 0x05, 0x00, 0x33, 0x3B, 0x00, 0xAA, 0x88, 0x80, 0x67,
-    0x40, 0x0E, 0x80, 0x63, 0x07, 0xA6, 0x6E, 0x05, 0x00, 0x63, 0x07, 0xA6, 0xB4, 0x06, 0x00, 0x33,
-    0x2A, 0x00, 0xAA, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xC6, 0x06,
-    0x00, 0x33, 0x29, 0x00, 0xAA, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xD2, 0x06, 0xC0, 0x0E, 0x80, 0x63,
-    0xBC, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01, 0x08, 0xDA,
-    0x80, 0x63, 0x6E, 0x85, 0x80, 0x67, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
-    0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x62, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xAA, 0x88, 0x0C, 0xA2,
-    0x18, 0x07, 0xD4, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x16, 0x07, 0x07, 0xA6, 0x6E, 0x05,
-    0x00, 0x33, 0x3D, 0x00, 0xAA, 0x88, 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0,
-    0x2E, 0x07, 0x07, 0xA6, 0x6E, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xD8, 0x84, 0x00, 0x63,
-    0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00, 0x01, 0x05, 0x80, 0x01, 0x72, 0x04,
-    0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00,
-    0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00, 0x81, 0x01,
-    0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04,
-    0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00,
-    0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x00, 0x63,
-    0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01, 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01,
-    0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xAE, 0x07, 0x00, 0x33, 0x07, 0x00, 0xAA, 0x88, 0x80, 0x05,
-    0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01,
-    0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xCE, 0x07, 0x00, 0x05, 0xC4, 0x87, 0x00, 0x01,
-    0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08,
-    0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04,
-    0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0, 0xFE, 0x07, 0x00, 0x88, 0x00, 0x43,
-    0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00,
-    0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x2E, 0x08, 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9,
-    0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x0E, 0x08, 0xEE, 0x97, 0x18, 0x95, 0x0E, 0x88, 0x73, 0x04,
-    0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x44, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x30, 0x97, 0xEE, 0x97,
-    0x18, 0x95, 0x34, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x4E, 0x08, 0x00, 0x05, 0x38, 0x88, 0x73, 0x04,
-    0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x60, 0x08, 0x00, 0x33, 0x3E, 0x00, 0xAA, 0x88,
-    0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B, 0x86, 0x88, 0x38, 0x2B, 0x7C, 0x88,
-    0x32, 0x09, 0x31, 0x05, 0x7C, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, 0x00, 0x36,
-    0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36, 0x80, 0x3A, 0x80, 0x3E, 0x00, 0x63,
-    0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
-    0x00, 0xA0, 0x9C, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23,
-    0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, 0x13, 0x23, 0xE0, 0x88, 0x66, 0x20, 0xC0, 0x20,
-    0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xCA, 0x88, 0x80, 0x73, 0x80, 0x77,
-    0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23, 0xE0, 0x88, 0x11, 0x23,
-    0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xD8, 0x84,
+  0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0xDB,  0x0C,  0x0A,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x23,  0x00,  0x23,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
+  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xD4,  0x88,  0x00,  0x00,  0x00,  0x00,
+  0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
+  0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
+  0x10,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x3A,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
+  0x4F,  0x00,  0xF5,  0x00,  0x3A,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
+  0x92,  0x80,  0x00,  0x46,  0x17,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
+  0x00,  0xA3,  0xD6,  0x00,  0x98,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE0,  0x84,  0xD2,  0xC1,
+  0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xE2,  0x01,  0x98,  0x97,  0xCE,  0x81,  0x00,  0x33,
+  0x02,  0x00,  0xB2,  0x88,  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0x02,  0x01,  0x4F,  0x00,
+  0x76,  0x97,  0x07,  0xA6,  0x0C,  0x01,  0x00,  0x33,  0x03,  0x00,  0xB2,  0x88,  0x03,  0x03,  0x03,  0xDE,
+  0x00,  0x33,  0x05,  0x00,  0xB2,  0x88,  0xCE,  0x00,  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,
+  0x00,  0xA2,  0x80,  0x01,  0x80,  0x63,  0x07,  0xA6,  0x2C,  0x01,  0x80,  0x81,  0x03,  0x03,  0x80,  0x63,
+  0xE2,  0x00,  0x07,  0xA6,  0x3C,  0x01,  0x00,  0x33,  0x04,  0x00,  0xB2,  0x88,  0x03,  0x07,  0x02,  0x01,
+  0x04,  0xCA,  0x0D,  0x23,  0x5A,  0x98,  0x4D,  0x04,  0xFE,  0x84,  0x05,  0xD8,  0x0D,  0x23,  0x5A,  0x98,
+  0xCD,  0x04,  0x15,  0x23,  0xE8,  0x88,  0xFB,  0x23,  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,
+  0x06,  0xA3,  0x6A,  0x01,  0x00,  0x33,  0x0A,  0x00,  0xB2,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x76,  0x01,
+  0x00,  0x33,  0x0B,  0x00,  0xB2,  0x88,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xB2,  0x88,
+  0x50,  0x04,  0x90,  0x81,  0x06,  0xAB,  0x8A,  0x01,  0x90,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x9A,  0x01,
+  0x50,  0x00,  0x00,  0xA3,  0x44,  0x01,  0x00,  0x05,  0x84,  0x81,  0x38,  0x97,  0x02,  0x01,  0x05,  0xC6,
+  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,  0xC6,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,
+  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xBC,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,
+  0x00,  0x33,  0x1B,  0x00,  0xB2,  0x88,  0x06,  0x23,  0x5A,  0x98,  0xCD,  0x04,  0xE0,  0x84,  0x06,  0x01,
+  0x00,  0xA2,  0xDC,  0x01,  0x57,  0x60,  0x00,  0xA0,  0xE2,  0x01,  0xE0,  0x84,  0x80,  0x23,  0xA0,  0x01,
+  0xE0,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x08,  0x02,  0x04,  0x01,  0x0C,  0xDE,
+  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x76,  0x97,  0x04,  0x82,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,
+  0x4F,  0x00,  0x54,  0x97,  0x48,  0x04,  0x84,  0x80,  0xE2,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,
+  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x67,  0xEB,
+  0x11,  0x23,  0xE8,  0x88,  0xF6,  0x97,  0xF4,  0x80,  0x80,  0x73,  0x80,  0x77,  0x06,  0xA6,  0x36,  0x02,
+  0x00,  0x33,  0x31,  0x00,  0xB2,  0x88,  0x04,  0x01,  0x03,  0xD8,  0xA4,  0x98,  0x4C,  0x96,  0x48,  0x82,
+  0xDC,  0x95,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,  0x02,  0xA6,  0x72,  0x02,  0x07,  0xA6,
+  0x60,  0x02,  0x06,  0xA6,  0x64,  0x02,  0x03,  0xA6,  0x68,  0x02,  0x00,  0x33,  0x10,  0x00,  0xB2,  0x88,
+  0x76,  0x95,  0x4A,  0x82,  0x42,  0x96,  0x4A,  0x82,  0x04,  0x23,  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,
+  0x36,  0x84,  0x04,  0x01,  0x0C,  0xDC,  0xE0,  0x23,  0x25,  0x61,  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,
+  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,  0x03,  0x23,  0xA4,  0x01,  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,
+  0x1C,  0x01,  0x02,  0xA6,  0xB0,  0x02,  0x07,  0xA6,  0x60,  0x02,  0x06,  0xA6,  0x64,  0x02,  0x03,  0xA6,
+  0x1A,  0x04,  0x01,  0xA6,  0xBA,  0x02,  0x00,  0xA6,  0xBA,  0x02,  0x00,  0x33,  0x12,  0x00,  0xB2,  0x88,
+  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,  0x00,  0xA0,  0x92,  0x02,  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,
+  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,  0x10,  0x31,  0x12,  0x35,  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,
+  0x00,  0x3F,  0x00,  0x00,  0xF0,  0x82,  0x18,  0x23,  0x04,  0x61,  0x18,  0xA0,  0xE8,  0x02,  0x04,  0x01,
+  0x9C,  0xC8,  0x00,  0x33,  0x1F,  0x00,  0xB2,  0x88,  0x08,  0x31,  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,
+  0x70,  0x98,  0xB6,  0x2D,  0x01,  0xA6,  0x1A,  0x03,  0x00,  0xA6,  0x1A,  0x03,  0x07,  0xA6,  0x12,  0x03,
+  0x06,  0xA6,  0x16,  0x03,  0x03,  0xA6,  0x1A,  0x04,  0x02,  0xA6,  0x72,  0x02,  0x00,  0x33,  0x33,  0x00,
+  0xB2,  0x88,  0x76,  0x95,  0xF4,  0x82,  0x42,  0x96,  0xF4,  0x82,  0x74,  0x98,  0x80,  0x42,  0x70,  0x98,
+  0x60,  0xE4,  0x04,  0x01,  0x29,  0xC8,  0x31,  0x05,  0x07,  0x01,  0x00,  0xA2,  0x5A,  0x03,  0x00,  0x43,
+  0x87,  0x01,  0x05,  0x05,  0x78,  0x98,  0x70,  0x98,  0x00,  0xA6,  0x1C,  0x03,  0x07,  0xA6,  0x52,  0x03,
+  0x03,  0xA6,  0x36,  0x04,  0x06,  0xA6,  0x56,  0x03,  0x01,  0xA6,  0x1C,  0x03,  0x00,  0x33,  0x25,  0x00,
+  0xB2,  0x88,  0x76,  0x95,  0x38,  0x83,  0x42,  0x96,  0x38,  0x83,  0x04,  0x01,  0x0C,  0xCE,  0x03,  0xC8,
+  0x00,  0x33,  0x42,  0x00,  0xB2,  0x88,  0x00,  0x01,  0x05,  0x05,  0xFF,  0xA2,  0x78,  0x03,  0xB1,  0x01,
+  0x08,  0x23,  0xB2,  0x01,  0x34,  0x83,  0x05,  0x05,  0x15,  0x01,  0x00,  0xA2,  0x98,  0x03,  0xEC,  0x00,
+  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0x01,  0xA6,  0x94,  0x03,  0x00,  0xA6,
+  0x94,  0x03,  0x0C,  0x84,  0x80,  0x42,  0x70,  0x98,  0x01,  0xA6,  0xA2,  0x03,  0x00,  0xA6,  0xBA,  0x03,
+  0x0C,  0x84,  0x98,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA2,  0x03,  0x07,  0xA6,  0xB0,  0x03,  0xD2,  0x83,
+  0x76,  0x95,  0xA6,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xB2,  0x88,  0x98,  0x98,  0x80,  0x42,  0x00,  0xA6,
+  0xBA,  0x03,  0x07,  0xA6,  0xC8,  0x03,  0xD2,  0x83,  0x76,  0x95,  0xBE,  0x83,  0x00,  0x33,  0x26,  0x00,
+  0xB2,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,  0xA0,  0x01,  0x12,  0x23,  0xA1,  0x01,
+  0x0C,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0xF0,  0x03,  0x80,  0x6B,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
+  0x03,  0xA6,  0x0A,  0x04,  0x07,  0xA6,  0x02,  0x04,  0x06,  0xA6,  0x06,  0x04,  0x00,  0x33,  0x17,  0x00,
+  0xB2,  0x88,  0x76,  0x95,  0xF0,  0x83,  0x42,  0x96,  0xF0,  0x83,  0x1A,  0x84,  0x06,  0xF0,  0x06,  0xA4,
+  0x1A,  0x04,  0x80,  0x6B,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,  0x03,  0xA6,  0x36,  0x04,
+  0x07,  0xA6,  0x2E,  0x04,  0x06,  0xA6,  0x32,  0x04,  0x00,  0x33,  0x30,  0x00,  0xB2,  0x88,  0x76,  0x95,
+  0x1A,  0x84,  0x42,  0x96,  0x1A,  0x84,  0x1D,  0x01,  0x06,  0xCC,  0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,
+  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,  0x07,  0xA6,  0x54,  0x04,  0x00,  0x33,
+  0x18,  0x00,  0xB2,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,  0x07,  0xA4,  0x5E,  0x04,  0x23,  0x01,
+  0x00,  0xA2,  0x80,  0x04,  0x0A,  0xA0,  0x70,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1D,  0x00,  0xB2,  0x88,
+  0x0B,  0xA0,  0x7C,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,  0xB2,  0x88,  0x42,  0x23,  0xE8,  0x88,
+  0x00,  0x23,  0x22,  0xA3,  0xE0,  0x04,  0x08,  0x23,  0x22,  0xA3,  0x9C,  0x04,  0x28,  0x23,  0x22,  0xA3,
+  0xA8,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xBE,  0x04,  0x42,  0x23,  0xE8,  0x88,  0x4A,  0x00,  0x06,  0x61,
+  0x00,  0xA0,  0xA8,  0x04,  0x45,  0x23,  0xE8,  0x88,  0xF6,  0x97,  0x00,  0xA2,  0xBA,  0x04,  0xA4,  0x98,
+  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xF0,  0x81,  0x47,  0x23,  0xE8,  0x88,  0x04,  0x01,
+  0x0B,  0xDE,  0xF6,  0x97,  0xA4,  0x98,  0x00,  0x33,  0x00,  0x81,  0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,
+  0x00,  0xA0,  0x08,  0x02,  0x43,  0x23,  0xE8,  0x88,  0x04,  0x23,  0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,
+  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xEE,  0x04,  0x00,  0x33,  0x27,  0x00,  0xB2,  0x88,  0x04,  0x01,
+  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xF6,  0x97,  0x20,  0x95,  0x4B,  0x00,
+  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x1C,  0x05,  0x00,  0x05,  0x76,  0x00,  0x06,  0x61,
+  0x00,  0xA2,  0x16,  0x05,  0x04,  0x85,  0x38,  0x97,  0xCD,  0x04,  0x1E,  0x85,  0x48,  0x04,  0x84,  0x80,
+  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x2E,  0x85,  0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,
+  0x06,  0x61,  0x00,  0xA2,  0x3A,  0x05,  0x1D,  0x01,  0x04,  0xD6,  0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,
+  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,  0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,
+  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,  0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,
+  0xFF,  0xA0,  0x5A,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,  0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,
+  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xDA,  0x05,  0x03,  0x03,  0x02,  0xA0,  0x88,  0x05,
+  0xD6,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xB2,  0x88,  0x04,  0xA0,  0xAE,  0x05,  0x80,  0x63,  0x4A,  0x00,
+  0x06,  0x61,  0x00,  0xA2,  0x9A,  0x05,  0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,
+  0x50,  0x00,  0x54,  0x97,  0xFE,  0x84,  0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0xFE,  0x84,  0x08,  0xA0,
+  0xB4,  0x05,  0xD6,  0x85,  0x03,  0xA0,  0xBA,  0x05,  0xD6,  0x85,  0x01,  0xA0,  0xC4,  0x05,  0x88,  0x00,
+  0x80,  0x63,  0xB2,  0x86,  0x07,  0xA0,  0xD0,  0x05,  0x06,  0x23,  0x5A,  0x98,  0x48,  0x23,  0xE8,  0x88,
+  0x07,  0x23,  0x80,  0x00,  0xF8,  0x86,  0x80,  0x63,  0x76,  0x85,  0x00,  0x63,  0x4A,  0x00,  0x06,  0x61,
+  0x00,  0xA2,  0x18,  0x06,  0x1D,  0x01,  0x18,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,  0x80,  0x63,
+  0x06,  0xA6,  0xFA,  0x05,  0x00,  0x33,  0x37,  0x00,  0xB2,  0x88,  0x1D,  0x01,  0x02,  0xD6,  0x46,  0x23,
+  0xE8,  0x88,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x12,  0x06,  0x00,  0x33,  0x38,  0x00,
+  0xB2,  0x88,  0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,
+  0x06,  0x61,  0x00,  0xA2,  0x30,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,
+  0x1D,  0x01,  0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,
+  0x00,  0x63,  0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x06,  0xA6,  0x5E,  0x06,
+  0x07,  0xA6,  0x76,  0x05,  0x02,  0xA6,  0xEC,  0x06,  0x00,  0x33,  0x39,  0x00,  0xB2,  0x88,  0x00,  0x00,
+  0x01,  0xA0,  0x06,  0x07,  0xDC,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x72,  0x06,  0x07,  0xA6,
+  0x76,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x06,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,  0x01,  0x00,
+  0x06,  0xA6,  0x8E,  0x06,  0x07,  0xA6,  0x76,  0x05,  0x00,  0x33,  0x3A,  0x00,  0xB2,  0x88,  0x40,  0x0E,
+  0x80,  0x63,  0x00,  0x43,  0x00,  0xA0,  0x80,  0x06,  0x06,  0xA6,  0xA6,  0x06,  0x07,  0xA6,  0x76,  0x05,
+  0x00,  0x33,  0x3B,  0x00,  0xB2,  0x88,  0x80,  0x67,  0x40,  0x0E,  0x80,  0x63,  0x07,  0xA6,  0x76,  0x05,
+  0x00,  0x63,  0x07,  0xA6,  0xBC,  0x06,  0x00,  0x33,  0x2A,  0x00,  0xB2,  0x88,  0x03,  0x03,  0x80,  0x63,
+  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,  0xCE,  0x06,  0x00,  0x33,  0x29,  0x00,  0xB2,  0x88,  0x00,  0x43,
+  0x00,  0xA2,  0xDA,  0x06,  0xC0,  0x0E,  0x80,  0x63,  0xC4,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,
+  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,  0x08,  0xDA,  0x80,  0x63,  0x76,  0x85,  0x80,  0x67,  0x00,  0x33,
+  0x00,  0x40,  0xC0,  0x20,  0x81,  0x62,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x6A,  0x06,
+  0x00,  0x33,  0x2C,  0x00,  0xB2,  0x88,  0x0C,  0xA2,  0x20,  0x07,  0xDC,  0x95,  0x83,  0x03,  0x80,  0x63,
+  0x06,  0xA6,  0x1E,  0x07,  0x07,  0xA6,  0x76,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xB2,  0x88,  0x00,  0x00,
+  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x36,  0x07,  0x07,  0xA6,  0x76,  0x05,  0xBF,  0x23,
+  0x04,  0x61,  0x84,  0x01,  0xE0,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,
+  0xF2,  0x00,  0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,
+  0x81,  0x05,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,
+  0x81,  0x01,  0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,
+  0x80,  0x01,  0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,
+  0x70,  0x00,  0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,
+  0x70,  0x00,  0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,
+  0xA2,  0x01,  0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xB6,  0x07,
+  0x00,  0x33,  0x07,  0x00,  0xB2,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,
+  0xB0,  0x01,  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,
+  0xD6,  0x07,  0x00,  0x05,  0xCC,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,
+  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,
+  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,
+  0x00,  0xA0,  0x06,  0x08,  0x08,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,
+  0xF3,  0x04,  0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,
+  0x36,  0x08,  0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x16,  0x08,
+  0xF6,  0x97,  0x20,  0x95,  0x16,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x4C,  0x88,
+  0x02,  0x01,  0x04,  0xD8,  0x38,  0x97,  0xF6,  0x97,  0x20,  0x95,  0x3C,  0x88,  0x75,  0x00,  0x00,  0xA3,
+  0x56,  0x08,  0x00,  0x05,  0x40,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,
+  0x68,  0x08,  0x00,  0x33,  0x3E,  0x00,  0xB2,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,
+  0x38,  0x2B,  0x8E,  0x88,  0x38,  0x2B,  0x84,  0x88,  0x32,  0x09,  0x31,  0x05,  0x84,  0x98,  0x05,  0x05,
+  0xB2,  0x09,  0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,
+  0x80,  0x36,  0x80,  0x3A,  0x80,  0x3E,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,
+  0x40,  0x3E,  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xA4,  0x08,  0x5D,  0x00,  0xFE,  0xC3,
+  0x00,  0x63,  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,
+  0x13,  0x23,  0xE8,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,
+  0x81,  0x62,  0xD2,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,
+  0xF1,  0xC7,  0x41,  0x23,  0xE8,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE0,  0x84,
+
 };
 
-STATIC ushort _mcode_size ASC_INITDATA = sizeof(_mcode_buf);
-STATIC ulong _mcode_chksum ASC_INITDATA = 0x01297F32UL;
+STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
+STATIC ulong _asc_mcode_chksum ASC_INITDATA = 0x012A727FUL ;
 
 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
@@ -8096,6 +11171,7 @@
     uchar               disable_cmd;
     ASC_SG_HEAD *sg_head;
     ulong               data_cnt;
+
     iop_base = asc_dvc->iop_base;
     sg_head = scsiq->sg_head;
     asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
@@ -8146,19 +11222,6 @@
             scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
         }
         sg_entry_cnt_minus_one = sg_entry_cnt - 1;
-#if CC_DEBUG_SG_LIST
-        if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
-            for (i = 0; i < sg_entry_cnt_minus_one; i++) {
-                addr = sg_head->sg_list[i].addr + sg_head->sg_list[i].bytes;
-                if (((ushort) addr & 0x0003) != 0) {
-                    asc_dvc->in_critical_cnt--;
-                    DvcLeaveCritical(last_int_level);
-                    AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_LIST_ODD_ADDRESS);
-                    return (ERR);
-                }
-            }
-        }
-#endif
     }
     scsi_cmd = scsiq->cdbptr[0];
     disable_syn_offset_one_fix = FALSE;
@@ -8280,6 +11343,7 @@
     uchar               tid_no;
     uchar               target_ix;
     int                 sta;
+
     iop_base = asc_dvc->iop_base;
     target_ix = scsiq->q2.target_ix;
     tid_no = ASC_TIX_TO_TID(target_ix);
@@ -8294,9 +11358,6 @@
             scsiq->q1.q_no = free_q_head;
             if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
                                               free_q_head)) == 1) {
-#if CC_WRITE_IO_COUNT
-                asc_dvc->req_count++;
-#endif
                 AscPutVarFreeQHead(iop_base, next_qp);
                 asc_dvc->cur_total_qng += (uchar) (n_q_required);
                 asc_dvc->cur_dvc_qng[tid_no]++;
@@ -8309,9 +11370,6 @@
             scsiq->q1.q_no = free_q_head;
             if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
                                         free_q_head)) == 1) {
-#if CC_WRITE_IO_COUNT
-                asc_dvc->req_count++;
-#endif
                 AscPutVarFreeQHead(iop_base, next_qp);
                 asc_dvc->cur_total_qng++;
                 asc_dvc->cur_dvc_qng[tid_no]++;
@@ -8328,6 +11386,7 @@
 )
 {
     int                 n_sg_list_qs;
+
     n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
     if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
         n_sg_list_qs++;
@@ -8346,6 +11405,7 @@
     uint                cur_free_qs;
     ASC_SCSI_BIT_ID_TYPE target_id;
     uchar               tid_no;
+
     target_id = ASC_TIX_TO_TARGET_ID(target_ix);
     tid_no = ASC_TIX_TO_TID(target_ix);
     if ((asc_dvc->unit_not_ready & target_id) ||
@@ -8389,6 +11449,7 @@
     uchar               syn_period_ix;
     uchar               syn_offset;
     PortAddr            iop_base;
+
     iop_base = asc_dvc->iop_base;
     if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
         ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
@@ -8410,43 +11471,10 @@
                          (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
                          (ushort *) scsiq->cdbptr,
                          (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
-#if !CC_LITTLE_ENDIAN_HOST
-    AscAdjEndianScsiQ(scsiq);
-#endif
     DvcPutScsiQ(iop_base,
                 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
                 (ushort *) & scsiq->q1.cntl,
       (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
-#if CC_WRITE_IO_COUNT
-    AscWriteLramWord(iop_base,
-                     (ushort) (q_addr + (ushort) ASC_SCSIQ_W_REQ_COUNT),
-                     (ushort) asc_dvc->req_count);
-#endif
-#if CC_VERIFY_LRAM_COPY
-    if ((asc_dvc->dvc_cntl & ASC_CNTL_NO_VERIFY_COPY) == 0) {
-        if (AscMemWordCmpToLram(iop_base,
-                             (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
-                                (ushort *) scsiq->cdbptr,
-                                (ushort) (scsiq->q2.cdb_len >> 1)) != 0) {
-            AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
-            return (ERR);
-        }
-        if (AscMemWordCmpToLram(iop_base,
-                             (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
-                                (ushort *) & scsiq->q1.cntl,
-         (ushort) (((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1))
-            != 0) {
-            AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
-            return (ERR);
-        }
-    }
-#endif
-#if CC_CLEAR_DMA_REMAIN
-    AscWriteLramDWord(iop_base,
-           (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_ADDR), 0UL);
-    AscWriteLramDWord(iop_base,
-            (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT), 0UL);
-#endif
     AscWriteLramWord(iop_base,
                      (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
              (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
@@ -8472,6 +11500,7 @@
     ushort              sg_entry_cnt;
     ushort              q_addr;
     uchar               next_qp;
+
     iop_base = asc_dvc->iop_base;
     sg_head = scsiq->sg_head;
     saved_data_addr = scsiq->q1.data_addr;
@@ -8542,6 +11571,7 @@
     int                 sta;
     ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
     PortAddr            iop_base;
+
     iop_base = asc_dvc->iop_base;
     sta = ERR;
     saved_unit_not_ready = asc_dvc->unit_not_ready;
@@ -8571,6 +11601,7 @@
     PortAddr            iop_base;
     int                 sta;
     uchar               tid_no;
+
     ASC_SCSI_BIT_ID_TYPE target_id;
     int                 i;
     ASC_SCSI_REQ_Q      scsiq_buf;
@@ -8642,13 +11673,14 @@
     int                 sta;
     int                 i;
     PortAddr            iop_base;
+
     iop_base = asc_dvc->iop_base;
     asc_dvc->unit_not_ready = 0xFF;
     sta = TRUE;
     AscWaitISRDone(asc_dvc);
     AscStopQueueExe(iop_base);
     asc_dvc->sdtr_done = 0;
-    AscResetChipAndScsiBus(iop_base);
+    AscResetChipAndScsiBus(asc_dvc);
     DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
     AscReInitLram(asc_dvc);
     for (i = 0; i <= ASC_MAX_TID; i++) {
@@ -8679,6 +11711,7 @@
 )
 {
     int                 sta = FALSE;
+
     if (AscHostReqRiscHalt(iop_base)) {
         sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
         AscStartChip(iop_base);
@@ -8696,8 +11729,8 @@
 {
     ASC_SCSI_BIT_ID_TYPE org_id;
     int                 i;
-    int                 sta;
-    sta = TRUE;
+    int                 sta = TRUE;
+
     AscSetBank(iop_base, 1);
     org_id = AscReadChipDvcID(iop_base);
     for (i = 0; i <= ASC_MAX_TID; i++) {
@@ -8740,6 +11773,7 @@
     ushort              s_addr;
     PortAddr            iop_base;
     ushort              warn_code;
+
     iop_base = asc_dvc->iop_base;
     warn_code = 0;
     AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
@@ -8791,6 +11825,7 @@
     PortAddr            iop_base;
     int                 i;
     ushort              lram_addr;
+
     iop_base = asc_dvc->iop_base;
     AscPutRiscVarFreeQHead(iop_base, 1);
     AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
@@ -8840,6 +11875,7 @@
     ushort              q_addr;
     uchar               q_status;
     int                 count = 0;
+
     while (scsiq->q1.q_no == 0) ;
     q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
     do {
@@ -8899,6 +11935,7 @@
 {
     uchar               byte;
     uchar               sdtr_period_ix;
+
     sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
     if (
            (sdtr_period_ix > asc_dvc->max_sdtr_index)
@@ -8931,6 +11968,7 @@
     int                 max_index;
     int                 min_index;
     int                 i;
+
     period_table = asc_dvc->sdtr_period_tbl;
     max_index = (int) asc_dvc->max_sdtr_index;
     min_index = (int)asc_dvc->host_init_sdtr_index ;
@@ -8955,6 +11993,7 @@
     ushort              q_addr;
     uchar               next_qp;
     uchar               q_status;
+
     q_addr = ASC_QNO_TO_QADDR(free_q_head);
     q_status = (uchar) AscReadLramByte(iop_base,
                                     (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
@@ -8974,6 +12013,7 @@
 )
 {
     uchar               i;
+
     for (i = 0; i < n_free_q; i++) {
         if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
             == ASC_QLINK_END) {
@@ -8996,6 +12036,7 @@
     ASC_QDONE_INFO *scsiq;
     ASC_ISR_CALLBACK    asc_isr_callback;
     int                 last_int_level;
+
     iop_base = asc_dvc->iop_base;
     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
     last_int_level = DvcEnterCritical();
@@ -9041,6 +12082,7 @@
     ASC_QDONE_INFO *scsiq;
     ASC_ISR_CALLBACK    asc_isr_callback;
     int                 last_int_level;
+
     iop_base = asc_dvc->iop_base;
     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
     last_int_level = DvcEnterCritical();
@@ -9078,6 +12120,7 @@
     int                 count = 0;
     int                 sta = 0;
     uchar               saved_stop_code;
+
     if (AscIsChipHalted(iop_base))
         return (1);
     saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
@@ -9100,8 +12143,8 @@
                    PortAddr iop_base
 )
 {
-    int                 count;
-    count = 0;
+    int                 count = 0;
+
     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                          ASC_STOP_REQ_RISC_STOP);
@@ -9135,6 +12178,7 @@
 {
     int                 count;
     uchar               stop_code;
+
     count = 0;
     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
@@ -9157,6 +12201,7 @@
 {
     int                 count;
     uchar               stop_code;
+
     count = 0;
     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
@@ -9180,12 +12225,14 @@
 {
     uchar               cur_req;
     uchar               tid_no;
+    int                 i = 0;
+
     tid_no = ASC_TIX_TO_TID(target_ix);
-    while (TRUE) {
+    while (i++ < 10) {
         if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
             break;
         }
-        DvcSleepMilliSecond(1000L);
+        DvcSleepMilliSecond(100L);
         if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
             break;
         }
@@ -9199,6 +12246,7 @@
 )
 {
     int                 tid;
+
     for (tid = 0; tid <= ASC_MAX_TID; tid++) {
         AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
     }
@@ -9213,6 +12261,7 @@
 )
 {
     ASC_MIN_SG_HEAD     sg_head;
+
     sg_head.entry_cnt = ASC_MIN_SG_LIST;
     if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
                   buf_size, (ASC_SG_HEAD *) & sg_head) != buf_size) {
@@ -9225,20 +12274,15 @@
 }
 
 STATIC void
-DvcDelayNanoSecond(
-                      ASC_DVC_VAR asc_ptr_type * asc_dvc,
-                      ulong nano_sec
-)
+DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
 {
-    ulong               loop;
-    PortAddr            iop_base;
-    iop_base = asc_dvc->iop_base;
-    loop = nano_sec / 90;
-    loop++;
-    while (loop-- != 0) {
-        inp(iop_base);
-    }
-    return;
+    udelay(micro_sec);
+}
+
+STATIC void
+DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec)
+{
+    udelay((nano_sec + 999)/1000);
 }
 
 ASC_INITFUNC(
@@ -9251,6 +12295,7 @@
     PortAddr            eisa_iop;
     ushort              product_id_high, product_id_low;
     ulong               product_id;
+
     eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
     product_id_low = inpw(eisa_iop);
     product_id_high = inpw(eisa_iop + 2);
@@ -9266,6 +12311,7 @@
 )
 {
     ulong               eisa_product_id;
+
     if (iop_base == 0) {
         iop_base = ASC_EISA_MIN_IOP_ADDR;
     } else {
@@ -9315,6 +12361,7 @@
 )
 {
     uchar               cc_val;
+
     cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
     AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
     AscSetChipIH(iop_base, INS_HALT);
@@ -9358,6 +12405,7 @@
     uchar               host_flag;
     uchar               risc_flag;
     ushort              loop;
+
     loop = 0;
     do {
         risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
@@ -9386,6 +12434,7 @@
 )
 {
     ushort              cfg;
+
     cfg = AscGetChipCfgLsw(iop_base);
     AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
     return;
@@ -9397,6 +12446,7 @@
 )
 {
     ushort              cfg;
+
     cfg = AscGetChipCfgLsw(iop_base);
     AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
     return;
@@ -9411,6 +12461,7 @@
 )
 {
     uchar               val;
+
     val = AscGetChipControl(iop_base) &
       (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
     if (bank == 1) {
@@ -9424,17 +12475,18 @@
     return;
 }
 
-
-
 STATIC int
 AscResetChipAndScsiBus(
-                          PortAddr iop_base
+                          ASC_DVC_VAR *asc_dvc
 )
 {
+    PortAddr    iop_base;
+
+    iop_base = asc_dvc->iop_base;
     while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
     AscStopChip(iop_base);
     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
-    DvcSleepMilliSecond(200);
+    DvcDelayNanoSecond(asc_dvc, 60000);
     AscSetChipIH(iop_base, INS_RFLAG_WTM);
     AscSetChipIH(iop_base, INS_HALT);
     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
@@ -9467,6 +12519,7 @@
 )
 {
     ushort              channel;
+
     channel = AscGetChipCfgLsw(iop_base) & 0x0003;
     if (channel == 0x03)
         return (0);
@@ -9485,6 +12538,7 @@
 {
     ushort              cfg_lsw;
     uchar               value;
+
     if ((dma_channel >= 5) && (dma_channel <= 7)) {
         if (dma_channel == 7)
             value = 0x00;
@@ -9521,6 +12575,7 @@
 )
 {
     uchar               speed_value;
+
     AscSetBank(iop_base, 1);
     speed_value = AscReadChipDmaSpeed(iop_base);
     speed_value &= 0x07;
@@ -9634,8 +12689,8 @@
 )
 )
 {
-    ushort              warn_code;
-    warn_code = 0;
+    ushort              warn_code = 0;
+
     asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
     if (asc_dvc->err_code != 0)
         return (UW_ERR);
@@ -9659,6 +12714,7 @@
     ushort              cfg_msw;
     ushort              warn_code;
     ushort              pci_device_id;
+
     iop_base = asc_dvc->iop_base;
     pci_device_id = asc_dvc->cfg->pci_device_id;
     warn_code = 0;
@@ -9683,10 +12739,8 @@
         }
     }
     if (asc_dvc->bus_type & ASC_IS_PCI) {
-#if CC_DISABLE_PCI_PARITY_INT
         cfg_msw &= 0xFFC0;
         AscSetChipCfgMsw(iop_base, cfg_msw);
-#endif
         if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
         } else {
             if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
@@ -9721,14 +12775,15 @@
 {
     ushort              warn_code;
     PortAddr            iop_base;
-    extern ushort       _mcode_size;
-    extern ulong        _mcode_chksum;
-    extern uchar        _mcode_buf[];
+    extern ushort       _asc_mcode_size;
+    extern ulong        _asc_mcode_chksum;
+    extern uchar        _asc_mcode_buf[];
+
     iop_base = asc_dvc->iop_base;
     warn_code = 0;
     if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
         !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
-        AscResetChipAndScsiBus(iop_base);
+        AscResetChipAndScsiBus(asc_dvc);
         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
     }
     asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
@@ -9742,8 +12797,8 @@
     warn_code |= AscInitLram(asc_dvc);
     if (asc_dvc->err_code != 0)
         return (UW_ERR);
-    if (AscLoadMicroCode(iop_base, 0, (ushort *) _mcode_buf,
-                         _mcode_size) != _mcode_chksum) {
+    if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
+                         _asc_mcode_size) != _asc_mcode_chksum) {
         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
         return (warn_code);
     }
@@ -9764,6 +12819,7 @@
     PortAddr            iop_base;
     ushort              warn_code;
     uchar               chip_version;
+
     iop_base = asc_dvc->iop_base;
     warn_code = 0;
     asc_dvc->err_code = 0;
@@ -9866,7 +12922,6 @@
     return (warn_code);
 }
 
-#if CC_INCLUDE_EEP_CONFIG
 ASC_INITFUNC(
 STATIC ushort
 AscInitFromEEP(
@@ -9875,12 +12930,14 @@
 )
 {
     ASCEEP_CONFIG       eep_config_buf;
-    ASCEEP_CONFIG *eep_config;
+    ASCEEP_CONFIG       *eep_config;
     PortAddr            iop_base;
     ushort              chksum;
     ushort              warn_code;
     ushort              cfg_msw, cfg_lsw;
     int                 i;
+    int                 write_eep = 0;
+
     iop_base = asc_dvc->iop_base;
     warn_code = 0;
     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
@@ -9888,7 +12945,7 @@
     if ((AscStopChip(iop_base) == FALSE) ||
         (AscGetChipScsiCtrl(iop_base) != 0)) {
         asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
-        AscResetChipAndScsiBus(iop_base);
+        AscResetChipAndScsiBus(asc_dvc);
         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
     }
     if (AscIsChipHalted(iop_base) == FALSE) {
@@ -9909,7 +12966,9 @@
         AscSetChipCfgMsw(iop_base, cfg_msw);
     }
     chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
-    eep_config->cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
+    if (chksum == 0) {
+        chksum = 0xaa55;
+    }
     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
         warn_code |= ASC_WARN_AUTO_CONFIG;
         if (asc_dvc->cfg->chip_version == 3) {
@@ -9923,9 +12982,32 @@
             }
         }
     }
+    eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
     eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
     if (chksum != eep_config->chksum) {
-        warn_code |= ASC_WARN_EEPROM_CHKSUM;
+            if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
+                    ASC_CHIP_VER_PCI_ULTRA_3050 )
+            {
+                eep_config->init_sdtr = 0xFF;
+                eep_config->disc_enable = 0xFF;
+                eep_config->start_motor = 0xFF;
+                eep_config->use_cmd_qng = 0;
+                eep_config->max_total_qng = 0xF0;
+                eep_config->max_tag_qng = 0x20;
+                eep_config->cntl = 0xBFFF;
+                eep_config->chip_scsi_id = 7;
+                eep_config->no_scam = 0;
+                eep_config->adapter_info[0] = 0;
+                eep_config->adapter_info[1] = 0;
+                eep_config->adapter_info[2] = 0;
+                eep_config->adapter_info[3] = 0;
+                eep_config->adapter_info[4] = 0;
+                /* Indicate EEPROM-less board. */
+                eep_config->adapter_info[5] = 0xBB;
+            } else {
+                write_eep = 1 ;
+                warn_code |= ASC_WARN_EEPROM_CHKSUM ;
+            }
     }
     asc_dvc->init_sdtr = eep_config->init_sdtr;
     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
@@ -9934,6 +13016,12 @@
     asc_dvc->start_motor = eep_config->start_motor;
     asc_dvc->dvc_cntl = eep_config->cntl;
     asc_dvc->no_scam = eep_config->no_scam;
+    asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
+    asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
+    asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
+    asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
+    asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
+    asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
     if (!AscTestExternalLram(asc_dvc)) {
         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
             eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
@@ -9976,9 +13064,6 @@
     }
 
     for (i = 0; i <= ASC_MAX_TID; i++) {
-#if CC_TMP_USE_EEP_SDTR
-        asc_dvc->cfg->sdtr_period_offset[i] = eep_config->dos_int13_table[i];
-#endif
         asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
         asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
         asc_dvc->cfg->sdtr_period_offset[i] =
@@ -9986,14 +13071,11 @@
                      (asc_dvc->host_init_sdtr_index << 4));
     }
     eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
-#if CC_CHK_FIX_EEP_CONTENT
-    if (AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type) != 0) {
-        asc_dvc->err_code |= ASC_IERR_WRITE_EEPROM;
+    if (write_eep) {
+        (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
     }
-#endif
     return (warn_code);
 }
-#endif
 
 ASC_INITFUNC(
 STATIC ushort
@@ -10006,6 +13088,7 @@
     ushort              warn_code;
     PortAddr            iop_base;
     ulong               phy_addr;
+
     iop_base = asc_dvc->iop_base;
     warn_code = 0;
     for (i = 0; i <= ASC_MAX_TID; i++) {
@@ -10054,6 +13137,7 @@
     ASC_ISR_CALLBACK    asc_isr_callback;
     uchar               cp_sen_len;
     uchar               i;
+
     ASC_DBG(1, "AscInitPollIsrCallBack: begin\n");
     if ((scsi_done_q->d2.flag & ASC_FLAG_SCSIQ_REQ) != 0) {
         scsiq_req = (ASC_SCSI_REQ_Q *) scsi_done_q->d2.srb_ptr;
@@ -10095,6 +13179,7 @@
     ushort              q_addr;
     ushort              saved_word;
     int                 sta;
+
     iop_base = asc_dvc->iop_base;
     sta = 0;
     q_addr = ASC_QNO_TO_QADDR(241);
@@ -10110,7 +13195,6 @@
     return (sta);
 }
 
-#if CC_INCLUDE_EEP_CONFIG
 ASC_INITFUNC(
 STATIC int
 AscWriteEEPCmdReg(
@@ -10121,6 +13205,7 @@
 {
     uchar               read_back;
     int                 retry;
+
     retry = 0;
     while (TRUE) {
         AscSetChipEEPCmd(iop_base, cmd_reg);
@@ -10145,6 +13230,7 @@
 {
     ushort              read_back;
     int                 retry;
+
     retry = 0;
     while (TRUE) {
         AscSetChipEEPData(iop_base, data_reg);
@@ -10191,6 +13277,7 @@
 {
     ushort              read_wval;
     uchar               cmd_reg;
+
     AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
     AscWaitEEPRead();
     cmd_reg = addr | ASC_EEP_CMD_READ;
@@ -10211,6 +13298,7 @@
 )
 {
     ushort              read_wval;
+
     read_wval = AscReadEEPWord(iop_base, addr);
     if (read_wval != word_val) {
         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
@@ -10242,6 +13330,7 @@
     int                 cfg_end;
     int                 s_addr;
     int                 isa_pnp_wsize;
+
     wbuf = (ushort *) cfg_buf;
     sum = 0;
     isa_pnp_wsize = 0;
@@ -10267,7 +13356,6 @@
     return (sum);
 }
 
-#if CC_CHK_FIX_EEP_CONTENT
 ASC_INITFUNC(
 STATIC int
 AscSetEEPConfigOnce(
@@ -10282,6 +13370,7 @@
     int                 s_addr;
     int                 cfg_beg;
     int                 cfg_end;
+
     wbuf = (ushort *) cfg_buf;
     n_error = 0;
     sum = 0;
@@ -10347,8 +13436,6 @@
     }
     return (n_error);
 }
-#endif
-#endif
 
 STATIC int
 AscInitPollBegin(
@@ -10356,6 +13443,7 @@
 )
 {
     PortAddr            iop_base;
+
     iop_base = asc_dvc->iop_base;
     AscDisableInterrupt(iop_base);
     asc_dvc->init_state |= ASC_INIT_STATE_BEG_INQUIRY;
@@ -10374,6 +13462,7 @@
 {
     PortAddr            iop_base;
     rint                i;
+
     iop_base = asc_dvc->iop_base;
     asc_dvc->isr_callback = (Ptr2Func) asc_dvc->saved_ptr2func;
     AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
@@ -10393,8 +13482,6 @@
     return (0);
 }
 
-STATIC int                 _asc_wait_slow_device_ = FALSE;
-
 STATIC int
 AscInitPollTarget(
                      REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
@@ -10425,9 +13512,9 @@
     if (PollScsiInquiry(asc_dvc, scsiq, (uchar *) inq,
         sizeof (ASC_SCSI_INQUIRY)) == 1) {
         dvc_found = 1;
-        support_read_cap = TRUE;
         dvc_type = inq->byte0.peri_dvc_type;
         if (dvc_type != SCSI_TYPE_UNKNOWN) {
+            support_read_cap = TRUE;
             if ((dvc_type != SCSI_TYPE_DASD)
                 && (dvc_type != SCSI_TYPE_WORM)
                 && (dvc_type != SCSI_TYPE_CDROM)
@@ -10435,12 +13522,6 @@
                 asc_dvc->start_motor &= ~tid_bits;
                 support_read_cap = FALSE;
             }
-            if ((dvc_type != SCSI_TYPE_DASD) || inq->byte1.rmb) {
-                if (!_asc_wait_slow_device_) {
-                    DvcSleepMilliSecond(3000 - ((int) tid_no * 250));
-                    _asc_wait_slow_device_ = TRUE;
-                }
-            }
             if (lun == 0) {
                 if ((inq->byte3.rsp_data_fmt >= 2) ||
                     (inq->byte2.ansi_apr_ver >= 2)) {
@@ -10494,6 +13575,14 @@
                          (uchar *)"CD-ROM DRIVE    ", 16) == 0)) {
                         asc_dvc->pci_fix_asyn_xfer &= ~tid_bits ;
                     }
+                    if ((dvc_type == SCSI_TYPE_CDROM) &&
+                        (AscCompareString((uchar *) inq->vendor_id,
+                         (uchar *) "YAMAHA", 6) == 0)  &&
+                        (AscCompareString((uchar *) inq->product_id,
+                         (uchar *) "CDR400", 6) == 0))
+                    {
+                        asc_dvc->pci_fix_asyn_xfer &= ~tid_bits ;
+                    }
  
                     if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
                         AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
@@ -10553,7 +13642,7 @@
                     scsiq->r3.host_stat = 0;
                     scsiq->r3.scsi_stat = 0;
                     scsiq->r3.scsi_msg = 0;
-                    DvcSleepMilliSecond(2000);
+                    DvcSleepMilliSecond(1000);
                     continue;
                 }
                 scsiq->r3.done_stat = 0;
@@ -10611,19 +13700,15 @@
 {
     ASC_CAP_INFO        scsi_cap_info;
     int                 status;
+
     if (AscScsiReadCapacity(asc_dvc, scsiq,
                             (uchar *) & scsi_cap_info) == ERR) {
         return (scsiq->r3.done_stat = QD_WITH_ERROR);
     }
     status = PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q *) scsiq, 8);
     if (status == 1) {
-#if CC_LITTLE_ENDIAN_HOST
         cap_info->lba = (ulong) * swapfarbuf4((uchar *) & scsi_cap_info.lba);
         cap_info->blk_size = (ulong) * swapfarbuf4((uchar *) & scsi_cap_info.blk_size);
-#else
-        cap_info->lba = scsi_cap_info.lba;
-        cap_info->blk_size = scsi_cap_info.blk_size;
-#endif
         return (scsiq->r3.done_stat);
     }
     return (scsiq->r3.done_stat = QD_WITH_ERROR);
@@ -10668,6 +13753,7 @@
     ASC_SCSI_BIT_ID_TYPE tid_bits;
     int                 retry;
     ASC_REQ_SENSE *sen;
+
     retry = 0;
     tid_bits = scsiq->r1.target_id;
     while (retry++ < 4) {
@@ -10675,26 +13761,28 @@
         if (scsiq->r3.done_stat == 0x01) {
             return (1);
         } else if (scsiq->r3.done_stat == QD_WITH_ERROR) {
-            DvcSleepMilliSecond(200);
             sen = (ASC_REQ_SENSE *) scsiq->sense_ptr;
             if ((scsiq->r3.scsi_stat == SS_CHK_CONDITION) &&
                 ((sen->err_code & 0x70) != 0)) {
                 if (sen->sense_key == SCSI_SENKEY_NOT_READY) {
+                    if (sen->asc == SCSI_ASC_NOMEDIA)
+                    {
+                        break;
+                    }
                     if (asc_dvc->start_motor & tid_bits) {
                         if (PollScsiStartUnit(asc_dvc, scsiq) == 1) {
-                            retry = 0;
+                            DvcSleepMilliSecond(250);
                             continue;
                         } else {
                             asc_dvc->start_motor &= ~tid_bits;
                             break;
                         }
                     } else {
-                        DvcSleepMilliSecond(5000);
+                        DvcSleepMilliSecond(250);
                     }
                 } else if (sen->sense_key == SCSI_SENKEY_ATTENTION) {
-                    DvcSleepMilliSecond((ulong)(500L*retry)) ;
+                    DvcSleepMilliSecond(250);
                 } else {
-                    DvcSleepMilliSecond(500) ;
                     break;
                 }
             } else {
@@ -10719,6 +13807,7 @@
     int                 loop, loop_end;
     int                 sta;
     PortAddr            iop_base;
+
     iop_base = asc_dvc->iop_base;
     loop = 0;
     loop_end = timeout_sec * 100;
@@ -10745,17 +13834,11 @@
         }
         if (AscIsChipHalted(iop_base)) {
             ASC_DBG(1, "AscPollQDone: AscIsChipHalted()\n");
-#if !CC_ASCISR_CHECK_INT_PENDING
-            AscAckInterrupt(iop_base);
-#endif
             AscISR(asc_dvc);
             loop = 0;
         } else {
             if (AscIsIntPending(iop_base)) {
                 ASC_DBG(1, "AscPollQDone: AscIsIntPending()\n");
-#if !CC_ASCISR_CHECK_INT_PENDING
-                AscAckInterrupt(iop_base);
-#endif
                 AscISR(asc_dvc);
             }
         }
@@ -10772,6 +13855,7 @@
 {
     int                 i;
     int                 diff;
+
     for (i = 0; i < len; i++) {
         diff = (int) (str1[i] - str2[i]);
         if (diff != 0)
@@ -10788,6 +13872,7 @@
 {
     uchar               byte_data;
     ushort              word_data;
+
     if (isodd_word(addr)) {
         AscSetChipLramAddr(iop_base, addr - 1);
         word_data = AscGetChipLramData(iop_base);
@@ -10807,6 +13892,7 @@
 )
 {
     ushort              word_data;
+
     AscSetChipLramAddr(iop_base, addr);
     word_data = AscGetChipLramData(iop_base);
     return (word_data);
@@ -10820,6 +13906,7 @@
 {
     ushort              val_low, val_high;
     ulong               dword_data;
+
     AscSetChipLramAddr(iop_base, addr);
     val_low = AscGetChipLramData(iop_base);
     val_high = AscGetChipLramData(iop_base);
@@ -10847,6 +13934,7 @@
 )
 {
     ushort              word_val;
+
     AscSetChipLramAddr(iop_base, addr);
     word_val = (ushort) dword_val;
     AscSetChipLramData(iop_base, word_val);
@@ -10863,6 +13951,7 @@
 )
 {
     ushort              word_data;
+
     if (isodd_word(addr)) {
         addr--;
         word_data = AscReadLramWord(iop_base, addr);
@@ -10925,6 +14014,7 @@
 {
     ulong               sum;
     int                 i;
+
     sum = 0L;
     for (i = 0; i < words; i++, s_addr += 2) {
         sum += AscReadLramWord(iop_base, s_addr);
@@ -10941,6 +14031,7 @@
 )
 {
     rint             i;
+
     AscSetChipLramAddr(iop_base, s_addr);
     for (i = 0; i < words; i++) {
         AscSetChipLramData(iop_base, set_wval);
@@ -11035,4 +14126,1728 @@
     scsiq->cdb[5] = 0;
     scsiq->r2.cdb_len = 6;
     return (0);
+}
+
+
+/*
+ * --- Adv Library Functions
+ */
+
+/* a_qswap.h */
+STATIC unsigned char _adv_mcode_buf[] ASC_INITDATA = {
+  0x9C,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0x40,  0x0A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x72,  0x01,  0xD2,  0x11,  0x00,  0x00,  0x70,  0x01,
+  0x30,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x88,  0x0F,  0x22,  0x03,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x48,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x78,  0x56,  0x34,  0x12,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x0C,  0x1C,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF2,  0xD2,  0x0A,
+  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x3E,  0x57,  0x3C,  0x56,  0x0C,  0x1C,  0x00,  0xFC,
+  0xA6,  0x00,  0x01,  0x58,  0xAA,  0x13,  0x20,  0xF0,  0x9A,  0x03,  0x06,  0xEC,  0xB9,  0x00,  0x0E,  0x47,
+  0x03,  0xE6,  0x10,  0x00,  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0x06,  0xEA,  0xB9,  0x00,  0x47,  0x4B,
+  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x01,  0x48,  0x4E,  0x12,  0x03,  0xF6,  0xC0,  0x00,
+  0x00,  0xF2,  0x64,  0x0A,  0x41,  0x58,  0x03,  0xF6,  0xD0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x49,  0x44,
+  0x59,  0xF0,  0x0A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x44,  0x58,  0x00,  0xF2,
+  0xDE,  0x0D,  0x02,  0xCC,  0x4A,  0xE4,  0x01,  0x00,  0x55,  0xF0,  0x08,  0x03,  0x45,  0xF4,  0x02,  0x00,
+  0x83,  0x5A,  0x04,  0xCC,  0x01,  0x4A,  0x12,  0x12,  0x00,  0xF2,  0xDE,  0x0D,  0x00,  0xCD,  0x48,  0xE4,
+  0x01,  0x00,  0xE9,  0x13,  0x00,  0xF2,  0xC2,  0x0F,  0xFA,  0x10,  0x0E,  0x47,  0x03,  0xE6,  0x10,  0x00,
+  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0xCE,  0x47,  0x97,  0x13,  0x04,  0xEC,  0xB4,  0x00,  0x00,  0xF2,
+  0xDE,  0x0D,  0x00,  0xCD,  0x48,  0xE4,  0x00,  0x00,  0x12,  0x12,  0x3E,  0x57,  0x06,  0xCC,  0x45,  0xF4,
+  0x02,  0x00,  0x83,  0x5A,  0x00,  0xCC,  0x00,  0xEA,  0xB4,  0x00,  0x92,  0x10,  0x00,  0xF0,  0x8C,  0x01,
+  0x43,  0xF0,  0x5C,  0x02,  0x44,  0xF0,  0x60,  0x02,  0x45,  0xF0,  0x64,  0x02,  0x46,  0xF0,  0x68,  0x02,
+  0x47,  0xF0,  0x6E,  0x02,  0x48,  0xF0,  0x9E,  0x02,  0xB9,  0x54,  0x62,  0x10,  0x00,  0x1C,  0x5A,  0x10,
+  0x02,  0x1C,  0x56,  0x10,  0x1E,  0x1C,  0x52,  0x10,  0x00,  0xF2,  0x1A,  0x11,  0x50,  0x10,  0x06,  0xFC,
+  0xA8,  0x00,  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x4A,  0x0A,  0x8C,  0x10,  0x01,  0xF6,  0x01,  0x00,
+  0x01,  0xFA,  0xA8,  0x00,  0x00,  0xF2,  0x28,  0x0B,  0x06,  0x10,  0xB9,  0x54,  0x01,  0xFA,  0xA8,  0x00,
+  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x54,  0x0A,  0x01,  0xFC,  0xA8,  0x00,  0x20,  0x10,  0x58,  0x1C,
+  0x00,  0xF2,  0x18,  0x0B,  0x5A,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,  0x00,  0xFA,  0xA6,  0x00,
+  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x72,  0x01,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,
+  0x00,  0xFA,  0xA6,  0x00,  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x80,  0x01,  0x03,  0xF6,
+  0xE0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x01,  0x48,  0x0A,  0x13,  0x00,  0xF2,  0x34,  0x10,  0x00,  0xF2,
+  0x50,  0x0F,  0x24,  0x10,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x02,  0xF6,  0xD0,  0x00,
+  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x49,  0x44,  0x5B,  0xF0,  0x04,  0x03,  0x00,  0xF2,  0x98,  0x0F,
+  0x00,  0xF0,  0x80,  0x01,  0x00,  0xF2,  0x10,  0x10,  0x0C,  0x1C,  0x02,  0x4B,  0xBF,  0x57,  0x9E,  0x43,
+  0x77,  0x57,  0x07,  0x4B,  0x20,  0xF0,  0x9A,  0x03,  0x40,  0x1C,  0x1E,  0xF0,  0x30,  0x03,  0x26,  0xF0,
+  0x2C,  0x03,  0xA0,  0xF0,  0x1A,  0x03,  0x11,  0xF0,  0x9A,  0x03,  0x12,  0x10,  0x9F,  0xF0,  0x3E,  0x03,
+  0x46,  0x1C,  0x82,  0xE7,  0x05,  0x00,  0x9E,  0xE7,  0x11,  0x00,  0x00,  0xF0,  0x02,  0x0A,  0x0C,  0x1C,
+  0x48,  0x1C,  0x46,  0x1C,  0x38,  0x54,  0x00,  0xEC,  0xBA,  0x00,  0x08,  0x44,  0x00,  0xEA,  0xBA,  0x00,
+  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x08,  0x44,  0x00,  0x4C,  0x82,  0xE7,  0x02,  0x00,
+  0x00,  0xF2,  0x0E,  0x11,  0x00,  0xF2,  0x0E,  0x11,  0x06,  0xF0,  0x74,  0x03,  0x1E,  0xF0,  0xF8,  0x09,
+  0x00,  0xF0,  0xFE,  0x09,  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0x55,  0xF0,  0xA0,  0x04,  0x01,  0xE6,
+  0x0C,  0x00,  0x00,  0xF2,  0x4A,  0x0D,  0x00,  0xF2,  0x0E,  0x11,  0x00,  0xF2,  0xB8,  0x11,  0x00,  0xF2,
+  0xC4,  0x11,  0x01,  0xF0,  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x46,  0x1C,  0x0C,  0x1C,  0x67,  0x1B,
+  0xBF,  0x57,  0x77,  0x57,  0x02,  0x4B,  0x48,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x8E,  0x0D,  0x30,  0x1C,
+  0x96,  0xF0,  0xB0,  0x03,  0xB1,  0xF0,  0xB4,  0x03,  0x1E,  0xF0,  0xF8,  0x09,  0x85,  0xF0,  0xFE,  0x09,
+  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0x14,  0x12,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,  0x4A,  0x0D,
+  0x00,  0xF2,  0x0E,  0x11,  0x01,  0xF0,  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x03,  0xF6,  0xE0,  0x00,
+  0x00,  0xF2,  0x64,  0x0A,  0x01,  0x48,  0x55,  0xF0,  0x8C,  0x04,  0x03,  0x82,  0x03,  0xFC,  0xA0,  0x00,
+  0x9B,  0x57,  0x40,  0x12,  0x69,  0x18,  0x00,  0xF2,  0x0E,  0x11,  0x85,  0xF0,  0x36,  0x04,  0x69,  0x08,
+  0x00,  0xF2,  0x0E,  0x11,  0x85,  0xF0,  0xFE,  0x09,  0x68,  0x08,  0x4C,  0x44,  0x28,  0x12,  0x44,  0x48,
+  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x45,  0x58,  0x00,  0xF2,  0xF2,  0x0D,  0x00,  0xCC,
+  0x01,  0x48,  0x55,  0xF0,  0x8C,  0x04,  0x4C,  0x44,  0xEF,  0x13,  0x00,  0xF2,  0xC2,  0x0F,  0x00,  0xF2,
+  0x10,  0x10,  0x08,  0x10,  0x68,  0x18,  0x45,  0x5A,  0x00,  0xF2,  0xF2,  0x0D,  0x04,  0x80,  0x18,  0xE4,
+  0x10,  0x00,  0x28,  0x12,  0x01,  0xE6,  0x06,  0x00,  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,
+  0x01,  0xE6,  0x0D,  0x00,  0x00,  0xF2,  0x4A,  0x0D,  0x00,  0xF2,  0x0E,  0x11,  0x04,  0xE6,  0x02,  0x00,
+  0x9E,  0xE7,  0x15,  0x00,  0x01,  0xF0,  0x18,  0x0A,  0x00,  0xF0,  0xFE,  0x09,  0x69,  0x08,  0x05,  0x80,
+  0x48,  0xE4,  0x00,  0x00,  0x0C,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,  0xB8,  0x00,  0x00,  0xF2,
+  0xB2,  0x10,  0x82,  0xE7,  0x02,  0x00,  0x1C,  0x90,  0x40,  0x5C,  0x00,  0x16,  0x01,  0xE6,  0x06,  0x00,
+  0x00,  0xF2,  0x4A,  0x0D,  0x01,  0xF0,  0x80,  0x01,  0x1E,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0x94,  0x04,
+  0x42,  0x5B,  0x06,  0xF7,  0x03,  0x00,  0x46,  0x59,  0xBF,  0x57,  0x77,  0x57,  0x01,  0xE6,  0x80,  0x00,
+  0x07,  0x80,  0x31,  0x44,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x5E,  0x13,  0x20,  0x80,  0x48,  0xE4,
+  0x03,  0x00,  0x56,  0x12,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x4C,  0x13,  0x00,  0xFC,  0xA2,  0x00,
+  0x98,  0x57,  0x55,  0xF0,  0x18,  0x05,  0x31,  0xE4,  0x40,  0x00,  0x00,  0xFC,  0xA0,  0x00,  0x98,  0x57,
+  0x36,  0x12,  0x4C,  0x1C,  0x00,  0xF2,  0x0E,  0x11,  0x89,  0x48,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,
+  0x2A,  0x05,  0x82,  0xE7,  0x06,  0x00,  0x1B,  0x80,  0x48,  0xE4,  0x22,  0x00,  0x5B,  0xF0,  0x08,  0x05,
+  0x48,  0xE4,  0x20,  0x00,  0x59,  0xF0,  0x0C,  0x05,  0x00,  0xE6,  0x20,  0x00,  0x09,  0x48,  0x00,  0xF2,
+  0x0E,  0x11,  0x86,  0xF0,  0x2A,  0x05,  0x83,  0x80,  0x04,  0x10,  0x00,  0xF2,  0x9E,  0x0D,  0x00,  0xE6,
+  0x01,  0x00,  0x00,  0xEA,  0x26,  0x01,  0x01,  0xEA,  0x27,  0x01,  0x04,  0x80,  0x18,  0xE4,  0x10,  0x00,
+  0x36,  0x12,  0xB9,  0x54,  0x00,  0xF2,  0xF2,  0x0E,  0x01,  0xE6,  0x06,  0x00,  0x04,  0x80,  0x18,  0xE4,
+  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,  0x00,  0xF2,  0x4A,  0x0D,  0x00,  0xF2,  0x0E,  0x11,
+  0x00,  0xF2,  0xB8,  0x11,  0x00,  0xF2,  0xC4,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,
+  0x01,  0xF0,  0x18,  0x0A,  0x00,  0xF0,  0xFE,  0x09,  0x00,  0xFC,  0x20,  0x01,  0x98,  0x57,  0x34,  0x12,
+  0x00,  0xFC,  0x24,  0x01,  0x98,  0x57,  0x2C,  0x13,  0xB9,  0x54,  0x00,  0xF2,  0xF2,  0x0E,  0x86,  0xF0,
+  0xA4,  0x05,  0x03,  0xF6,  0x01,  0x00,  0x00,  0xF2,  0x88,  0x0E,  0x85,  0xF0,  0x9A,  0x05,  0x82,  0xE7,
+  0x03,  0x00,  0x00,  0xF2,  0x5C,  0x0B,  0x82,  0xE7,  0x02,  0x00,  0x00,  0xFC,  0x24,  0x01,  0xB0,  0x57,
+  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFC,  0x9E,  0x00,  0x98,  0x57,  0x5A,  0x12,  0x00,  0xFC,  0xB6,  0x00,
+  0x98,  0x57,  0x52,  0x13,  0x03,  0xE6,  0x0C,  0x00,  0x00,  0xFC,  0x9C,  0x00,  0x98,  0x57,  0x04,  0x13,
+  0x03,  0xE6,  0x19,  0x00,  0x05,  0xE6,  0x08,  0x00,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,
+  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x04,  0x13,  0x05,  0xE6,  0x0F,  0x00,  0xB9,  0x54,
+  0x00,  0xF2,  0xF2,  0x0E,  0x86,  0xF0,  0x06,  0x06,  0x00,  0xF2,  0xB6,  0x0E,  0x85,  0xF0,  0xFC,  0x05,
+  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x5C,  0x0B,  0x82,  0xE7,  0x02,  0x00,  0x00,  0xFC,  0xB6,  0x00,
+  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0xF2,  0xF2,  0x0E,  0x9C,  0x32,
+  0x4E,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x8E,  0x0D,  0x30,  0x1C,  0x82,  0xE7,  0x04,  0x00,  0xB1,  0xF0,
+  0x1E,  0x06,  0x0A,  0xF0,  0x3A,  0x06,  0x05,  0xF0,  0xD2,  0x06,  0x06,  0xF0,  0xD8,  0x06,  0x09,  0xF0,
+  0x20,  0x09,  0x1E,  0xF0,  0xF8,  0x09,  0x00,  0xF0,  0xFE,  0x09,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,
+  0x30,  0x12,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x21,  0x80,  0x18,  0xE4,  0xE0,  0x00,
+  0x09,  0x48,  0x00,  0xF2,  0x0E,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x09,  0xE7,
+  0x00,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x99,  0xA4,  0x00,  0xF2,  0x0E,  0x11,  0x09,  0xE7,  0x00,  0x00,
+  0x9A,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x34,  0x12,  0x09,  0xE7,  0x1B,  0x00,  0x00,  0xF2,
+  0x0E,  0x11,  0x21,  0x80,  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,  0x0E,  0x11,  0x09,  0xE7,
+  0x00,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x09,  0xE7,
+  0x01,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF0,  0x08,  0x09,  0xBB,  0x55,
+  0x9A,  0x81,  0x03,  0xF7,  0x20,  0x00,  0x09,  0x6F,  0x93,  0x45,  0x55,  0xF0,  0xDE,  0x06,  0xB1,  0xF0,
+  0xBE,  0x06,  0x0A,  0xF0,  0xB6,  0x06,  0x09,  0xF0,  0x20,  0x09,  0x1E,  0xF0,  0xF8,  0x09,  0x00,  0xF0,
+  0xFE,  0x09,  0x00,  0xF2,  0x5C,  0x0B,  0x47,  0x10,  0x09,  0xE7,  0x08,  0x00,  0x41,  0x10,  0x05,  0x80,
+  0x48,  0xE4,  0x00,  0x00,  0x1E,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,  0xB8,  0x00,  0x00,  0xF2,
+  0xB2,  0x10,  0x2C,  0x90,  0xAE,  0x90,  0x08,  0x50,  0x8A,  0x50,  0x38,  0x54,  0x1F,  0x40,  0x00,  0xF2,
+  0xB0,  0x0D,  0x08,  0x10,  0x08,  0x90,  0x8A,  0x90,  0x30,  0x50,  0xB2,  0x50,  0x9C,  0x32,  0x0C,  0x92,
+  0x8E,  0x92,  0x38,  0x54,  0x04,  0x80,  0x30,  0xE4,  0x08,  0x00,  0x04,  0x40,  0x0C,  0x1C,  0x00,  0xF6,
+  0x03,  0x00,  0xB1,  0xF0,  0x22,  0x07,  0x9E,  0xF0,  0x36,  0x07,  0x01,  0x48,  0x55,  0xF0,  0xF8,  0x09,
+  0x0C,  0x1C,  0x10,  0x44,  0xED,  0x10,  0x0B,  0xF0,  0x5A,  0x07,  0x0C,  0xF0,  0x5E,  0x07,  0x05,  0xF0,
+  0x4E,  0x07,  0x06,  0xF0,  0x54,  0x07,  0x09,  0xF0,  0x20,  0x09,  0x00,  0xF0,  0xFE,  0x09,  0x00,  0xF2,
+  0x5C,  0x0B,  0xCF,  0x10,  0x09,  0xE7,  0x08,  0x00,  0xC9,  0x10,  0x2E,  0x1C,  0x02,  0x10,  0x2C,  0x1C,
+  0xAA,  0xF0,  0x60,  0x07,  0xAC,  0xF0,  0x6E,  0x07,  0x40,  0x10,  0x34,  0x1C,  0xF3,  0x10,  0xAD,  0xF0,
+  0x78,  0x07,  0xC8,  0x10,  0x36,  0x1C,  0xE9,  0x10,  0x2B,  0xF0,  0x7E,  0x08,  0x6B,  0x18,  0x18,  0xF4,
+  0x00,  0xFE,  0x20,  0x12,  0x01,  0x58,  0xD2,  0xF0,  0x7E,  0x08,  0x76,  0x18,  0x18,  0xF4,  0x03,  0x00,
+  0xEC,  0x12,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xE2,  0x12,  0x0B,  0xF0,  0x60,  0x07,
+  0x0C,  0xF0,  0x60,  0x07,  0x36,  0x1C,  0x34,  0x1C,  0xB7,  0x10,  0x38,  0x54,  0xB9,  0x54,  0x84,  0x80,
+  0x19,  0xE4,  0x20,  0x00,  0xB2,  0x13,  0x85,  0x80,  0x81,  0x48,  0x66,  0x12,  0x04,  0x80,  0x18,  0xE4,
+  0x08,  0x00,  0x58,  0x13,  0x1F,  0x80,  0x08,  0x44,  0xC8,  0x44,  0x9F,  0x12,  0x1F,  0x40,  0x34,  0x91,
+  0xB6,  0x91,  0x44,  0x55,  0xE5,  0x55,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,  0xBB,  0x55,  0x82,  0x81,
+  0xC0,  0x55,  0x48,  0xF4,  0x0F,  0x00,  0x5A,  0xF0,  0x16,  0x08,  0x4A,  0xE4,  0x17,  0x00,  0xD5,  0xF0,
+  0xF6,  0x07,  0x02,  0xF6,  0x0F,  0x00,  0x02,  0xF4,  0x02,  0x00,  0x02,  0xEA,  0xB8,  0x00,  0x04,  0x91,
+  0x86,  0x91,  0x02,  0x4B,  0x2C,  0x90,  0x08,  0x50,  0x2E,  0x90,  0x0A,  0x50,  0x2C,  0x51,  0xAE,  0x51,
+  0x00,  0xF2,  0xB2,  0x10,  0x38,  0x54,  0x00,  0xF2,  0xB0,  0x0D,  0x56,  0x10,  0x34,  0x91,  0xB6,  0x91,
+  0x0C,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x41,  0x12,  0x0C,  0x91,  0x8E,  0x91,  0x04,  0x80,
+  0x18,  0xE4,  0xF7,  0x00,  0x04,  0x40,  0x30,  0x90,  0xB2,  0x90,  0x36,  0x10,  0x02,  0x80,  0x48,  0xE4,
+  0x10,  0x00,  0x31,  0x12,  0x82,  0xE7,  0x10,  0x00,  0x84,  0x80,  0x19,  0xE4,  0x20,  0x00,  0x10,  0x13,
+  0x0C,  0x90,  0x8E,  0x90,  0x5D,  0xF0,  0x74,  0x07,  0x0C,  0x58,  0x8D,  0x58,  0x00,  0xF0,  0x60,  0x07,
+  0x38,  0x54,  0xB9,  0x54,  0x19,  0x80,  0xF1,  0x10,  0x3A,  0x55,  0x19,  0x81,  0xBB,  0x55,  0x10,  0x90,
+  0x92,  0x90,  0x10,  0x58,  0x91,  0x58,  0x14,  0x59,  0x95,  0x59,  0x00,  0xF0,  0x60,  0x07,  0x04,  0x80,
+  0x18,  0xE4,  0x20,  0x00,  0x06,  0x12,  0x6C,  0x19,  0x19,  0x41,  0x7C,  0x10,  0x6C,  0x19,  0x0C,  0x51,
+  0xED,  0x19,  0x8E,  0x51,  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFF,  0x02,  0x13,  0x6A,  0x10,  0x01,  0x58,
+  0xD2,  0xF0,  0xBC,  0x08,  0x76,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x0A,  0x12,  0x00,  0xFC,  0x22,  0x01,
+  0x18,  0xF4,  0x01,  0x00,  0x06,  0x13,  0x9E,  0xE7,  0x16,  0x00,  0x4C,  0x10,  0xD1,  0xF0,  0xC6,  0x08,
+  0x9E,  0xE7,  0x17,  0x00,  0x42,  0x10,  0xD0,  0xF0,  0xD0,  0x08,  0x9E,  0xE7,  0x19,  0x00,  0x38,  0x10,
+  0xCF,  0xF0,  0xDA,  0x08,  0x9E,  0xE7,  0x20,  0x00,  0x2E,  0x10,  0xCE,  0xF0,  0xE4,  0x08,  0x9E,  0xE7,
+  0x21,  0x00,  0x24,  0x10,  0xCD,  0xF0,  0xEE,  0x08,  0x9E,  0xE7,  0x22,  0x00,  0x1A,  0x10,  0xCC,  0xF0,
+  0x00,  0x09,  0x84,  0x80,  0x19,  0xE4,  0x04,  0x00,  0x06,  0x12,  0x9E,  0xE7,  0x12,  0x00,  0x08,  0x10,
+  0xCB,  0xF0,  0x08,  0x09,  0x9E,  0xE7,  0x24,  0x00,  0xB1,  0xF0,  0x08,  0x09,  0x05,  0xF0,  0x1A,  0x09,
+  0x09,  0xF0,  0x20,  0x09,  0x1E,  0xF0,  0xF8,  0x09,  0xE4,  0x10,  0x00,  0xF2,  0x5C,  0x0B,  0xE9,  0x10,
+  0x9C,  0x32,  0x82,  0xE7,  0x20,  0x00,  0x32,  0x1C,  0xE9,  0x09,  0x00,  0xF2,  0x0E,  0x11,  0x85,  0xF0,
+  0xFE,  0x09,  0x69,  0x08,  0x01,  0xF0,  0x40,  0x09,  0x1E,  0xF0,  0xF8,  0x09,  0x00,  0xF0,  0x34,  0x09,
+  0x30,  0x44,  0x06,  0x12,  0x9E,  0xE7,  0x42,  0x00,  0xB8,  0x10,  0x04,  0xF6,  0x01,  0x00,  0xB3,  0x45,
+  0x74,  0x12,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x22,  0x13,  0x4B,  0xE4,  0x02,  0x00,  0x36,  0x12,
+  0x4B,  0xE4,  0x28,  0x00,  0xAC,  0x13,  0x00,  0xF2,  0xB8,  0x11,  0x00,  0xF2,  0xC4,  0x11,  0x03,  0xF6,
+  0xD0,  0x00,  0xFA,  0x14,  0x82,  0xE7,  0x01,  0x00,  0x00,  0xF0,  0x80,  0x01,  0x9E,  0xE7,  0x44,  0x00,
+  0x4B,  0xE4,  0x02,  0x00,  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x76,  0x10,  0x00,  0xF2,  0x9E,  0x0D,
+  0x03,  0xE6,  0x02,  0x00,  0x6C,  0x10,  0x00,  0xF2,  0x9E,  0x0D,  0x19,  0x82,  0x34,  0x46,  0x0A,  0x13,
+  0x03,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x43,  0x00,  0x68,  0x10,  0x04,  0x80,  0x30,  0xE4,  0x20,  0x00,
+  0x04,  0x40,  0x00,  0xF2,  0xB8,  0x11,  0x00,  0xF2,  0xC4,  0x11,  0x82,  0xE7,  0x01,  0x00,  0x06,  0xF7,
+  0x02,  0x00,  0x00,  0xF0,  0x08,  0x03,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x06,  0x12,  0x03,  0xE6,
+  0x02,  0x00,  0x3E,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x3A,  0x12,  0x04,  0x80,  0x18,  0xE4,
+  0xFD,  0x00,  0x04,  0x40,  0x1C,  0x1C,  0x9D,  0xF0,  0xE6,  0x09,  0x1C,  0x1C,  0x9D,  0xF0,  0xEC,  0x09,
+  0xC1,  0x10,  0x9E,  0xE7,  0x13,  0x00,  0x0A,  0x10,  0x9E,  0xE7,  0x41,  0x00,  0x04,  0x10,  0x9E,  0xE7,
+  0x24,  0x00,  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0xD5,  0xF0,  0x8A,  0x02,  0x04,  0xE6,  0x04,  0x00,
+  0x06,  0x10,  0x04,  0xE6,  0x04,  0x00,  0x9D,  0x41,  0x1C,  0x42,  0x9F,  0xE7,  0x00,  0x00,  0x06,  0xF7,
+  0x02,  0x00,  0x03,  0xF6,  0xE0,  0x00,  0x3C,  0x14,  0x44,  0x58,  0x45,  0x58,  0x00,  0xF2,  0xF2,  0x0D,
+  0x00,  0xF2,  0x7A,  0x10,  0x00,  0xF2,  0xC2,  0x0F,  0x3C,  0x14,  0x1E,  0x1C,  0x00,  0xF0,  0x80,  0x01,
+  0x12,  0x1C,  0x22,  0x1C,  0xD2,  0x14,  0x00,  0xF0,  0x72,  0x01,  0x83,  0x59,  0x03,  0xDC,  0x73,  0x57,
+  0x80,  0x5D,  0x00,  0x16,  0x83,  0x59,  0x03,  0xDC,  0x38,  0x54,  0x70,  0x57,  0x33,  0x54,  0x3B,  0x54,
+  0x80,  0x5D,  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x38,  0x54,  0x00,  0xCC,  0x00,  0x16,  0x03,  0x57,
+  0x83,  0x59,  0x00,  0x4C,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,  0x01,  0x00,  0x0E,  0x12,  0x48,  0xE4,
+  0x05,  0x00,  0x08,  0x12,  0x00,  0xF2,  0xB8,  0x11,  0x00,  0xF2,  0xC4,  0x11,  0xC1,  0x5A,  0x3A,  0x55,
+  0x02,  0xEC,  0xB5,  0x00,  0x45,  0x59,  0x00,  0xF2,  0xF2,  0x0D,  0x83,  0x58,  0x30,  0xE7,  0x00,  0x00,
+  0x10,  0x4D,  0x30,  0xE7,  0x40,  0x00,  0x10,  0x4F,  0x38,  0x90,  0xBA,  0x90,  0x10,  0x5C,  0x80,  0x5C,
+  0x83,  0x5A,  0x10,  0x4E,  0x04,  0xEA,  0xB5,  0x00,  0x43,  0x5B,  0x03,  0xF4,  0xE0,  0x00,  0x83,  0x59,
+  0x04,  0xCC,  0x01,  0x4A,  0x0A,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF2,  0x0D,  0x00,  0xF2,  0x34,  0x10,
+  0x00,  0x16,  0x08,  0x1C,  0x00,  0xFC,  0xAC,  0x00,  0x06,  0x58,  0x67,  0x18,  0x18,  0xF4,  0x8F,  0xE1,
+  0x01,  0xFC,  0xAE,  0x00,  0x19,  0xF4,  0x70,  0x1E,  0xB0,  0x54,  0x07,  0x58,  0x00,  0xFC,  0xB0,  0x00,
+  0x08,  0x58,  0x00,  0xFC,  0xB2,  0x00,  0x09,  0x58,  0x0A,  0x1C,  0x00,  0xE6,  0x0F,  0x00,  0x00,  0xEA,
+  0xB9,  0x00,  0x38,  0x54,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFA,  0xB6,  0x00,  0x18,  0x1C,  0x14,  0x1C,
+  0x10,  0x1C,  0x32,  0x1C,  0x12,  0x1C,  0x00,  0x16,  0x3E,  0x57,  0x0C,  0x14,  0x0E,  0x47,  0x07,  0xE6,
+  0x10,  0x00,  0xCE,  0x47,  0xF5,  0x13,  0x00,  0x16,  0x00,  0xF2,  0x9E,  0x0D,  0x02,  0x4B,  0x03,  0xF6,
+  0xE0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x01,  0x48,  0x20,  0x12,  0x44,  0x58,  0x45,  0x58,  0x9E,  0xE7,
+  0x15,  0x00,  0x9C,  0xE7,  0x04,  0x00,  0x00,  0xF2,  0xF2,  0x0D,  0x00,  0xF2,  0x7A,  0x10,  0x00,  0xF2,
+  0xC2,  0x0F,  0x00,  0xF2,  0x76,  0x0A,  0x1E,  0x1C,  0xD5,  0x10,  0x00,  0x16,  0x69,  0x08,  0x48,  0xE4,
+  0x04,  0x00,  0x64,  0x12,  0x48,  0xE4,  0x02,  0x00,  0x20,  0x12,  0x48,  0xE4,  0x03,  0x00,  0x1A,  0x12,
+  0x48,  0xE4,  0x08,  0x00,  0x14,  0x12,  0x48,  0xE4,  0x01,  0x00,  0xF0,  0x12,  0x48,  0xE4,  0x07,  0x00,
+  0x12,  0x12,  0x01,  0xE6,  0x07,  0x00,  0x00,  0xF2,  0x4A,  0x0D,  0x00,  0xF2,  0x0E,  0x11,  0x05,  0xF0,
+  0x5C,  0x0B,  0x00,  0x16,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x99,  0x00,  0x02,  0x80,  0x48,  0xE4,
+  0x03,  0x00,  0xB9,  0x12,  0x48,  0xE4,  0x06,  0x00,  0xB3,  0x12,  0x01,  0xE6,  0x06,  0x00,  0x00,  0xF2,
+  0x4A,  0x0D,  0x00,  0xF2,  0x0E,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,  0x01,  0xF0,
+  0x18,  0x0A,  0x00,  0xF0,  0xFE,  0x09,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,  0x10,  0x00,  0x1C,  0x12,
+  0x82,  0xE7,  0x08,  0x00,  0x3C,  0x56,  0x03,  0x82,  0x00,  0xF2,  0xDE,  0x0D,  0x30,  0xE7,  0x08,  0x00,
+  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x80,  0x01,  0x6C,  0x19,  0xED,  0x19,
+  0x5D,  0xF0,  0xD0,  0x0B,  0x44,  0x55,  0xE5,  0x55,  0x59,  0xF0,  0x4E,  0x0C,  0x04,  0x55,  0xA5,  0x55,
+  0x1F,  0x80,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,  0x49,  0x44,  0x2E,  0x13,  0x01,  0xEC,
+  0xB8,  0x00,  0x41,  0xE4,  0x02,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x49,  0xE4,  0x11,  0x00,  0x59,  0xF0,
+  0x2A,  0x0C,  0x01,  0xE6,  0x17,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x02,  0x4B,  0x88,  0x90,  0xAC,  0x50,
+  0x8A,  0x90,  0xAE,  0x50,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,  0x10,  0x44,  0x02,  0x4B,
+  0x1F,  0x40,  0xC0,  0x44,  0x00,  0xF2,  0xB0,  0x0D,  0x04,  0x55,  0xA5,  0x55,  0x9F,  0x10,  0x0C,  0x51,
+  0x8E,  0x51,  0x30,  0x90,  0xB2,  0x90,  0x00,  0x56,  0xA1,  0x56,  0x30,  0x50,  0xB2,  0x50,  0x34,  0x90,
+  0xB6,  0x90,  0x40,  0x56,  0xE1,  0x56,  0x34,  0x50,  0xB6,  0x50,  0x65,  0x10,  0xB1,  0xF0,  0x6C,  0x0C,
+  0x85,  0xF0,  0xC6,  0x0B,  0xE9,  0x09,  0x4B,  0xE4,  0x03,  0x00,  0x78,  0x12,  0x4B,  0xE4,  0x02,  0x00,
+  0x01,  0x13,  0xB1,  0xF0,  0x82,  0x0C,  0x85,  0xF0,  0xC6,  0x0B,  0x69,  0x08,  0x48,  0xE4,  0x03,  0x00,
+  0xD5,  0xF0,  0x82,  0x0B,  0x00,  0xF2,  0x0E,  0x11,  0x85,  0xF0,  0xC6,  0x0B,  0xE8,  0x09,  0x3C,  0x56,
+  0x00,  0xFC,  0x20,  0x01,  0x98,  0x57,  0x02,  0x13,  0xBB,  0x45,  0x4B,  0xE4,  0x00,  0x00,  0x08,  0x12,
+  0x03,  0xE6,  0x01,  0x00,  0x04,  0xF6,  0x00,  0x80,  0xA8,  0x14,  0xD2,  0x14,  0x30,  0x1C,  0x02,  0x80,
+  0x48,  0xE4,  0x03,  0x00,  0x10,  0x13,  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,  0x02,  0x13,  0x4C,  0x1C,
+  0x3E,  0x1C,  0x00,  0xF0,  0x8A,  0x0B,  0x00,  0xFC,  0x24,  0x01,  0xB0,  0x57,  0x00,  0xFA,  0x24,  0x01,
+  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,  0x8A,  0x0B,  0x00,  0xF2,  0x88,  0x0E,
+  0x00,  0xF0,  0x8A,  0x0B,  0xB1,  0xF0,  0xF4,  0x0C,  0x85,  0xF0,  0x82,  0x0B,  0x69,  0x08,  0x48,  0xE4,
+  0x01,  0x00,  0xD5,  0xF0,  0x82,  0x0B,  0xFC,  0x14,  0x42,  0x58,  0x6C,  0x14,  0x80,  0x14,  0x30,  0x1C,
+  0x4A,  0xF4,  0x02,  0x00,  0x55,  0xF0,  0x82,  0x0B,  0x4A,  0xF4,  0x01,  0x00,  0x0E,  0x12,  0x02,  0x80,
+  0x48,  0xE4,  0x03,  0x00,  0x06,  0x13,  0x3E,  0x1C,  0x00,  0xF0,  0x8A,  0x0B,  0x00,  0xFC,  0xB6,  0x00,
+  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,
+  0x8A,  0x0B,  0x00,  0xF2,  0xB6,  0x0E,  0x00,  0xF0,  0x8A,  0x0B,  0x4C,  0x1C,  0xB1,  0xF0,  0x4C,  0x0D,
+  0x85,  0xF0,  0x58,  0x0D,  0x69,  0x08,  0xF3,  0x10,  0x86,  0xF0,  0x60,  0x0D,  0x4E,  0x1C,  0x89,  0x48,
+  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,
+  0xFF,  0x7F,  0x30,  0x56,  0x00,  0x5C,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,
+  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x30,  0x56,  0x00,  0x5C,  0x00,  0x16,  0x00,  0xF6,
+  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x0B,  0x58,  0x00,  0x16,  0x03,  0xF6,
+  0x24,  0x01,  0x00,  0xF2,  0x54,  0x0A,  0x03,  0xF6,  0xB6,  0x00,  0x00,  0xF2,  0x54,  0x0A,  0x00,  0x16,
+  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,  0x18,  0xF4,  0xFF,  0x00,  0x00,  0x54,  0x00,  0x54,  0x00,  0x54,
+  0x00,  0xF4,  0x08,  0x00,  0xE1,  0x18,  0x80,  0x54,  0x03,  0x58,  0x00,  0xDD,  0x01,  0xDD,  0x02,  0xDD,
+  0x03,  0xDC,  0x02,  0x4B,  0x30,  0x50,  0xB2,  0x50,  0x34,  0x51,  0xB6,  0x51,  0x00,  0x16,  0x45,  0x5A,
+  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,  0x05,  0xF4,  0x02,  0x12,  0x83,  0x5A,
+  0x00,  0x16,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,  0x05,  0xF4,  0x00,  0x12,
+  0x83,  0x5A,  0x00,  0x16,  0x38,  0x54,  0xBB,  0x55,  0x3C,  0x56,  0xBD,  0x56,  0x00,  0xF2,  0x0E,  0x11,
+  0x85,  0xF0,  0x7E,  0x0E,  0xE9,  0x09,  0xC1,  0x59,  0x00,  0xF2,  0x0E,  0x11,  0x85,  0xF0,  0x7E,  0x0E,
+  0xE8,  0x0A,  0x83,  0x55,  0x83,  0x55,  0x4B,  0xF4,  0x90,  0x01,  0x5C,  0xF0,  0x32,  0x0E,  0xBD,  0x56,
+  0x40,  0x10,  0x4B,  0xF4,  0x30,  0x00,  0x59,  0xF0,  0x44,  0x0E,  0x01,  0xF6,  0x0C,  0x00,  0x00,  0xF6,
+  0x01,  0x00,  0x2E,  0x10,  0x02,  0xFC,  0x9C,  0x00,  0x9A,  0x57,  0x14,  0x13,  0x4B,  0xF4,  0x64,  0x00,
+  0x59,  0xF0,  0x60,  0x0E,  0x03,  0xF6,  0x64,  0x00,  0x01,  0xF6,  0x19,  0x00,  0x00,  0xF6,  0x01,  0x00,
+  0x43,  0xF4,  0x33,  0x00,  0x56,  0xF0,  0x72,  0x0E,  0x04,  0xF4,  0x00,  0x01,  0x43,  0xF4,  0x19,  0x00,
+  0xF3,  0x10,  0xB4,  0x56,  0xC3,  0x58,  0x02,  0xFC,  0x9E,  0x00,  0x9A,  0x57,  0x08,  0x13,  0x3C,  0x56,
+  0x00,  0xF6,  0x02,  0x00,  0x00,  0x16,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x0E,  0x11,
+  0x86,  0xF0,  0xB4,  0x0E,  0x09,  0xE7,  0x02,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,  0xB4,  0x0E,
+  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,  0xB4,  0x0E,  0x4E,  0x1C,  0x89,  0x49,
+  0x00,  0xF2,  0x0E,  0x11,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,
+  0xEE,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,  0xEE,  0x0E,  0x09,  0xE7,
+  0x01,  0x00,  0x00,  0xF2,  0x0E,  0x11,  0x86,  0xF0,  0xEE,  0x0E,  0x89,  0x49,  0x00,  0xF2,  0x0E,  0x11,
+  0x86,  0xF0,  0xEE,  0x0E,  0x4E,  0x1C,  0x89,  0x4A,  0x00,  0xF2,  0x0E,  0x11,  0x00,  0x16,  0x3C,  0x56,
+  0x00,  0x16,  0x00,  0xEC,  0x26,  0x01,  0x48,  0xE4,  0x01,  0x00,  0x1E,  0x13,  0x38,  0x44,  0x00,  0xEA,
+  0x26,  0x01,  0x49,  0xF4,  0x00,  0x00,  0x04,  0x12,  0x4E,  0x1C,  0x02,  0x10,  0x4C,  0x1C,  0x01,  0xEC,
+  0x27,  0x01,  0x89,  0x48,  0x00,  0xF2,  0x0E,  0x11,  0x02,  0x14,  0x00,  0x16,  0x85,  0xF0,  0x4E,  0x0F,
+  0x38,  0x54,  0x00,  0xEA,  0x99,  0x00,  0x00,  0xF2,  0x5C,  0x0B,  0x02,  0x80,  0x48,  0xE4,  0x06,  0x00,
+  0x1C,  0x13,  0x00,  0xEC,  0x99,  0x00,  0x48,  0xE4,  0x01,  0x00,  0x0A,  0x12,  0x04,  0x80,  0x30,  0xE4,
+  0x01,  0x00,  0x04,  0x40,  0x08,  0x10,  0x04,  0x80,  0x18,  0xE4,  0xFE,  0x00,  0x04,  0x40,  0x00,  0x16,
+  0x02,  0xF6,  0xE0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x81,  0x48,  0x22,  0x12,  0x00,  0x4E,
+  0x83,  0x5A,  0x90,  0x4C,  0x20,  0xE7,  0x00,  0x00,  0xC3,  0x58,  0x1B,  0xF4,  0xFF,  0x00,  0x83,  0x55,
+  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,  0x8B,  0x55,  0x83,  0x59,  0x00,  0x4E,  0x00,  0x16,
+  0x00,  0x4E,  0x02,  0xF6,  0xF0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x00,  0x4E,  0x83,  0x5A,  0x30,  0xE7,
+  0x00,  0x00,  0x20,  0xE7,  0x00,  0x00,  0x00,  0x16,  0x02,  0xF6,  0xF0,  0x00,  0x02,  0x57,  0x03,  0x59,
+  0x01,  0xCC,  0x00,  0x4E,  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x80,  0x4C,  0xC3,  0x58,  0x1B,  0xF4,
+  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,  0x83,  0x59,  0x00,  0x4E,
+  0x00,  0x16,  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x3A,  0x55,  0x02,  0xCC,  0x45,  0x5A,
+  0x00,  0xF2,  0xF2,  0x0D,  0xC0,  0x5A,  0x40,  0x5C,  0x38,  0x54,  0x00,  0xCD,  0x01,  0xCC,  0x4A,  0x46,
+  0x0A,  0x13,  0x83,  0x59,  0x00,  0x4C,  0x01,  0x48,  0x16,  0x13,  0x0C,  0x10,  0xC5,  0x58,  0x00,  0xF2,
+  0xF2,  0x0D,  0x00,  0x4C,  0x01,  0x48,  0x08,  0x13,  0x05,  0xF6,  0xF0,  0x00,  0x05,  0x57,  0x08,  0x10,
+  0x45,  0x58,  0x00,  0xF2,  0xF2,  0x0D,  0x8D,  0x56,  0x83,  0x5A,  0x80,  0x4C,  0x05,  0x17,  0x00,  0x16,
+  0x02,  0x4B,  0x06,  0xF7,  0x04,  0x00,  0x62,  0x0B,  0x03,  0x82,  0x00,  0xF2,  0xDE,  0x0D,  0x02,  0x80,
+  0x00,  0x4C,  0x45,  0xF4,  0x02,  0x00,  0x52,  0x14,  0x06,  0xF7,  0x02,  0x00,  0x06,  0x14,  0x00,  0xF2,
+  0x50,  0x0F,  0x00,  0x16,  0x02,  0x4B,  0x01,  0xF6,  0xFF,  0x00,  0x38,  0x1C,  0x05,  0xF4,  0x04,  0x00,
+  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x1D,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,  0x4A,  0x10,  0x9C,  0x14,
+  0x01,  0x48,  0x1C,  0x13,  0x0E,  0xF7,  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,  0xAF,  0x19,  0x03,  0x42,
+  0x45,  0xF4,  0x02,  0x00,  0x83,  0x5A,  0x02,  0xCC,  0x02,  0x41,  0x45,  0xF4,  0x02,  0x00,  0x00,  0x16,
+  0x91,  0x44,  0xD5,  0xF0,  0x3A,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x01,  0xF6,  0xFF,  0x00,  0x38,  0x1C,
+  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x0E,  0xF7,  0x3C,  0x00,  0x03,  0xF7,
+  0x04,  0x00,  0x0F,  0x79,  0x1C,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,  0x98,  0x10,  0x4E,  0x14,  0x01,  0x48,
+  0x06,  0x13,  0x45,  0xF4,  0x04,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,  0x7E,  0x10,  0x00,  0xF0,
+  0x9E,  0x02,  0x02,  0xF6,  0xFF,  0x00,  0x38,  0x1C,  0x2C,  0xBC,  0xAE,  0xBC,  0xE2,  0x08,  0x00,  0xEC,
+  0xB8,  0x00,  0x02,  0x48,  0x1D,  0xF7,  0x80,  0x00,  0xB8,  0xF0,  0xC8,  0x10,  0x1E,  0x14,  0x01,  0x48,
+  0x0E,  0x13,  0x0E,  0xF7,  0x80,  0x00,  0x38,  0x54,  0x03,  0x58,  0xAF,  0x19,  0x82,  0x48,  0x00,  0x16,
+  0x82,  0x48,  0x12,  0x45,  0xD5,  0xF0,  0xB6,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x39,  0xF0,  0xF4,  0x10,
+  0x38,  0x44,  0x00,  0x16,  0x7E,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x04,  0x13,  0x61,  0x18,  0x00,  0x16,
+  0x38,  0x1C,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xF1,  0x12,  0xE3,  0x10,  0x30,  0x44,
+  0x30,  0x44,  0x30,  0x44,  0xB1,  0xF0,  0x14,  0x11,  0x00,  0x16,  0x3E,  0x57,  0x03,  0xF6,  0xE0,  0x00,
+  0x03,  0x57,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x6A,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF2,  0x0D,
+  0x02,  0x4B,  0x70,  0x14,  0x34,  0x13,  0x02,  0x80,  0x48,  0xE4,  0x08,  0x00,  0x18,  0x12,  0x9C,  0xE7,
+  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,  0x00,  0xF2,  0xC2,  0x0F,  0x00,  0xF2,  0x76,  0x0A,  0x1E,  0x1C,
+  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x30,  0xE4,  0x10,  0x00,  0x04,  0x40,  0x00,  0xF2,  0xDE,  0x0D,
+  0x20,  0xE7,  0x01,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x04,  0xDC,  0x01,  0x4A,  0x24,  0x12,
+  0x45,  0x5A,  0x00,  0xF2,  0xF2,  0x0D,  0x43,  0x5B,  0x06,  0xEC,  0x98,  0x00,  0x00,  0xF2,  0x34,  0x10,
+  0xC6,  0x59,  0x20,  0x14,  0x0A,  0x13,  0x00,  0xF2,  0xC2,  0x0F,  0x00,  0xF2,  0x10,  0x10,  0xA7,  0x10,
+  0x83,  0x5A,  0xD7,  0x10,  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,  0x5A,  0xF0,  0x1C,  0x11,
+  0xB9,  0x54,  0x00,  0x16,  0x14,  0x90,  0x96,  0x90,  0x02,  0xFC,  0xA8,  0x00,  0x03,  0xFC,  0xAA,  0x00,
+  0x48,  0x55,  0x02,  0x13,  0xC9,  0x55,  0x00,  0x16,  0x00,  0xEC,  0xBA,  0x00,  0x10,  0x44,  0x00,  0xEA,
+  0xBA,  0x00,  0x00,  0x16,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x64,  0x0A,  0x10,  0x44,  0x00,  0x4C,
+  0x00,  0x16 };
+
+unsigned short _adv_mcode_size ASC_INITDATA =
+    sizeof(_adv_mcode_buf); /* 0x11D2 */
+unsigned long  _adv_mcode_chksum ASC_INITDATA = 0x0347D07AUL;
+
+/* a_init.c */
+/*
+ * EEPROM Configuration.
+ *
+ * All drivers should use this structure to set the default EEPROM
+ * configuration. The BIOS now uses this structure when it is built.
+ * Additional structure information can be found in a_condor.h where
+ * the structure is defined.
+ */
+STATIC ADVEEP_CONFIG
+Default_EEPROM_Config ASC_INITDATA = {
+    ADV_EEPROM_BIOS_ENABLE,     /* cfg_msw */
+    0x0000,                     /* cfg_lsw */
+    0xFFFF,                     /* disc_enable */
+    0xFFFF,                     /* wdtr_able */
+    0xFFFF,                     /* sdtr_able */
+    0xFFFF,                     /* start_motor */
+    0xFFFF,                     /* tagqng_able */
+    0xFFFF,                     /* bios_scan */
+    0,                          /* scam_tolerant */
+    7,                          /* adapter_scsi_id */
+    0,                          /* bios_boot_delay */
+    3,                          /* scsi_reset_delay */
+    0,                          /* bios_id_lun */
+    0,                          /* termination */
+    0,                          /* reserved1 */
+    0xFFEF,                     /* bios_ctrl */
+    0xFFFF,                     /* ultra_able */
+    0,                          /* reserved2 */
+    ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
+    ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
+    0,                          /* dvc_cntl */
+    0,                          /* bug_fix */
+    0,                          /* serial_number_word1 */
+    0,                          /* serial_number_word2 */
+    0,                          /* serial_number_word3 */
+    0,                          /* check_sum */
+    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
+    0,                          /* dvc_err_code */
+    0,                          /* adv_err_code */
+    0,                          /* adv_err_addr */
+    0,                          /* saved_dvc_err_code */
+    0,                          /* saved_adv_err_code */
+    0,                          /* saved_adv_err_addr */
+    0                           /* num_of_err */
+};
+
+/*
+ * Initialize the ADV_DVC_VAR structure.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
+ * For a non-fatal error return a warning code. If there are no warnings
+ * then 0 is returned.
+ */
+ASC_INITFUNC(
+int
+AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
+)
+{
+    ushort      warn_code;
+    AdvPortAddr iop_base;
+    uchar       pci_cmd_reg;
+    int         status;
+
+    warn_code = 0;
+    asc_dvc->err_code = 0;
+    iop_base = asc_dvc->iop_base;
+
+    /*
+     * PCI Command Register
+     */
+
+    if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
+                            AscPCIConfigCommandRegister))
+         & AscPCICmdRegBits_BusMastering)
+        != AscPCICmdRegBits_BusMastering)
+    {
+        pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
+
+        DvcAdvWritePCIConfigByte(asc_dvc,
+                AscPCIConfigCommandRegister, pci_cmd_reg);
+
+        if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
+             & AscPCICmdRegBits_BusMastering)
+            != AscPCICmdRegBits_BusMastering)
+        {
+            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
+        }
+    }
+
+    /*
+     * PCI Latency Timer
+     *
+     * If the "latency timer" register is 0x20 or above, then we don't need
+     * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
+     * comes up less than 0x20).
+     */
+    if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
+        DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
+        if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
+        {
+            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
+        }
+    }
+
+    /*
+     * Save the state of the PCI Configuration Command Register
+     * "Parity Error Response Control" Bit. If the bit is clear (0),
+     * in AdvInitAsc3550Driver() tell the microcode to ignore DMA
+     * parity errors.
+     */
+    asc_dvc->cfg->control_flag = 0;
+    if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
+         & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
+    {
+        asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
+    }
+
+    asc_dvc->cur_host_qng = 0;
+
+    asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
+      ADV_LIB_VERSION_MINOR;
+    asc_dvc->cfg->chip_version =
+      AdvGetChipVersion(iop_base, asc_dvc->bus_type);
+
+    /*
+     * Reset the chip to start and allow register writes.
+     */
+    if (AdvFindSignature(iop_base) == 0)
+    {
+        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
+        return ADV_ERROR;
+    }
+    else {
+
+        AdvResetChip(asc_dvc);
+
+        if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR)
+        {
+            return ADV_ERROR;
+        }
+        warn_code |= status;
+
+        /*
+         * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
+         * Resets should be performed.
+         */
+        if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
+        {
+            AdvResetSCSIBus(asc_dvc);
+        }
+    }
+
+    return warn_code;
+}
+
+/*
+ * Initialize the ASC3550.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
+ * For a non-fatal error return a warning code. If there are no warnings
+ * then 0 is returned.
+ */
+ASC_INITFUNC(
+int
+AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
+)
+{
+    AdvPortAddr iop_base;
+    ushort      warn_code;
+    ulong       sum;
+    int         begin_addr;
+    int         end_addr;
+    int         code_sum;
+    int         word;
+    int         rql_addr;                   /* RISC Queue List address */
+    int         i;
+    ushort      scsi_cfg1;
+    uchar       biosmem[ASC_MC_BIOSLEN];    /* BIOS RISC Memory 0x40-0x8F. */
+
+    /* If there is already an error, don't continue. */
+    if (asc_dvc->err_code != 0)
+    {
+        return ADV_ERROR;
+    }
+
+    warn_code = 0;
+    iop_base = asc_dvc->iop_base;
+
+    /*
+     * Save the RISC memory BIOS region before writing the microcode.
+     * The BIOS may already be loaded and using its RISC LRAM region
+     * so its region must be saved and restored.
+     *
+     * Note: This code makes the assumption, which is currently true,
+     * that a chip reset does not clear RISC LRAM.
+     */
+    for (i = 0; i < ASC_MC_BIOSLEN; i++)
+    {
+        AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
+    }
+
+    /*
+     * Load the Microcode
+     *
+     * Write the microcode image to RISC memory starting at address 0.
+     */
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
+    for (word = 0; word < _adv_mcode_size; word += 2)
+    {
+        AdvWriteWordAutoIncLram(iop_base,
+            *((ushort *) (&_adv_mcode_buf[word])));
+    }
+
+    /*
+     * Clear the rest of Condor's Internal RAM (8KB).
+     */
+    for (; word < ADV_CONDOR_MEMSIZE; word += 2)
+    {
+        AdvWriteWordAutoIncLram(iop_base, 0);
+    }
+
+    /*
+     * Verify the microcode checksum.
+     */
+    sum = 0;
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
+    for (word = 0; word < _adv_mcode_size; word += 2)
+    {
+        sum += AdvReadWordAutoIncLram(iop_base);
+    }
+
+    if (sum != _adv_mcode_chksum)
+    {
+        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
+        return ADV_ERROR;
+    }
+
+    /*
+     * Restore the RISC memory BIOS region.
+     */
+    for (i = 0; i < ASC_MC_BIOSLEN; i++)
+    {
+        AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
+    }
+
+    /*
+     * Calculate and write the microcode code checksum to the microcode
+     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).  
+     */
+    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
+    AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
+    code_sum = 0;
+    for (word = begin_addr; word < end_addr; word += 2)
+    {
+        code_sum += *((ushort *) (&_adv_mcode_buf[word]));
+    }
+    AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
+
+    /*
+     * Read microcode version and date.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
+    AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
+
+    /*
+     * Initialize microcode operating variables
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID,
+                       asc_dvc->chip_scsi_id);
+
+    /*
+     * If the PCI Configuration Command Register "Parity Error Response
+     * Control" Bit was clear (0), then set the microcode variable
+     * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
+     * to ignore DMA parity errors.
+     */
+    if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
+    {
+        /* 
+         * Note: Don't remove the use of a temporary variable in
+         * the following code, otherwise the Microsoft C compiler
+         * will turn the following lines into a no-op.
+         */
+        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+        word |= CONTROL_FLAG_IGNORE_PERR;
+        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+    }
+
+    /*
+     * Set default microcode operating variables for WDTR, SDTR, and
+     * command tag queuing based on the EEPROM configuration values.
+     *
+     * These ADV_DVC_VAR fields and the microcode variables will be
+     * changed in AdvInquiryHandling() if it is found a device is
+     * incapable of a particular feature.
+     */
+
+    /*
+     * Set the microcode ULTRA target mask from EEPROM value. The
+     * SDTR target mask overrides the ULTRA target mask in the
+     * microcode so it is safe to set this value without determining
+     * whether the device supports SDTR.
+     * 
+     * Note: There is no way to know whether a device supports ULTRA
+     * speed without attempting a SDTR ULTRA speed negotiation with
+     * the device. The device will reject the speed if it does not
+     * support it by responding with an SDTR message containing a
+     * slower speed.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able);
+    AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
+
+
+    /*
+     * Set SCSI_CFG0 Microcode Default Value.
+     *
+     * The microcode will set the SCSI_CFG0 register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
+        PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
+  
+    /*
+     * Determine SCSI_CFG1 Microcode Default Value.
+     *
+     * The microcode will set the SCSI_CFG1 register using this value
+     * after it is started below.
+     */
+
+    /* Read current SCSI_CFG1 Register value. */
+    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
+
+    /*
+     * If all three connectors are in use, return an error.
+     */
+    if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
+        (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
+    {
+        asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
+        return ADV_ERROR;
+    }
+
+    /*
+     * If the internal narrow cable is reversed all of the SCSI_CTRL
+     * register signals will be set. Check for and return an error if
+     * this condition is found.
+     */
+    if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
+    {
+        asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
+        return ADV_ERROR;
+    }
+
+    /*
+     * If this is a differential board and a single-ended device
+     * is attached to one of the connectors, return an error.
+     */
+    if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
+    {
+        asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
+        return ADV_ERROR;
+    }
+
+    /*
+     * If automatic termination control is enabled, then set the
+     * termination value based on a table listed in a_condor.h.
+     *
+     * If manual termination was specified with an EEPROM setting
+     * then 'termination' was set-up in AdvInitFromEEP() and
+     * is ready to be 'ored' into SCSI_CFG1.
+     */
+    if (asc_dvc->cfg->termination == 0)
+    {
+        /*
+         * The software always controls termination by setting TERM_CTL_SEL.
+         * If TERM_CTL_SEL were set to 0, the hardware would set termination.
+         */
+        asc_dvc->cfg->termination |= TERM_CTL_SEL;
+
+        switch(scsi_cfg1 & CABLE_DETECT)
+        {
+            /* TERM_CTL_H: on, TERM_CTL_L: on */
+            case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
+                asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
+                break;
+
+            /* TERM_CTL_H: on, TERM_CTL_L: off */
+            case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
+                asc_dvc->cfg->termination |= TERM_CTL_H;
+                break;
+
+            /* TERM_CTL_H: off, TERM_CTL_L: off */
+            case 0x2: case 0x6:
+                break;
+        }
+    }
+
+    /*
+     * Clear any set TERM_CTL_H and TERM_CTL_L bits.
+     */
+    scsi_cfg1 &= ~TERM_CTL;
+
+    /*
+     * Invert the TERM_CTL_H and TERM_CTL_L bits and then
+     * set 'scsi_cfg1'. The TERM_POL bit does not need to be
+     * referenced, because the hardware internally inverts
+     * the Termination High and Low bits if TERM_POL is set.
+     */
+    scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
+
+    /*
+     * Set SCSI_CFG1 Microcode Default Value
+     *
+     * Set filter value and possibly modified termination control
+     * bits in the Microcode SCSI_CFG1 Register Value.
+     *
+     * The microcode will set the SCSI_CFG1 register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
+                       FLTR_11_TO_20NS | scsi_cfg1);
+
+    /*
+     * Set SEL_MASK Microcode Default Value
+     *
+     * The microcode will set the SEL_MASK register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
+                        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
+
+    /*
+     * Link all the RISC Queue Lists together in a doubly-linked
+     * NULL terminated list.
+     *
+     * Skip the NULL (0) queue which is not used.
+     */
+    for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE + ASC_MC_RISC_Q_LIST_SIZE;
+         i < ASC_MC_RISC_Q_TOTAL_CNT;
+         i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE)
+    {
+        /*
+         * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers
+         * in a one word write and set the state (RQL_STATE) to free.
+         */
+        AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8)));
+        AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
+    }
+
+    /*
+     * Set the Host and RISC Queue List pointers.
+     *
+     * Both sets of pointers are initialized with the same values:
+     * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF).
+     */
+    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST);
+    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST);
+
+    AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST);
+    AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST);
+
+    /*
+     * Finally, set up the last RISC Queue List (255) with
+     * a NULL forward pointer.
+     */
+    AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8)));
+    AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
+
+    AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
+         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
+
+    /* 
+     * Note: Don't remove the use of a temporary variable in
+     * the following code, otherwise the Microsoft C compiler
+     * will turn the following lines into a no-op.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
+    AdvWriteWordRegister(iop_base, IOPW_PC, word);
+
+    /* finally, finally, gentlemen, start your engine */
+    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
+ 
+    return warn_code;
+}
+
+/*
+ * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
+ * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
+ * all of this is done.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
+ * For a non-fatal error return a warning code. If there are no warnings
+ * then 0 is returned.
+ *
+ * Note: Chip is stopped on entry.
+ */
+ASC_INITFUNC(
+STATIC int
+AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
+)
+{
+    AdvPortAddr         iop_base;
+    ushort              warn_code;
+    ADVEEP_CONFIG       eep_config;
+    int                 i;
+
+    iop_base = asc_dvc->iop_base;
+
+    warn_code = 0;
+
+    /*
+     * Read the board's EEPROM configuration.
+     *
+     * Set default values if a bad checksum is found.
+     */
+    if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum)
+    {
+        warn_code |= ASC_WARN_EEPROM_CHKSUM;
+
+        /*
+         * Set EEPROM default values.
+         */
+        for (i = 0; i < sizeof(ADVEEP_CONFIG); i++)
+        {
+            *((uchar *) &eep_config + i) =
+                *((uchar *) &Default_EEPROM_Config + i);
+        }
+
+        /*
+         * Assume the 6 byte board serial number that was read
+         * from EEPROM is correct even if the EEPROM checksum
+         * failed.
+         */
+        eep_config.serial_number_word3 =
+            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
+        eep_config.serial_number_word2 =
+            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
+        eep_config.serial_number_word1 =
+            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
+        AdvSetEEPConfig(iop_base, &eep_config);
+    }
+
+    /*
+     * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
+     * EEPROM configuration that was read.
+     *
+     * This is the mapping of EEPROM fields to Adv Library fields.
+     */
+    asc_dvc->wdtr_able = eep_config.wdtr_able;
+    asc_dvc->sdtr_able = eep_config.sdtr_able;
+    asc_dvc->ultra_able = eep_config.ultra_able;
+    asc_dvc->tagqng_able = eep_config.tagqng_able;
+    asc_dvc->cfg->disc_enable = eep_config.disc_enable;
+    asc_dvc->max_host_qng = eep_config.max_host_qng;
+    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
+    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
+    asc_dvc->start_motor = eep_config.start_motor;
+    asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
+    asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay;
+    asc_dvc->bios_ctrl = eep_config.bios_ctrl;
+    asc_dvc->no_scam = eep_config.scam_tolerant;
+    asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
+    asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
+    asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
+
+    /*
+     * Set the host maximum queuing (max. 253, min. 16) and the per device
+     * maximum queuing (max. 63, min. 4).
+     */
+    if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
+    {
+        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
+    } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
+    {
+        /* If the value is zero, assume it is uninitialized. */
+        if (eep_config.max_host_qng == 0)
+        {
+            eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
+        } else
+        {
+            eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
+        }
+    }
+
+    if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
+    {
+        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
+    } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
+    {
+        /* If the value is zero, assume it is uninitialized. */
+        if (eep_config.max_dvc_qng == 0)
+        {
+            eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
+        } else
+        {
+            eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
+        }
+    }
+
+    /*
+     * If 'max_dvc_qng' is greater than 'max_host_qng', then
+     * set 'max_dvc_qng' to 'max_host_qng'.
+     */
+    if (eep_config.max_dvc_qng > eep_config.max_host_qng)
+    {
+        eep_config.max_dvc_qng = eep_config.max_host_qng;
+    }
+
+    /*
+     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng'
+     * values based on possibly adjusted EEPROM values.
+     */
+    asc_dvc->max_host_qng = eep_config.max_host_qng;
+    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
+
+
+    /*
+     * If the EEPROM 'termination' field is set to automatic (0), then set
+     * the ADV_DVC_CFG 'termination' field to automatic also.
+     *
+     * If the termination is specified with a non-zero 'termination'
+     * value check that a legal value is set and set the ADV_DVC_CFG
+     * 'termination' field appropriately.
+     */
+    if (eep_config.termination == 0)
+    {
+        asc_dvc->cfg->termination = 0;    /* auto termination */
+    } else
+    {
+        /* Enable manual control with low off / high off. */
+        if (eep_config.termination == 1)
+        {
+            asc_dvc->cfg->termination = TERM_CTL_SEL;
+
+        /* Enable manual control with low off / high on. */
+        } else if (eep_config.termination == 2)
+        {
+            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
+
+        /* Enable manual control with low on / high on. */
+        } else if (eep_config.termination == 3)
+        {
+            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
+        } else
+        {
+            /*
+             * The EEPROM 'termination' field contains a bad value. Use
+             * automatic termination instead.
+             */
+            asc_dvc->cfg->termination = 0;
+            warn_code |= ASC_WARN_EEPROM_TERMINATION;
+        }
+    }
+
+    return warn_code;
+}
+
+/*
+ * Read EEPROM configuration into the specified buffer.
+ *
+ * Return a checksum based on the EEPROM configuration read.
+ */
+ASC_INITFUNC(
+STATIC ushort
+AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
+)
+{
+    ushort              wval, chksum;
+    ushort              *wbuf;
+    int                 eep_addr;
+
+    wbuf = (ushort *) cfg_buf;
+    chksum = 0;
+
+    for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
+         eep_addr < ASC_EEP_DVC_CFG_END;
+         eep_addr++, wbuf++)
+    {
+        wval = AdvReadEEPWord(iop_base, eep_addr);
+        chksum += wval;
+        *wbuf = wval;
+    }
+    *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+    wbuf++;
+    for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
+         eep_addr < ASC_EEP_MAX_WORD_ADDR;
+         eep_addr++, wbuf++)
+    {
+        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+    }
+    return chksum;
+}
+
+/*
+ * Read the EEPROM from specified location
+ */
+ASC_INITFUNC(
+STATIC ushort
+AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
+)
+{
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
+        ASC_EEP_CMD_READ | eep_word_addr);
+    AdvWaitEEPCmd(iop_base);
+    return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
+}
+
+/*
+ * Wait for EEPROM command to complete
+ */
+ASC_INITFUNC(
+STATIC void
+AdvWaitEEPCmd(AdvPortAddr iop_base)
+)
+{
+    int eep_delay_ms;
+
+    for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++)
+    {
+        if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
+        {
+            break;
+        }
+        DvcSleepMilliSecond(1);
+    }
+    if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
+    {
+        ADV_ASSERT(0);
+    }
+    return;
+}
+
+/*
+ * Write the EEPROM from 'cfg_buf'.
+ */
+ASC_INITFUNC(
+STATIC void
+AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
+)
+{
+    ushort       *wbuf;
+    ushort       addr, chksum;
+
+    wbuf = (ushort *) cfg_buf;
+    chksum = 0;
+
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
+    AdvWaitEEPCmd(iop_base);
+
+    /*
+     * Write EEPROM from word 0 to word 15
+     */
+    for (addr = ASC_EEP_DVC_CFG_BEGIN;
+         addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
+    {
+        chksum += *wbuf;
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+        DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
+    }
+
+    /*
+     * Write EEPROM checksum at word 18
+     */
+    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+    AdvWaitEEPCmd(iop_base);
+    wbuf++;        /* skip over check_sum */
+
+    /*
+     * Write EEPROM OEM name at words 19 to 26 
+     */
+    for (addr = ASC_EEP_DVC_CTL_BEGIN;
+         addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
+    {
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+    }
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
+    AdvWaitEEPCmd(iop_base);
+    return;
+}
+
+/*
+ * This function resets the chip and SCSI bus
+ *
+ * It is up to the caller to add a delay to let the bus settle after
+ * calling this function.
+ *
+ * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in
+ * AdvInitAsc3550Driver(). Here when doing a write to one of these
+ * registers read first and then write.
+ *
+ * Note: A SCSI Bus Reset can not be done until after the EEPROM
+ * configuration is read to determine whether SCSI Bus Resets
+ * should be performed.
+ */
+ASC_INITFUNC(
+STATIC void
+AdvResetChip(ADV_DVC_VAR *asc_dvc)
+)
+{
+    AdvPortAddr    iop_base;
+    ushort         word;
+    uchar          byte;
+
+    iop_base = asc_dvc->iop_base;
+
+    /*
+     * Reset Chip.
+     */
+    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
+    DvcSleepMilliSecond(100);
+    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
+
+    /*
+     * Initialize Chip registers.
+     * 
+     * Note: Don't remove the use of a temporary variable in the following
+     * code, otherwise the Microsoft C compiler will turn the following lines
+     * into a no-op.
+     */
+    byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG);
+    byte |= RAM_SZ_8KB;
+    AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte);
+
+    word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
+    word &= ~BIG_ENDIAN;
+    AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word);
+
+    /*
+     * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold
+     * of 128 bytes. This register is only accessible to the host.
+     */
+    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
+        START_CTL_EMFU | READ_CMD_MRM);
+}
+
+/* a_advlib.c */
+/*
+ * Description:
+ *      Send a SCSI request to the ASC3550 chip
+ *
+ * If there is no SG list for the request, set 'sg_entry_cnt' to 0.
+ *
+ * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be
+ * called. It is assumed the caller has already initialized 'sg_real_addr'.
+ *
+ * Return:
+ *      ADV_SUCCESS(1) - the request is in the mailbox
+ *      ADV_BUSY(0) - total request count > 253, try later
+ *      ADV_ERROR(-1) - invalid scsi request Q
+ */
+STATIC int
+AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
+                ADV_SCSI_REQ_Q *scsiq)
+{
+    if (scsiq == (ADV_SCSI_REQ_Q *) 0L)
+    {
+        /* 'scsiq' should never be NULL. */
+        ADV_ASSERT(0);
+        return ADV_ERROR;
+    }
+
+    return AdvSendScsiCmd(asc_dvc, scsiq);
+}
+
+/*
+ * Reset SCSI Bus and purge all outstanding requests.
+ *
+ * Return Value:
+ *      ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
+ *
+ * Note: Should always return ADV_TRUE.
+ */
+STATIC int
+AdvResetSB(ADV_DVC_VAR *asc_dvc)
+{
+    int         status;
+
+    status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET, 0L, 0);
+
+    AdvResetSCSIBus(asc_dvc);
+
+    return status;
+}
+
+/*
+ * Reset SCSI Bus and delay.
+ */
+STATIC void
+AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc)
+{
+    AdvPortAddr    iop_base;
+    ushort         scsi_ctrl;
+
+    iop_base = asc_dvc->iop_base;
+
+    /*
+     * The microcode currently sets the SCSI Bus Reset signal while
+     * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above.
+     * But the SCSI Bus Reset Hold Time in the microcode is not deterministic
+     * (it may in fact be for less than the SCSI Spec. minimum of 25 us).
+     * Therefore on return the Adv Library sets the SCSI Bus Reset signal
+     * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater
+     * than 25 us.
+     */
+    scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL);
+    AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
+        scsi_ctrl | ADV_SCSI_CTRL_RSTOUT);
+    DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
+    AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
+        scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT);
+
+    DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
+}
+
+
+/*
+ * Adv Library Interrupt Service Routine
+ *
+ *  This function is called by a driver's interrupt service routine.
+ *  The function disables and re-enables interrupts.
+ *
+ *  When a microcode idle command is completed, the ADV_DVC_VAR
+ *  'idle_cmd_done' field is set to ADV_TRUE.
+ *
+ *  Note: AdvISR() can be called when interrupts are disabled or even
+ *  when there is no hardware interrupt condition present. It will
+ *  always check for completed idle commands and microcode requests.
+ *  This is an important feature that shouldn't be changed because it
+ *  allows commands to be completed from polling mode loops.
+ *
+ * Return:
+ *   ADV_TRUE(1) - interrupt was pending
+ *   ADV_FALSE(0) - no interrupt was pending
+ */
+STATIC int
+AdvISR(ADV_DVC_VAR *asc_dvc)
+{
+    AdvPortAddr                 iop_base;
+    uchar                       int_stat;
+    ushort                      next_done_loc, target_bit;
+    int                         completed_q;
+    int                         flags;
+    ADV_SCSI_REQ_Q              *scsiq;
+    ASC_REQ_SENSE               *sense_data;
+    int                         ret;
+
+    flags = DvcEnterCritical();
+    iop_base = asc_dvc->iop_base;
+
+    if (AdvIsIntPending(iop_base))
+    {
+        ret = ADV_TRUE;
+    } else
+    {
+        ret = ADV_FALSE;
+    }
+
+    /* Reading the register clears the interrupt. */
+    int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
+
+    if (int_stat & ADV_INTR_STATUS_INTRB)
+    {
+        asc_dvc->idle_cmd_done = ADV_TRUE;
+    }
+
+    /*
+     * Notify the driver of a hardware detected SCSI Bus Reset.
+     */
+    if (int_stat & ADV_INTR_STATUS_INTRC)
+    {
+        if (asc_dvc->sbreset_callback != 0)
+        {
+            (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc);
+        }
+    }
+
+    /*
+     * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC
+     * Queue List request. Its forward pointer (RQL_FWD) points to the
+     * current completed RISC Queue List request.
+     */
+    AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc);
+    next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
+        (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD;
+
+    AdvReadByteLram(iop_base, next_done_loc, completed_q);
+
+    /* Loop until all completed Q's are processed. */
+    while (completed_q != ASC_MC_NULL_Q)
+    {
+        AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q);
+
+        next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
+          (completed_q * ASC_MC_RISC_Q_LIST_SIZE);
+
+        /*
+         * Read the ADV_SCSI_REQ_Q virtual address pointer from
+         * the RISC list entry. The microcode has changed the
+         * ADV_SCSI_REQ_Q physical address to its virtual address.
+         *
+         * Refer to comments at the end of AdvSendScsiCmd() for
+         * more information on the RISC list structure.
+         */
+        {
+            ushort lsw, msw;
+            AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw);
+            AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw);
+
+            scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw);
+        }
+        ADV_ASSERT(scsiq != NULL);
+
+        target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
+
+        /*
+         * Clear request microcode control flag.
+         */
+        scsiq->cntl = 0;
+
+        /*
+         * Check Condition handling
+         */
+        if ((scsiq->done_status == QD_WITH_ERROR) &&
+            (scsiq->scsi_status == SS_CHK_CONDITION) &&
+            (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 &&
+            (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN)
+        {
+            /*
+             * Command returned with a check condition and valid
+             * sense data.
+             */
+        }
+        /*
+         * If the command that completed was a SCSI INQUIRY and
+         * LUN 0 was sent the command, then process the INQUIRY
+         * command information for the device.
+         */
+        else if (scsiq->done_status == QD_NO_ERROR &&
+                   scsiq->cdb[0] == SCSICMD_Inquiry &&
+                   scsiq->target_lun == 0)
+        {
+            AdvInquiryHandling(asc_dvc, scsiq);
+        }
+
+        
+        /* Change the RISC Queue List state to free. */
+        AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE);
+
+        /* Get the RISC Queue List forward pointer. */
+        AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q);
+
+        /*
+         * Notify the driver of the completed request by passing
+         * the ADV_SCSI_REQ_Q pointer to its callback function.
+         */
+        ADV_ASSERT(asc_dvc->cur_host_qng > 0);
+        asc_dvc->cur_host_qng--;
+        scsiq->a_flag |= ADV_SCSIQ_DONE;
+        (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq);
+        /*
+         * Note: After the driver callback function is called, 'scsiq'
+         * can no longer be referenced.
+         *
+         * Fall through and continue processing other completed
+         * requests...
+         */
+
+        /*
+         * Disable interrupts again in case the driver inadvertently
+         * enabled interrupts in its callback function.
+         *
+         * The DvcEnterCritical() return value is ignored, because
+         * the 'flags' saved when AdvISR() was first entered will be
+         * used to restore the interrupt flag on exit.
+         */
+        (void) DvcEnterCritical();
+    }
+    DvcLeaveCritical(flags);
+    return ret;
+}
+
+/*
+ * Send an idle command to the chip and wait for completion.
+ *
+ * Interrupts do not have to be enabled on entry.
+ *
+ * Return Values:
+ *   ADV_TRUE - command completed successfully
+ *   ADV_FALSE - command failed
+ */
+STATIC int
+AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
+               ushort idle_cmd,
+               ulong idle_cmd_parameter,
+               int flags)
+{
+    int         last_int_level;
+    ulong       i;
+    AdvPortAddr iop_base;
+    int         ret;
+
+    asc_dvc->idle_cmd_done = 0;
+
+    last_int_level = DvcEnterCritical();
+    iop_base = asc_dvc->iop_base;
+
+    /*
+     * Write the idle command value after the idle command parameter
+     * has been written to avoid a race condition. If the order is not
+     * followed, the microcode may process the idle command before the
+     * parameters have been written to LRAM.
+     */
+    AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter);
+    AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
+    DvcLeaveCritical(last_int_level);
+
+    /*
+     * If the 'flags' argument contains the ADV_NOWAIT flag, then
+     * return with success.
+     */
+    if (flags & ADV_NOWAIT)
+    {
+        return ADV_TRUE;
+    }
+
+    for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++)
+    {
+        /*
+         * 'idle_cmd_done' is set by AdvISR().
+         */
+        if (asc_dvc->idle_cmd_done)
+        {
+            break;
+        }
+        DvcSleepMilliSecond(1);
+
+        /*
+         * If interrupts were disabled on entry to AdvSendIdleCmd(),
+         * then they will still be disabled here. Call AdvISR() to
+         * check for the idle command completion.
+         */
+        (void) AdvISR(asc_dvc);
+    }
+
+    last_int_level = DvcEnterCritical();
+
+    if (asc_dvc->idle_cmd_done == ADV_FALSE)
+    {
+        ADV_ASSERT(0); /* The idle command should never timeout. */
+        return ADV_FALSE;
+    } else
+    {
+        AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret);
+        return ret;
+    }
+}
+
+/*
+ * Send the SCSI request block to the adapter
+ *
+ * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the
+ * following structure:
+ *
+ * 0: RQL_FWD - RISC list forward pointer (1 byte)
+ * 1: RQL_BWD - RISC list backward pointer (1 byte)
+ * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte)
+ * 3: RQL_TID - request target id (1 byte)
+ * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes)
+ *
+ * Return:
+ *      ADV_SUCCESS(1) - the request is in the mailbox
+ *      ADV_BUSY(0) - total request count > 253, try later
+ */
+STATIC int
+AdvSendScsiCmd(
+    ADV_DVC_VAR *asc_dvc,
+    ADV_SCSI_REQ_Q  *scsiq)
+{
+    ushort                 next_ready_loc;
+    uchar                  next_ready_loc_fwd;
+    int                    last_int_level;
+    AdvPortAddr            iop_base;
+    long                   req_size;
+    ulong                  q_phy_addr;
+
+    /*
+     * The ADV_SCSI_REQ_Q 'target_id' field should never be equal
+     * to the host adapter ID or exceed ADV_MAX_TID.
+     */
+    if (scsiq->target_id == asc_dvc->chip_scsi_id ||
+        scsiq->target_id > ADV_MAX_TID)
+    {
+        scsiq->host_status = QHSTA_M_INVALID_DEVICE;
+        scsiq->done_status = QD_WITH_ERROR;
+        return ADV_ERROR;
+    }
+
+    iop_base = asc_dvc->iop_base;
+
+    last_int_level = DvcEnterCritical();
+
+    if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng)
+    {
+        DvcLeaveCritical(last_int_level);
+        return ADV_BUSY;
+    } else
+    {
+        ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT);
+        asc_dvc->cur_host_qng++;
+    }
+
+    /*
+     * Clear the ADV_SCSI_REQ_Q done flag.
+     */
+    scsiq->a_flag &= ~ADV_SCSIQ_DONE;
+
+    /*
+     * Save the original sense buffer length.
+     *
+     * After the request completes 'sense_len' will be set to the residual
+     * byte count of the Auto-Request Sense if a command returns CHECK
+     * CONDITION and the Sense Data is valid indicated by 'host_status' not
+     * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid
+     * Sense Data Length subtract 'sense_len' from 'orig_sense_len'.
+     */
+    scsiq->orig_sense_len = scsiq->sense_len;
+
+    AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc);
+    next_ready_loc = ASC_MC_RISC_Q_LIST_BASE +
+        (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE);
+
+    /*
+     * Write the physical address of the Q to the mailbox.
+     * We need to skip the first four bytes, because the microcode
+     * uses them internally for linking Q's together.
+     */
+    req_size = sizeof(ADV_SCSI_REQ_Q);
+    q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq,
+                    (uchar *) scsiq, &req_size,
+                    ADV_IS_SCSIQ_FLAG);
+    ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr);
+    ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
+
+    scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
+
+    /*
+     * The RISC list structure, which 'next_ready_loc' is a pointer
+     * to in microcode LRAM, has the format detailed in the comment
+     * header for this function.
+     *
+     * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request.
+     */
+    AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr);
+
+    /* Write target_id to 'next_ready_loc' request. */
+    AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id);
+
+    /*
+     * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to
+     * the 'next_ready_loc' request forward pointer.
+     *
+     * Do this *before* changing the 'next_ready_loc' queue to QS_READY.
+     * After the state is changed to QS_READY 'RQL_FWD' will be changed
+     * by the microcode.
+     *
+     * NOTE: The temporary variable 'next_ready_loc_fwd' is required to
+     * prevent some compilers from optimizing out 'AdvReadByteLram()' if
+     * it were used as the 3rd argument to 'AdvWriteByteLram()'.
+     */
+    AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd);
+    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd);
+
+    /*
+     * Change the state of 'next_ready_loc' request from QS_FREE to
+     * QS_READY which will cause the microcode to pick it up and
+     * execute it.
+     *
+     * Can't reference 'next_ready_loc' after changing the request
+     * state to QS_READY. The microcode now owns the request.
+     */
+    AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY);
+
+    DvcLeaveCritical(last_int_level);
+    return ADV_SUCCESS;
+}
+
+/*
+ * Inquiry Information Byte 7 Handling
+ *
+ * Handle SCSI Inquiry Command information for a device by setting
+ * microcode operating variables that affect WDTR, SDTR, and Tag 
+ * Queuing.
+ */
+STATIC void
+AdvInquiryHandling(
+    ADV_DVC_VAR          *asc_dvc,
+    ADV_SCSI_REQ_Q       *scsiq)
+{
+    AdvPortAddr          iop_base;
+    uchar                tid;
+    ASC_SCSI_INQUIRY     *inq;
+    ushort               tidmask;
+    ushort               cfg_word;
+
+    /*
+     * AdvInquiryHandling() requires up to INQUIRY information Byte 7
+     * to be available.
+     *
+     * If less than 8 bytes of INQUIRY information were requested or less
+     * than 8 bytes were transferred, then return. cdb[4] is the request
+     * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
+     * microcode to the transfer residual count.
+     */
+    if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
+    {
+        return;
+    }
+
+    iop_base = asc_dvc->iop_base;
+    tid = scsiq->target_id;
+    inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr;
+
+    /*
+     * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
+     */
+    if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2)
+    {
+        return;
+    } else
+    {
+        /*
+         * INQUIRY Byte 7 Handling
+         *
+         * Use a device's INQUIRY byte 7 to determine whether it
+         * supports WDTR, SDTR, and Tag Queuing. If the feature
+         * is enabled in the EEPROM and the device supports the
+         * feature, then enable it in the microcode.
+         */
+
+        tidmask = ADV_TID_TO_TIDMASK(tid);
+
+        /*
+         * Wide Transfers
+         *
+         * If the EEPROM enabled WDTR for the device and the device
+         * supports wide bus (16 bit) transfers, then turn on the
+         * device's 'wdtr_able' bit and write the new value to the
+         * microcode.
+         */
+        if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16)
+        {
+            AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
+            if ((cfg_word & tidmask) == 0)
+            {
+                cfg_word |= tidmask;
+                AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
+
+                /*
+                 * Clear the microcode "WDTR negotiation" done indicator
+                 * for the target to cause it to negotiate with the new
+                 * setting set above.
+                 */
+                AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
+                cfg_word &= ~tidmask;
+                AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
+            }
+        }
+
+        /*
+         * Synchronous Transfers
+         *
+         * If the EEPROM enabled SDTR for the device and the device
+         * supports synchronous transfers, then turn on the device's
+         * 'sdtr_able' bit. Write the new value to the microcode.
+         */
+        if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync)
+        {
+            AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
+            if ((cfg_word & tidmask) == 0)
+            {
+                cfg_word |= tidmask;
+                AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
+
+                /*
+                 * Clear the microcode "SDTR negotiation" done indicator
+                 * for the target to cause it to negotiate with the new
+                 * setting set above.
+                 */
+                AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+                cfg_word &= ~tidmask;
+                AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+            }
+        }
+
+        /*
+         * If the EEPROM enabled Tag Queuing for device and the
+         * device supports Tag Queuing, then turn on the device's
+         * 'tagqng_enable' bit in the microcode and set the microcode
+         * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
+         * value.
+         *
+         * Tag Queuing is disabled for the BIOS which runs in polled
+         * mode and would see no benefit from Tag Queuing. Also by
+         * disabling Tag Queuing in the BIOS devices with Tag Queuing
+         * bugs will at least work with the BIOS.
+         */
+        if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue)
+        {
+            AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
+            cfg_word |= tidmask;
+            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
+            AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+                asc_dvc->max_dvc_qng);
+        }
+    }
 }
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/advansys.h linux/drivers/scsi/advansys.h
--- v2.1.80/linux/drivers/scsi/advansys.h	Tue Jan 20 16:52:42 1998
+++ linux/drivers/scsi/advansys.h	Fri Jan 23 17:35:23 1998
@@ -1,9 +1,9 @@
-/* $Id: advansys.h,v 1.6 1997/05/30 19:25:12 davem Exp $ */
+/* $Id: advansys.h,v 1.17 1998/01/08 21:23:49 bobf Exp bobf $ */
 
 /*
  * advansys.h - Linux Host Driver for AdvanSys SCSI Adapters
  * 
- * Copyright (c) 1995-1997 Advanced System Products, Inc.
+ * Copyright (c) 1995-1998 Advanced System Products, Inc.
  * All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -18,7 +18,7 @@
  *  ftp://ftp.advansys.com/pub/linux
  *
  * Please send questions, comments, bug reports to:
- * bobf@advansys.com (Bob Frey)
+ *  bobf@advansys.com (Bob Frey)
  */
 
 #ifndef _ADVANSYS_H
@@ -40,10 +40,18 @@
 int advansys_command(Scsi_Cmnd *);
 int advansys_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 int advansys_abort(Scsi_Cmnd *);
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
+int advansys_reset(Scsi_Cmnd *);
+#else /* version >= v1.3.89 */
 int advansys_reset(Scsi_Cmnd *, unsigned int);
+#endif /* version >= v1.3.89 */
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
+int advansys_biosparam(Disk *, int, int[]);
+#else /* version >= v1.3.0 */
 int advansys_biosparam(Disk *, kdev_t, int[]);
 extern struct proc_dir_entry proc_scsi_advansys;
 int advansys_proc_info(char *, char **, off_t, int, int, int);
+#endif /* version >= v1.3.0 */
 
 /* init/main.c setup function */
 void advansys_setup(char *, int *);
@@ -51,31 +59,116 @@
 /*
  * AdvanSys Host Driver Scsi_Host_Template (struct SHT) from hosts.h.
  */
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
 #define ADVANSYS { \
-			proc_dir:     &proc_scsi_advansys,	 \
-			proc_info:    advansys_proc_info,	 \
-			name:         "advansys",		 \
-			detect:       advansys_detect,		 \
-			release:      advansys_release,	         \
-			info:         advansys_info,		 \
-			command:      advansys_command, 	 \
-			queuecommand: advansys_queuecommand,     \
-			abort:        advansys_abort,		 \
-			reset:        advansys_reset,		 \
-			bios_param:    advansys_biosparam,	 \
-	/*							 \
-	 * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
-	 * must be set. The flag will be cleared in advansys_detect for non-ISA \
-	 * adapters. Refer to the comment in scsi_module.c for more information. \
-	 */							 \
-			unchecked_isa_dma: 1,			 \
-	/*							 \
-	 * All adapters controlled by this driver are capable of large \
-	 * scatter-gather lists. According to the mid-level SCSI documentation \
-	 * this obviates any performance gain provided by setting \
-	 * 'use_clustering'. But empirically while CPU utilization is increased \
-	 * by enabling clustering, I/O throughput increases as well. \
-	 */							 \
-			use_clustering: ENABLE_CLUSTERING,	 \
+    NULL,                     /* struct SHT *next */ \
+    NULL,                     /* int *usage_count */ \
+    "advansys",               /* char *name */ \
+    advansys_detect,          /* int (*detect)(struct SHT *) */ \
+    advansys_release,         /* int (*release)(struct Scsi_Host *) */ \
+    advansys_info,            /* const char *(*info)(struct Scsi_Host *) */ \
+    advansys_command,         /* int (*command)(Scsi_Cmnd *) */ \
+    advansys_queuecommand, \
+            /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \
+    advansys_abort,           /* int (*abort)(Scsi_Cmnd *) */ \
+    advansys_reset,           /* int (*reset)(Scsi_Cmnd *) */ \
+    NULL,                     /* int (*slave_attach)(int, int) */ \
+    advansys_biosparam,       /* int (* bios_param)(Disk *, int, int []) */ \
+    /* \
+     * The following fields are set per adapter in advansys_detect(). \
+     */ \
+    0,                        /* int can_queue */ \
+    0,                        /* int this_id */ \
+    0,                        /* short unsigned int sg_tablesize */ \
+    0,                        /* short cmd_per_lun */ \
+    0,                        /* unsigned char present */    \
+    /* \
+     * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
+     * must be set. The flag will be cleared in advansys_detect for non-ISA \
+     * adapters. Refer to the comment in scsi_module.c for more information. \
+     */ \
+    1,                        /* unsigned unchecked_isa_dma:1 */ \
+    /* \
+     * All adapters controlled by this driver are capable of large \
+     * scatter-gather lists. According to the mid-level SCSI documentation \
+     * this obviates any performance gain provided by setting \
+     * 'use_clustering'. But empirically while CPU utilization is increased \
+     * by enabling clustering, I/O throughput increases as well. \
+     */ \
+    ENABLE_CLUSTERING,        /* unsigned use_clustering:1 */ \
 }
+#elif LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75)
+#define ADVANSYS { \
+    NULL,                    /* struct SHT *next */ \
+    NULL, \
+        /* version < v2.1.23 long *usage_count */ \
+        /* version >= v2.1.23 struct module * */ \
+    &proc_scsi_advansys,     /* struct proc_dir_entry *proc_dir */ \
+    advansys_proc_info,    \
+        /* int (*proc_info)(char *, char **, off_t, int, int, int) */ \
+    "advansys",              /* const char *name */ \
+    advansys_detect,         /* int (*detect)(struct SHT *) */ \
+    advansys_release,        /* int (*release)(struct Scsi_Host *) */ \
+    advansys_info,           /* const char *(*info)(struct Scsi_Host *) */ \
+    advansys_command,        /* int (*command)(Scsi_Cmnd *) */ \
+    advansys_queuecommand, \
+        /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \
+    advansys_abort,          /* int (*abort)(Scsi_Cmnd *) */ \
+    advansys_reset, \
+        /* version < v1.3.89 int (*reset)(Scsi_Cmnd *) */ \
+        /* version >= v1.3.89 int (*reset)(Scsi_Cmnd *, unsigned int) */ \
+    NULL,                    /* int (*slave_attach)(int, int) */ \
+    advansys_biosparam,      /* int (* bios_param)(Disk *, kdev_t, int []) */ \
+    /* \
+     * The following fields are set per adapter in advansys_detect(). \
+     */ \
+    0,                        /* int can_queue */ \
+    0,                        /* int this_id */ \
+    0,                        /* short unsigned int sg_tablesize */ \
+    0,                        /* short cmd_per_lun */ \
+    0,                        /* unsigned char present */    \
+    /* \
+     * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
+     * must be set. The flag will be cleared in advansys_detect for non-ISA \
+     * adapters. Refer to the comment in scsi_module.c for more information. \
+     */ \
+    1,                        /* unsigned unchecked_isa_dma:1 */ \
+    /* \
+     * All adapters controlled by this driver are capable of large \
+     * scatter-gather lists. According to the mid-level SCSI documentation \
+     * this obviates any performance gain provided by setting \
+     * 'use_clustering'. But empirically while CPU utilization is increased \
+     * by enabling clustering, I/O throughput increases as well. \
+     */ \
+    ENABLE_CLUSTERING,        /* unsigned use_clustering:1 */ \
+}
+#else /* version >= v2.1.75 */
+#define ADVANSYS { \
+    proc_dir:     &proc_scsi_advansys, \
+    proc_info:    advansys_proc_info, \
+    name:         "advansys", \
+    detect:       advansys_detect, \
+    release:      advansys_release, \
+    info:         advansys_info, \
+    command:      advansys_command, \
+    queuecommand: advansys_queuecommand, \
+    abort:        advansys_abort, \
+    reset:        advansys_reset, \
+    bios_param:    advansys_biosparam, \
+    /* \
+     * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
+     * must be set. The flag will be cleared in advansys_detect for non-ISA \
+     * adapters. Refer to the comment in scsi_module.c for more information. \
+     */ \
+    unchecked_isa_dma: 1, \
+    /* \
+     * All adapters controlled by this driver are capable of large \
+     * scatter-gather lists. According to the mid-level SCSI documentation \
+     * this obviates any performance gain provided by setting \
+     * 'use_clustering'. But empirically while CPU utilization is increased \
+     * by enabling clustering, I/O throughput increases as well. \
+     */ \
+    use_clustering: ENABLE_CLUSTERING, \
+}
+#endif /* version >= v2.1.75 */
 #endif /* _ADVANSYS_H */
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/pci2000.h linux/drivers/scsi/pci2000.h
--- v2.1.80/linux/drivers/scsi/pci2000.h	Sun Dec 21 17:04:49 1997
+++ linux/drivers/scsi/pci2000.h	Fri Jan 23 17:38:04 1998
@@ -209,7 +209,7 @@
 		  queuecommand:	  Pci2000_QueueCommand,			\
 		  abort:	  Pci2000_Abort,			\
 		  reset:	  Pci2000_Reset,			\
-		  biosparam:	  Pci2000_BiosParam,                 	\
+		  bios_param:	  Pci2000_BiosParam,                 	\
 		  can_queue:	  16, 					\
 		  this_id:	  -1, 					\
 		  sg_tablesize:	  16,		 			\
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/pci2220i.h linux/drivers/scsi/pci2220i.h
--- v2.1.80/linux/drivers/scsi/pci2220i.h	Sun Dec 21 17:04:49 1997
+++ linux/drivers/scsi/pci2220i.h	Fri Jan 23 17:38:04 1998
@@ -328,7 +328,7 @@
 		  queuecommand:	  Pci2220i_QueueCommand,		\
 		  abort:	  Pci2220i_Abort,			\
 		  reset:	  Pci2220i_Reset,			\
-		  biosparam:	  Pci2220i_BiosParam,                 	\
+		  bios_param:	  Pci2220i_BiosParam,                 	\
 		  can_queue:	  1, 					\
 		  this_id:	  -1, 					\
 		  sg_tablesize:	  SG_NONE,		 		\
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/pluto.c linux/drivers/scsi/pluto.c
--- v2.1.80/linux/drivers/scsi/pluto.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/pluto.c	Wed Jan 21 17:04:39 1998
@@ -0,0 +1,313 @@
+/* pluto.c: SparcSTORAGE Array SCSI host adapter driver.
+ *
+ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/blk.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "../fc4/fcp_scsi.h"
+#include "pluto.h"
+
+#include <linux/module.h>
+
+/* #define PLUTO_DEBUG */
+
+#define pluto_printk printk ("PLUTO %s: ", fc->name); printk
+
+#ifdef PLUTO_DEBUG
+#define PLD(x)  pluto_printk x;
+#define PLND(x) printk ("PLUTO: "); printk x;
+#else
+#define PLD(x)
+#define PLND(x)
+#endif
+
+struct proc_dir_entry proc_scsi_pluto = {
+	PROC_SCSI_PLUTO, 5, "pluto",
+	S_IFDIR | S_IRUGO | S_IXUGO, 2
+};
+
+static struct ctrl_inquiry {
+	struct Scsi_Host host;
+	struct pluto pluto;
+	Scsi_Cmnd cmd;
+	char inquiry[256];
+	fc_channel *fc;
+} *fcs __initdata;
+static int fcscount __initdata;
+static atomic_t fcss __initdata;
+static struct timer_list fc_timer __initdata = { 0 };
+struct semaphore fc_sem __initdata = MUTEX_LOCKED;
+
+static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr);
+
+__initfunc(static void pluto_detect_timeout(unsigned long data))
+{
+	PLND(("Timeout\n"))
+	up(&fc_sem);
+}
+
+__initfunc(static void pluto_detect_done(Scsi_Cmnd *SCpnt))
+{
+	/* Do nothing */
+}
+
+__initfunc(static void pluto_detect_scsi_done(Scsi_Cmnd *SCpnt))
+{
+	SCpnt->request.rq_status = RQ_SCSI_DONE;
+	PLND(("Detect done %08lx\n", (long)SCpnt))
+	if (atomic_dec_and_test (&fcss))
+		up(&fc_sem);
+}
+
+static void pluto_select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist)
+{
+	Scsi_Device *device;
+	
+	for (device = devlist; device; device = device->next) {
+		if (device->host != host) continue;
+		if (device->tagged_supported)
+			device->queue_depth = /* 254 */ 8;
+		else
+			device->queue_depth = 2;
+	}
+}
+
+/* Detect all SSAs attached to the machine.
+   To be fast, do it on all online FC channels at the same time. */
+__initfunc(int pluto_detect(Scsi_Host_Template *tpnt))
+{
+	int i, retry, nplutos;
+	fc_channel *fc;
+	Scsi_Device dev;
+
+	tpnt->proc_dir = &proc_scsi_pluto;
+	fcscount = 0;
+	for_each_online_fc_channel(fc)
+		fcscount++;
+	PLND(("%d channels online\n", fcscount))
+	if (!fcscount)
+		return 0;
+	fcs = (struct ctrl_inquiry *) scsi_init_malloc (sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA);
+	if (!fcs) {
+		printk ("PLUTO: Not enough memory to probe\n");
+		return 0;
+	}
+	
+	memset (fcs, 0, sizeof (struct ctrl_inquiry) * fcscount);
+	memset (&dev, 0, sizeof(dev));
+	atomic_set (&fcss, fcscount);
+	fc_timer.function = pluto_detect_timeout;
+	
+	i = 0;
+	for_each_online_fc_channel(fc) {
+		Scsi_Cmnd *SCpnt;
+		struct Scsi_Host *host;
+		struct pluto *pluto;
+		
+		if (i == fcscount) break;
+		
+		PLD(("trying to find SSA\n"))
+
+		/* If this is already registered to some other SCSI host, then it cannot be pluto */
+		if (fc->scsi_name[0]) continue;
+		memcpy (fc->scsi_name, "SSA", 4);
+		
+		fcs[i].fc = fc;
+		
+		fc->can_queue = PLUTO_CAN_QUEUE;
+		fc->rsp_size = 64;
+		fc->encode_addr = pluto_encode_addr;
+		
+		fc->fcp_register(fc, TYPE_SCSI_FCP, 0);
+	
+		SCpnt = &(fcs[i].cmd);
+		host = &(fcs[i].host);
+		pluto = (struct pluto *)host->hostdata;
+		
+		pluto->fc = fc;
+	
+		SCpnt->host = host;
+		SCpnt->cmnd[0] = INQUIRY;
+		SCpnt->cmnd[4] = 255;
+		
+		/* FC layer requires this, so that SCpnt->device->tagged_supported is initially 0 */
+		SCpnt->device = &dev;
+		
+		SCpnt->cmd_len = COMMAND_SIZE(INQUIRY);
+	
+		SCpnt->request.rq_status = RQ_SCSI_BUSY;
+		
+		SCpnt->done = pluto_detect_done;
+		SCpnt->bufflen = 256;
+		SCpnt->buffer = fcs[i].inquiry;
+		SCpnt->request_bufflen = 256;
+		SCpnt->request_buffer = fcs[i].inquiry;
+		PLD(("set up %d %08lx\n", i, (long)SCpnt))
+		i++;
+	}
+	
+	for (retry = 0; retry < 5; retry++) {
+		for (i = 0; i < fcscount; i++) {
+			if (!fcs[i].fc) break;
+			if (fcs[i].cmd.request.rq_status != RQ_SCSI_DONE) {
+				disable_irq(fcs[i].fc->irq);
+				PLND(("queuecommand %d %d\n", retry, i))
+				fcp_scsi_queuecommand (&(fcs[i].cmd), 
+					pluto_detect_scsi_done);
+				enable_irq(fcs[i].fc->irq);
+			}
+		}
+	    
+		fc_timer.expires = jiffies + 10 * HZ;
+		add_timer(&fc_timer);
+		
+		down(&fc_sem);
+		PLND(("Woken up\n"))
+		if (!atomic_read(&fcss))
+			break; /* All fc channels have answered us */
+	}
+	del_timer(&fc_timer);
+
+	PLND(("Finished search\n"))
+	for (i = 0, nplutos = 0; i < fcscount; i++) {
+		Scsi_Cmnd *SCpnt;
+		
+		if (!(fc = fcs[i].fc)) break;
+	
+		SCpnt = &(fcs[i].cmd);
+		
+		/* Let FC mid-level free allocated resources */
+		SCpnt->done (SCpnt);
+		
+		if (!SCpnt->result) {
+			struct pluto_inquiry *inq;
+			struct pluto *pluto;
+			struct Scsi_Host *host;
+			
+			inq = (struct pluto_inquiry *)fcs[i].inquiry;
+
+			if ((inq->dtype & 0x1f) == TYPE_PROCESSOR &&
+			    !strncmp (inq->vendor_id, "SUN", 3) &&
+			    !strncmp (inq->product_id, "SSA", 3)) {
+				char *p;
+				long *ages;
+				
+				ages = kmalloc (((inq->channels + 1) * inq->targets) * sizeof(long), GFP_KERNEL);
+				if (!ages) continue;
+				
+				host = scsi_register (tpnt, sizeof (struct pluto));
+				if (!host) panic ("Cannot register PLUTO host\n");
+				
+				nplutos++;
+				
+				pluto = (struct pluto *)host->hostdata;
+				
+				host->max_id = inq->targets;
+				host->max_channel = inq->channels;
+				host->irq = fc->irq;
+				
+				host->select_queue_depths = pluto_select_queue_depths;
+				
+				fc->channels = inq->channels + 1;
+				fc->targets = inq->targets;
+				fc->ages = ages;
+				memset (ages, 0, ((inq->channels + 1) * inq->targets) * sizeof(long));
+				
+				pluto->fc = fc;
+				memcpy (pluto->rev_str, inq->revision, 4);
+				pluto->rev_str[4] = 0;
+				p = strchr (pluto->rev_str, ' ');
+				if (p) *p = 0;
+				memcpy (pluto->fw_rev_str, inq->fw_revision, 4);
+				pluto->fw_rev_str[4] = 0;
+				p = strchr (pluto->fw_rev_str, ' ');
+				if (p) *p = 0;
+				memcpy (pluto->serial_str, inq->serial, 12);
+				pluto->serial_str[12] = 0;
+				p = strchr (pluto->serial_str, ' ');
+				if (p) *p = 0;
+				
+				PLD(("Found SSA rev %s fw rev %s serial %s %dx%d\n", pluto->rev_str, pluto->fw_rev_str, pluto->serial_str, host->max_channel, host->max_id))
+			} else
+				fc->fcp_register(fc, TYPE_SCSI_FCP, 1);
+		} else
+			fc->fcp_register(fc, TYPE_SCSI_FCP, 1);
+	}
+	scsi_init_free((char *)fcs, sizeof (struct ctrl_inquiry) * fcscount);
+	if (nplutos)
+		printk ("PLUTO: Total of %d SparcSTORAGE Arrays found\n", nplutos);
+	return nplutos;
+}
+
+int pluto_release(struct Scsi_Host *host)
+{
+	struct pluto *pluto = (struct pluto *)host->hostdata;
+	fc_channel *fc = pluto->fc;
+	
+	fc->fcp_register(fc, TYPE_SCSI_FCP, 1);
+	kfree (fc->ages);
+	return 0;
+}
+
+const char *pluto_info(struct Scsi_Host *host)
+{
+	static char buf[80];
+	struct pluto *pluto = (struct pluto *) host->hostdata;
+
+	sprintf(buf, "SUN SparcSTORAGE Array %s fw %s serial %s %dx%d on %s",
+		pluto->rev_str, pluto->fw_rev_str, pluto->serial_str,
+		host->max_channel, host->max_id, pluto->fc->name);
+	return buf;
+}
+
+/* SSA uses this FC4S addressing:
+   switch (addr[0])
+   {
+   case 0: CONTROLLER - All of addr[1]..addr[3] has to be 0
+   case 1: SINGLE DISK - addr[1] channel, addr[2] id, addr[3] 0
+   case 2: DISK GROUP - ???
+   }
+   
+   So that SCSI mid-layer can access to these, we reserve
+   channel 0 id 0 lun 0 for CONTROLLER
+   and channels 1 .. max_channel are normal single disks.
+ */
+static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr)
+{
+	PLND(("encode addr %d %d %d\n", SCpnt->channel, SCpnt->target, SCpnt->cmnd[1] & 0xe0))
+	/* We don't support LUNs */
+	if (SCpnt->cmnd[1] & 0xe0) return -EINVAL;
+	if (!SCpnt->channel) {
+		if (SCpnt->target) return -EINVAL;
+		memset (addr, 0, 4 * sizeof(u16));
+	} else {
+		addr[0] = 1;
+		addr[1] = SCpnt->channel - 1;
+		addr[2] = SCpnt->target;
+		addr[3] = 0;
+	}
+	PLND(("trying %04x%04x%04x%04x\n", addr[0], addr[1], addr[2], addr[3]))
+	return 0;
+}
+
+#ifdef MODULE
+
+Scsi_Host_Template driver_template = PLUTO;
+
+#include "scsi_module.c"
+
+EXPORT_NO_SYMBOLS;
+#endif /* MODULE */
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/pluto.h linux/drivers/scsi/pluto.h
--- v2.1.80/linux/drivers/scsi/pluto.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/pluto.h	Wed Jan 21 17:04:39 1998
@@ -0,0 +1,59 @@
+/* pluto.h: SparcSTORAGE Array SCSI host adapter driver definitions.
+ *
+ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef _PLUTO_H
+#define _PLUTO_H
+
+#include "../fc4/fcp_scsi.h"
+
+struct pluto {
+	/* This must be first */
+	fc_channel	*fc;
+	char		rev_str[5];
+	char		fw_rev_str[5];
+	char		serial_str[13];
+};
+
+struct pluto_inquiry {
+	u8	dtype;
+	u8	removable:1, qualifier:7;
+	u8	iso:2, ecma:3, ansi:3;
+	u8	aenc:1, trmiop:1, :2, rdf:4;
+	u8	len;
+	u8	xxx1;
+	u8	xxx2;
+	u8	reladdr:1, wbus32:1, wbus16:1, sync:1, linked:1, :1, cmdque:1, softreset:1;
+	u8	vendor_id[8];
+	u8	product_id[16];
+	u8	revision[4];
+	u8	fw_revision[4];
+	u8	serial[12];
+	u8	xxx3[2];
+	u8	channels;
+	u8	targets;
+};
+
+/* This is the max number of outstanding SCSI commands per pluto */
+#define PLUTO_CAN_QUEUE		254
+
+int pluto_detect(Scsi_Host_Template *);
+int pluto_release(struct Scsi_Host *);
+const char * pluto_info(struct Scsi_Host *);
+
+#define PLUTO {							\
+	detect:			pluto_detect,			\
+	release:		pluto_release,			\
+	info:			pluto_info,			\
+	queuecommand:		fcp_scsi_queuecommand,		\
+	abort:			fcp_scsi_abort,			\
+	reset:			fcp_scsi_reset,			\
+	can_queue:		PLUTO_CAN_QUEUE,		\
+	this_id:		-1,				\
+	sg_tablesize:		1,				\
+	cmd_per_lun:		1,				\
+	use_clustering:		ENABLE_CLUSTERING		\
+}	
+
+#endif /* !(_PLUTO_H) */
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/psi240i.h linux/drivers/scsi/psi240i.h
--- v2.1.80/linux/drivers/scsi/psi240i.h	Sun Dec 21 17:04:49 1997
+++ linux/drivers/scsi/psi240i.h	Fri Jan 23 17:38:04 1998
@@ -327,7 +327,7 @@
 		  queuecommand:	  Psi240i_QueueCommand,		\
 		  abort:	  Psi240i_Abort,			\
 		  reset:	  Psi240i_Reset,			\
-		  biosparam:	  Psi240i_BiosParam,                 	\
+		  bios_param:	  Psi240i_BiosParam,                 	\
 		  can_queue:	  1, 					\
 		  this_id:	  -1, 					\
 		  sg_tablesize:	  SG_NONE,		 		\
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.1.80/linux/drivers/scsi/scsi.c	Thu Jan 15 21:11:01 1998
+++ linux/drivers/scsi/scsi.c	Fri Jan 23 17:38:04 1998
@@ -200,16 +200,6 @@
 static void scsi_dump_status(int level);
 
 
-/*
- *  This is the number  of clock ticks we should wait before we time out
- *  and abort the command.  This is for  where the scsi.c module generates
- *  the command, not where it originates from a higher level, in which
- *  case the timeout is specified there.
- *
- */
-
-
-
 struct dev_info{
     const char * vendor;
     const char * model;
@@ -3208,7 +3198,7 @@
         printk(" %d %d %d : %d %p\n",
                shpnt->host_failed,
                shpnt->host_busy,
-               shpnt->host_active,
+               atomic_read(&shpnt->host_active),
                shpnt->host_blocked,
                shpnt->pending_commands);
 
diff -u --recursive --new-file v2.1.80/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c
--- v2.1.80/linux/drivers/scsi/t128.c	Sun Jan  4 10:55:09 1998
+++ linux/drivers/scsi/t128.c	Fri Jan 23 17:38:04 1998
@@ -141,11 +141,11 @@
 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
 
 static struct base {
-    unsigned char *address;
+    unsigned int address;
     int noauto;
 } bases[] __initdata = {
-    {(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0},
-    {(unsigned char *) 0xdc000, 0}, {(unsigned char *) 0xd8000, 0}};
+    { 0xcc000, 0}, { 0xc8000, 0}, { 0xdc000, 0}, { 0xd8000, 0}
+};
 
 #define NO_BASES (sizeof (bases) / sizeof (struct base))
 
@@ -178,7 +178,7 @@
 	    overrides[commandline_current].address = (unsigned char *) ints[1];
 	    overrides[commandline_current].irq = ints[2];
 	    for (i = 0; i < NO_BASES; ++i)
-		if (bases[i].address == (unsigned char *) ints[1]) {
+		if (bases[i].address == ints[1]) {
 		    bases[i].noauto = 1;
 		    break;
 		}
@@ -216,7 +216,7 @@
 	else 
 	    for (; !base && (current_base < NO_BASES); ++current_base) {
 #if (TDEBUG & TDEBUG_INIT)
-    printk("scsi-t128 : probing address %08x\n", (unsigned int) bases[current_base].address);
+    printk("scsi-t128 : probing address %08x\n", bases[current_base].address);
 #endif
 		for (sig = 0; sig < NO_SIGNATURES; ++sig) 
 		    if (!bases[current_base].noauto && 
@@ -224,7 +224,7 @@
 					signatures[sig].offset,
 					signatures[sig].string,
 					strlen(signatures[sig].string))) {
-		      base = bases[current_base].address;
+			base = (unsigned char *) bases[current_base].address;
 #if (TDEBUG & TDEBUG_INIT)
 			printk("scsi-t128 : detected board.\n");
 #endif
diff -u --recursive --new-file v2.1.80/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
--- v2.1.80/linux/drivers/sound/audio.c	Tue Jan 20 16:44:57 1998
+++ linux/drivers/sound/audio.c	Fri Jan 23 17:38:04 1998
@@ -350,7 +350,7 @@
 int audio_ioctl(int dev, struct fileinfo *file_must_not_be_used,
 		unsigned int cmd, caddr_t arg)
 {
-	int val, info, count;
+	int val = 0, info, count;
 	unsigned long flags;
 	struct dma_buffparms *dmap;
 
diff -u --recursive --new-file v2.1.80/linux/drivers/sound/dev_table.c linux/drivers/sound/dev_table.c
--- v2.1.80/linux/drivers/sound/dev_table.c	Tue Jan 20 16:44:57 1998
+++ linux/drivers/sound/dev_table.c	Fri Jan 23 17:38:04 1998
@@ -36,9 +36,9 @@
 
 static void start_services(void)
 {
+#ifdef FIXME
 	int soundcards_installed;
 
-#ifdef FIXME
 	if (!(soundcards_installed = sndtable_get_cardcount()))
 		return;		/* No cards detected */
 #endif
diff -u --recursive --new-file v2.1.80/linux/drivers/sound/gus_card.c linux/drivers/sound/gus_card.c
--- v2.1.80/linux/drivers/sound/gus_card.c	Sun Dec 21 17:41:24 1997
+++ linux/drivers/sound/gus_card.c	Thu Jan 22 14:46:41 1998
@@ -28,8 +28,7 @@
 extern int      have_gus_max;
 int             gus_pnp_flag = 0;
 
-void
-attach_gus_card(struct address_info *hw_config)
+void attach_gus_card(struct address_info *hw_config)
 {
 	snd_set_irq_handler(hw_config->irq, gusintr, "Gravis Ultrasound", hw_config->osp);
 
@@ -48,8 +47,7 @@
 #endif
 }
 
-int
-probe_gus(struct address_info *hw_config)
+int probe_gus(struct address_info *hw_config)
 {
 	int             irq;
 	int             io_addr;
@@ -63,13 +61,13 @@
 		if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
 		    irq != 11 && irq != 12 && irq != 15)
 		  {
-			  printk("GUS: Unsupported IRQ %d\n", irq);
+			  printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);
 			  return 0;
 		  }
 	if (check_region(hw_config->io_base, 16))
-		printk("GUS: I/O range conflict (1)\n");
+		printk(KERN_ERR "GUS: I/O range conflict (1)\n");
 	else if (check_region(hw_config->io_base + 0x100, 16))
-		printk("GUS: I/O range conflict (2)\n");
+		printk(KERN_ERR "GUS: I/O range conflict (2)\n");
 	else if (gus_wave_detect(hw_config->io_base))
 		return 1;
 
@@ -95,8 +93,7 @@
 	return 0;
 }
 
-void
-unload_gus(struct address_info *hw_config)
+void unload_gus(struct address_info *hw_config)
 {
 	DDB(printk("unload_gus(%x)\n", hw_config->io_base));
 
@@ -112,8 +109,7 @@
 		sound_free_dma(hw_config->dma2);
 }
 
-void
-gusintr(int irq, void *dev_id, struct pt_regs *dummy)
+void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
 	unsigned char   src;
 	extern int      gus_timer_enabled;
@@ -126,56 +122,50 @@
 #endif
 
 	while (1)
-	  {
-		  if (!(src = inb(u_IrqStatus)))
-			  return;
-
-		  if (src & DMA_TC_IRQ)
-		    {
-			    guswave_dma_irq();
-		    }
-		  if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
-		    {
+	{
+		if (!(src = inb(u_IrqStatus)))
+			return;
+
+		if (src & DMA_TC_IRQ)
+		{
+			guswave_dma_irq();
+		}
+		if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
+		{
 #if defined(CONFIG_MIDI)
-			    gus_midi_interrupt(0);
+			gus_midi_interrupt(0);
 #endif
-		    }
-		  if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
-		    {
+		}
+		if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
+		{
 #if defined(CONFIG_SEQUENCER) || defined(CONFIG_SEQUENCER_MODULE)
-			    if (gus_timer_enabled)
-			      {
-				      sound_timer_interrupt();
-			      }
-			    gus_write8(0x45, 0);	/* Ack IRQ */
-			    gus_timer_command(4, 0x80);		/* Reset IRQ flags */
-
+			if (gus_timer_enabled)
+				sound_timer_interrupt();
+			gus_write8(0x45, 0);	/* Ack IRQ */
+			gus_timer_command(4, 0x80);		/* Reset IRQ flags */
 #else
-			    gus_write8(0x45, 0);	/* Stop timers */
+			gus_write8(0x45, 0);	/* Stop timers */
 #endif
-		    }
-		  if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
-		    {
-			    gus_voice_irq();
-		    }
-	  }
+		}
+		if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
+			gus_voice_irq();
+	}
 }
 
 #endif
 
 /*
- * Some extra code for the 16 bit sampling option
+ *	Some extra code for the 16 bit sampling option
  */
+
 #ifdef CONFIG_GUS16
 
-int
-probe_gus_db16(struct address_info *hw_config)
+int probe_gus_db16(struct address_info *hw_config)
 {
 	return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);
 }
 
-void
-attach_gus_db16(struct address_info *hw_config)
+void attach_gus_db16(struct address_info *hw_config)
 {
 #if defined(CONFIG_GUSHW) || defined(MODULE)
 	gus_pcm_volume = 100;
@@ -189,8 +179,7 @@
 					  hw_config->osp);
 }
 
-void
-unload_gus_db16(struct address_info *hw_config)
+void unload_gus_db16(struct address_info *hw_config)
 {
 
 	ad1848_unload(hw_config->io_base,
@@ -226,16 +215,15 @@
 MODULE_PARM(gus16, "i");
 MODULE_PARM(db16, "i");
 
-int
-init_module(void)
+int init_module(void)
 {
-	printk("Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+	printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
 	if (io == -1 || dma == -1 || irq == -1)
-	  {
-		  printk("I/O, IRQ, and DMA are mandatory\n");
-		  return -EINVAL;
-	  }
+	{
+		printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
+		return -EINVAL;
+	}
 	config.io_base = io;
 	config.irq = irq;
 	config.dma = dma;
@@ -244,10 +232,10 @@
 
 #if defined(CONFIG_GUS16)
 	if (probe_gus_db16(&config) && gus16)
-	  {
-		  attach_gus_db16(&config);
-		  db16 = 1;
-	  }
+	{
+		attach_gus_db16(&config);
+		db16 = 1;
+	}	
 #endif
 	if (probe_gus(&config) == 0)
 		return -ENODEV;
@@ -256,8 +244,7 @@
 	return 0;
 }
 
-void
-cleanup_module(void)
+void cleanup_module(void)
 {
 #if defined(CONFIG_GUS16)
 	if (db16)
diff -u --recursive --new-file v2.1.80/linux/drivers/sound/gus_midi.c linux/drivers/sound/gus_midi.c
--- v2.1.80/linux/drivers/sound/gus_midi.c	Tue Dec 30 10:59:17 1997
+++ linux/drivers/sound/gus_midi.c	Thu Jan 22 14:46:41 1998
@@ -33,24 +33,18 @@
 extern int      gus_base, gus_irq, gus_dma;
 extern int     *gus_osp;
 
-static int
-GUS_MIDI_STATUS(void)
+static int GUS_MIDI_STATUS(void)
 {
 	return inb(u_MidiStatus);
 }
 
-static int
-gus_midi_open(int dev, int mode,
-	      void            (*input) (int dev, unsigned char data),
-	      void            (*output) (int dev)
-)
+static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
 {
-
 	if (midi_busy)
-	  {
-		  printk("GUS: Midi busy\n");
-		  return -EBUSY;
-	  }
+	{
+/*		printk("GUS: Midi busy\n");*/
+		return -EBUSY;
+	}
 	outb((MIDI_RESET), u_MidiControl);
 	gus_delay();
 
@@ -59,10 +53,10 @@
 
 	if (mode == OPEN_READ || mode == OPEN_READWRITE)
 		if (!gus_pnp_flag)
-		  {
-			  gus_midi_control |= MIDI_ENABLE_RCV;
-			  input_opened = 1;
-		  }
+		{
+			gus_midi_control |= MIDI_ENABLE_RCV;
+			input_opened = 1;
+		}
 	outb((gus_midi_control), u_MidiControl);	/* Enable */
 
 	midi_busy = 1;
@@ -72,8 +66,7 @@
 	return 0;
 }
 
-static int
-dump_to_midi(unsigned char midi_byte)
+static int dump_to_midi(unsigned char midi_byte)
 {
 	unsigned long   flags;
 	int             ok = 0;
@@ -84,24 +77,24 @@
 	cli();
 
 	if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
-	  {
-		  ok = 1;
-		  outb((midi_byte), u_MidiData);
-	} else
-	  {
-		  /*
-		   * Enable Midi xmit interrupts (again)
-		   */
-		  gus_midi_control |= MIDI_ENABLE_XMIT;
-		  outb((gus_midi_control), u_MidiControl);
-	  }
+	{
+		ok = 1;
+		outb((midi_byte), u_MidiData);
+	}
+	else
+	{
+		/*
+		 * Enable Midi xmit interrupts (again)
+		 */
+		gus_midi_control |= MIDI_ENABLE_XMIT;
+		outb((gus_midi_control), u_MidiControl);
+	}
 
 	restore_flags(flags);
 	return ok;
 }
 
-static void
-gus_midi_close(int dev)
+static void gus_midi_close(int dev)
 {
 	/*
 	 * Reset FIFO pointers, disable intrs
@@ -111,10 +104,8 @@
 	midi_busy = 0;
 }
 
-static int
-gus_midi_out(int dev, unsigned char midi_byte)
+static int gus_midi_out(int dev, unsigned char midi_byte)
 {
-
 	unsigned long   flags;
 
 	/*
@@ -125,15 +116,14 @@
 	cli();
 
 	while (qlen && dump_to_midi(tmp_queue[qhead]))
-	  {
-		  qlen--;
-		  qhead++;
-	  }
-
+	{
+		qlen--;
+		qhead++;
+	}
 	restore_flags(flags);
 
 	/*
-	 * Output the byte if the local queue is empty.
+	 *	Output the byte if the local queue is empty.
 	 */
 
 	if (!qlen)
@@ -143,14 +133,13 @@
 					 */
 
 	/*
-	 * Put to the local queue
+	 *	Put to the local queue
 	 */
 
 	if (qlen >= 256)
 		return 0;	/*
 				 * Local queue full
 				 */
-
 	save_flags(flags);
 	cli();
 
@@ -159,29 +148,24 @@
 	qtail++;
 
 	restore_flags(flags);
-
 	return 1;
 }
 
-static int
-gus_midi_start_read(int dev)
+static int gus_midi_start_read(int dev)
 {
 	return 0;
 }
 
-static int
-gus_midi_end_read(int dev)
+static int gus_midi_end_read(int dev)
 {
 	return 0;
 }
 
-static void
-gus_midi_kick(int dev)
+static void gus_midi_kick(int dev)
 {
 }
 
-static int
-gus_midi_buffer_status(int dev)
+static int gus_midi_buffer_status(int dev)
 {
 	unsigned long   flags;
 
@@ -192,12 +176,11 @@
 	cli();
 
 	if (qlen && dump_to_midi(tmp_queue[qhead]))
-	  {
-		  qlen--;
-		  qhead++;
-	  }
+	{
+		qlen--;
+		qhead++;
+	}
 	restore_flags(flags);
-
 	return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
 }
 
@@ -207,7 +190,9 @@
 
 static struct midi_operations gus_midi_operations =
 {
-	{"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
+	{
+		"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS
+	},
 	&std_midi_synth,
 	{0},
 	gus_midi_open,
@@ -224,16 +209,15 @@
 	NULL
 };
 
-void
-gus_midi_init(struct address_info *hw_config)
+void gus_midi_init(struct address_info *hw_config)
 {
-	int             dev = sound_alloc_mididev();
+	int dev = sound_alloc_mididev();
 
 	if (dev == -1)
-	  {
-		  printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
-		  return;
-	  }
+	{
+		printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
+		return;
+	}
 	outb((MIDI_RESET), u_MidiControl);
 
 	std_midi_synth.midi_dev = my_dev = dev;
@@ -243,44 +227,41 @@
 	return;
 }
 
-void
-gus_midi_interrupt(int dummy)
+void gus_midi_interrupt(int dummy)
 {
 	volatile unsigned char stat, data;
-	unsigned long   flags;
-	int             timeout = 10;
+	unsigned long flags;
+	int timeout = 10;
 
 	save_flags(flags);
 	cli();
 
 	while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
-	  {
-		  if (stat & MIDI_RCV_FULL)
-		    {
-			    data = inb(u_MidiData);
-			    if (input_opened)
-				    midi_input_intr(my_dev, data);
-		    }
-		  if (stat & MIDI_XMIT_EMPTY)
-		    {
-			    while (qlen && dump_to_midi(tmp_queue[qhead]))
-			      {
-				      qlen--;
-				      qhead++;
-			      }
-
-			    if (!qlen)
-			      {
-				      /*
-				       * Disable Midi output interrupts, since no data in the buffer
-				       */
-				      gus_midi_control &= ~MIDI_ENABLE_XMIT;
-				      outb((gus_midi_control), u_MidiControl);
-				      outb((gus_midi_control), u_MidiControl);
-			      }
-		    }
-	  }
-
+	{
+		if (stat & MIDI_RCV_FULL)
+		{
+			data = inb(u_MidiData);
+			if (input_opened)
+				midi_input_intr(my_dev, data);
+		}
+		if (stat & MIDI_XMIT_EMPTY)
+		{
+			while (qlen && dump_to_midi(tmp_queue[qhead]))
+			{
+				qlen--;
+				qhead++;
+			}
+			if (!qlen)
+			{
+			      /*
+			       * Disable Midi output interrupts, since no data in the buffer
+			       */
+			      gus_midi_control &= ~MIDI_ENABLE_XMIT;
+			      outb((gus_midi_control), u_MidiControl);
+			      outb((gus_midi_control), u_MidiControl);
+			}
+		}
+	}
 	restore_flags(flags);
 }
 
diff -u --recursive --new-file v2.1.80/linux/drivers/sound/gus_vol.c linux/drivers/sound/gus_vol.c
--- v2.1.80/linux/drivers/sound/gus_vol.c	Sat Nov 29 10:33:20 1997
+++ linux/drivers/sound/gus_vol.c	Thu Jan 22 14:46:41 1998
@@ -34,10 +34,10 @@
  * we can give a big boost to very weak voices like nylon guitar and the
  * basses.  The normal value is 64.  Strings are assigned lower values.
  */
-unsigned short
-gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
+
+unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
 {
-	int             i, m, n, x;
+	int i, m, n, x;
 
 
 	/*
@@ -50,6 +50,7 @@
 	/*
 	 * Boost expression by voice volume above neutral.
 	 */
+	 
 	if (voicev > 65)
 		xpn += voicev - 64;
 	xpn += (voicev - 64) / 2;
@@ -85,18 +86,22 @@
 	 * Convert to GUS's logarithmic form with 4 bit exponent i and 8 bit
 	 * mantissa m.
 	 */
+	 
 	n = x;
 	i = 7;
 	if (n < 128)
-	  {
+	{
 		  while (i > 0 && n < (1 << i))
 			  i--;
-	} else
+	}
+	else
+	{
 		while (n > 255)
-		  {
+		{
 			  n >>= 1;
 			  i++;
-		  }
+		}
+	}
 	/*
 	 * Mantissa is part of linear volume not expressed in exponent.  (This is
 	 * not quite like real logs -- I wonder if it's right.)
@@ -107,12 +112,12 @@
 	 * Adjust mantissa to 8 bits.
 	 */
 	if (m > 0)
-	  {
-		  if (i > 8)
-			  m >>= i - 8;
-		  else if (i < 8)
-			  m <<= 8 - i;
-	  }
+	{
+		if (i > 8)
+			m >>= i - 8;
+		else if (i < 8)
+			m <<= 8 - i;
+	}
 	return ((i << 8) + m);
 }
 
@@ -122,10 +127,9 @@
  * and the volume set by the mixer-device (default 60%).
  */
 
-unsigned short
-gus_linear_vol(int vol, int mainvol)
+unsigned short gus_linear_vol(int vol, int mainvol)
 {
-	int             mixer_mainvol;
+	int mixer_mainvol;
 
 	if (vol <= 0)
 		vol = 0;
@@ -146,7 +150,6 @@
 #else
 	mainvol = 127;
 #endif
-
 	return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
 }
 
diff -u --recursive --new-file v2.1.80/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
--- v2.1.80/linux/drivers/sound/gus_wave.c	Tue Jan 20 16:44:57 1998
+++ linux/drivers/sound/gus_wave.c	Thu Jan 22 14:46:41 1998
@@ -32,42 +32,42 @@
 #define NOT_SAMPLE	0xffff
 
 struct voice_info
-  {
-	  unsigned long   orig_freq;
-	  unsigned long   current_freq;
-	  unsigned long   mode;
-	  int             fixed_pitch;
-	  int             bender;
-	  int             bender_range;
-	  int             panning;
-	  int             midi_volume;
-	  unsigned int    initial_volume;
-	  unsigned int    current_volume;
-	  int             loop_irq_mode, loop_irq_parm;
+{
+	unsigned long   orig_freq;
+	unsigned long   current_freq;
+	unsigned long   mode;
+	int             fixed_pitch;
+	int             bender;
+	int             bender_range;
+	int             panning;
+	int             midi_volume;
+	unsigned int    initial_volume;
+	unsigned int    current_volume;
+	int             loop_irq_mode, loop_irq_parm;
 #define LMODE_FINISH		1
 #define LMODE_PCM		2
 #define LMODE_PCM_STOP		3
-	  int             volume_irq_mode, volume_irq_parm;
+	int             volume_irq_mode, volume_irq_parm;
 #define VMODE_HALT		1
 #define VMODE_ENVELOPE		2
 #define VMODE_START_NOTE	3
 
-	  int             env_phase;
-	  unsigned char   env_rate[6];
-	  unsigned char   env_offset[6];
-
-	  /*
-	   * Volume computation parameters for gus_adagio_vol()
-	   */
-	  int             main_vol, expression_vol, patch_vol;
-
-	  /* Variables for "Ultraclick" removal */
-	  int             dev_pending, note_pending, volume_pending,
-	                  sample_pending;
-	  char            kill_pending;
-	  long            offset_pending;
+	int             env_phase;
+	unsigned char   env_rate[6];
+	unsigned char   env_offset[6];
+
+	/*
+	 * Volume computation parameters for gus_adagio_vol()
+	 */
+	int		main_vol, expression_vol, patch_vol;
+
+	/* Variables for "Ultraclick" removal */
+	int             dev_pending, note_pending, volume_pending,
+	                sample_pending;
+	char            kill_pending;
+	long            offset_pending;
 
-  };
+};
 
 static struct voice_alloc_info *voice_alloc;
 
@@ -101,6 +101,7 @@
  * Current version of this driver doesn't allow synth and PCM functions
  * at the same time. The active_device specifies the active driver
  */
+
 static int      active_device = 0;
 
 #define GUS_DEV_WAVE		1	/* Wave table synth */
@@ -114,12 +115,14 @@
 static char     bounce_buf[8 * 1024];	/* Must match value set to max_fragment */
 
 static struct wait_queue *dram_sleeper = NULL;
-static volatile struct snd_wait dram_sleep_flag =
-{0};
+static volatile struct snd_wait dram_sleep_flag = {
+	0
+};
 
 /*
  * Variables and buffers for PCM output
  */
+
 #define MAX_PCM_BUFFERS		(128*MAX_REALTIME_FACTOR)	/* Don't change */
 
 static int      pcm_bsize, pcm_nblk, pcm_banksize;
@@ -172,8 +175,10 @@
 static int      patch_table[MAX_PATCH];
 static int      patch_map[32];
 
-static struct synth_info gus_info =
-{"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH};
+static struct synth_info gus_info = {
+	"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 
+	0, 16, 0, MAX_PATCH
+};
 
 static void     gus_poke(long addr, unsigned char data);
 static void     compute_and_set_volume(int voice, int volume, int ramp_time);
@@ -187,10 +192,9 @@
 #define	INSTANT_RAMP		-1	/* Instant change. No ramping */
 #define FAST_RAMP		0	/* Fastest possible ramp */
 
-static void
-reset_sample_memory(void)
+static void reset_sample_memory(void)
 {
-	int             i;
+	int i;
 
 	for (i = 0; i <= MAX_SAMPLE; i++)
 		sample_ptrs[i] = -1;
@@ -209,17 +213,15 @@
 		patch_table[i] = NOT_SAMPLE;
 }
 
-void
-gus_delay(void)
+void gus_delay(void)
 {
-	int             i;
+	int i;
 
 	for (i = 0; i < 7; i++)
 		inb(u_DRAMIO);
 }
 
-static void
-gus_poke(long addr, unsigned char data)
+static void gus_poke(long addr, unsigned char data)
 {				/* Writes a byte to the DRAM */
 	unsigned long   flags;
 
@@ -235,8 +237,7 @@
 	restore_flags(flags);
 }
 
-static unsigned char
-gus_peek(long addr)
+static unsigned char gus_peek(long addr)
 {				/* Reads a byte from the DRAM */
 	unsigned long   flags;
 	unsigned char   tmp;
@@ -255,8 +256,7 @@
 	return tmp;
 }
 
-void
-gus_write8(int reg, unsigned int data)
+void gus_write8(int reg, unsigned int data)
 {				/* Writes to an indirect register (8 bit) */
 	unsigned long   flags;
 
@@ -269,9 +269,9 @@
 	restore_flags(flags);
 }
 
-static unsigned char
-gus_read8(int reg)
-{				/* Reads from an indirect register (8 bit). Offset 0x80. */
+static unsigned char gus_read8(int reg)
+{				
+	/* Reads from an indirect register (8 bit). Offset 0x80. */
 	unsigned long   flags;
 	unsigned char   val;
 
@@ -284,9 +284,9 @@
 	return val;
 }
 
-static unsigned char
-gus_look8(int reg)
-{				/* Reads from an indirect register (8 bit). No additional offset. */
+static unsigned char gus_look8(int reg)
+{
+	/* Reads from an indirect register (8 bit). No additional offset. */
 	unsigned long   flags;
 	unsigned char   val;
 
@@ -299,9 +299,9 @@
 	return val;
 }
 
-static void
-gus_write16(int reg, unsigned int data)
-{				/* Writes to an indirect register (16 bit) */
+static void gus_write16(int reg, unsigned int data)
+{
+	/* Writes to an indirect register (16 bit) */
 	unsigned long   flags;
 
 	save_flags(flags);
@@ -315,9 +315,9 @@
 	restore_flags(flags);
 }
 
-static unsigned short
-gus_read16(int reg)
-{				/* Reads from an indirect register (16 bit). Offset 0x80. */
+static unsigned short gus_read16(int reg)
+{
+	/* Reads from an indirect register (16 bit). Offset 0x80. */
 	unsigned long   flags;
 	unsigned char   hi, lo;
 
@@ -334,9 +334,9 @@
 	return ((hi << 8) & 0xff00) | lo;
 }
 
-static unsigned short
-gus_look16(int reg)
-{				/* Reads from an indirect register (16 bit). No additional offset. */
+static unsigned short gus_look16(int reg)
+{		
+	/* Reads from an indirect register (16 bit). No additional offset. */
 	unsigned long   flags;
 	unsigned char   hi, lo;
 
@@ -353,32 +353,33 @@
 	return ((hi << 8) & 0xff00) | lo;
 }
 
-static void
-gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
-{				/* Writes an 24 bit memory address */
+static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
+{
+	/* Writes an 24 bit memory address */
 	unsigned long   hold_address;
 	unsigned long   flags;
 
 	save_flags(flags);
 	cli();
 	if (is16bit)
-	  {
-		  if (iw_mode)
-		    {
-			    /* Interwave spesific address translations */
-			    address >>= 1;
-		  } else
-		    {
-			    /*
-			     * Special processing required for 16 bit patches
-			     */
-
-			    hold_address = address;
-			    address = address >> 1;
-			    address &= 0x0001ffffL;
-			    address |= (hold_address & 0x000c0000L);
-		    }
-	  }
+	{
+		if (iw_mode)
+		{
+			/* Interwave spesific address translations */
+			address >>= 1;
+		}
+		else
+		{
+			/*
+			 * Special processing required for 16 bit patches
+			 */
+
+			hold_address = address;
+			address = address >> 1;
+			address &= 0x0001ffffL;
+			address |= (hold_address & 0x000c0000L);
+		}
+	}
 	gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
 	gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
 		    + (frac << 5));
@@ -390,17 +391,14 @@
 	restore_flags(flags);
 }
 
-static void
-gus_select_voice(int voice)
+static void gus_select_voice(int voice)
 {
 	if (voice < 0 || voice > 31)
 		return;
-
 	outb((voice), u_Voice);
 }
 
-static void
-gus_select_max_voices(int nvoices)
+static void gus_select_max_voices(int nvoices)
 {
 	if (iw_mode)
 		nvoices = 32;
@@ -410,26 +408,22 @@
 		nvoices = 32;
 
 	voice_alloc->max_voice = nr_voices = nvoices;
-
 	gus_write8(0x0e, (nvoices - 1) | 0xc0);
 }
 
-static void
-gus_voice_on(unsigned int mode)
+static void gus_voice_on(unsigned int mode)
 {
 	gus_write8(0x00, (unsigned char) (mode & 0xfc));
 	gus_delay();
 	gus_write8(0x00, (unsigned char) (mode & 0xfc));
 }
 
-static void
-gus_voice_off(void)
+static void gus_voice_off(void)
 {
 	gus_write8(0x00, gus_read8(0x00) | 0x03);
 }
 
-static void
-gus_voice_mode(unsigned int m)
+static void gus_voice_mode(unsigned int m)
 {
 	unsigned char   mode = (unsigned char) (m & 0xff);
 
@@ -439,8 +433,7 @@
 	gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
 }
 
-static void
-gus_voice_freq(unsigned long freq)
+static void gus_voice_freq(unsigned long freq)
 {
 	unsigned long   divisor = freq_div_table[nr_voices - 14];
 	unsigned short  fc;
@@ -455,34 +448,29 @@
 	gus_write16(0x01, fc);
 }
 
-static void
-gus_voice_volume(unsigned int vol)
+static void gus_voice_volume(unsigned int vol)
 {
 	gus_write8(0x0d, 0x03);	/* Stop ramp before setting volume */
 	gus_write16(0x09, (unsigned short) (vol << 4));
 }
 
-static void
-gus_voice_balance(unsigned int balance)
+static void gus_voice_balance(unsigned int balance)
 {
 	gus_write8(0x0c, (unsigned char) (balance & 0xff));
 }
 
-static void
-gus_ramp_range(unsigned int low, unsigned int high)
+static void gus_ramp_range(unsigned int low, unsigned int high)
 {
 	gus_write8(0x07, (unsigned char) ((low >> 4) & 0xff));
 	gus_write8(0x08, (unsigned char) ((high >> 4) & 0xff));
 }
 
-static void
-gus_ramp_rate(unsigned int scale, unsigned int rate)
+static void gus_ramp_rate(unsigned int scale, unsigned int rate)
 {
 	gus_write8(0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
 }
 
-static void
-gus_rampon(unsigned int m)
+static void gus_rampon(unsigned int m)
 {
 	unsigned char   mode = (unsigned char) (m & 0xff);
 
@@ -491,10 +479,9 @@
 	gus_write8(0x0d, mode & 0xfc);
 }
 
-static void
-gus_ramp_mode(unsigned int m)
+static void gus_ramp_mode(unsigned int m)
 {
-	unsigned char   mode = (unsigned char) (m & 0xff);
+	unsigned char mode = (unsigned char) (m & 0xff);
 
 	gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
 		   (mode & 0xfc));	/* Leave the last 2 bits alone */
@@ -502,16 +489,14 @@
 	gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
 }
 
-static void
-gus_rampoff(void)
+static void gus_rampoff(void)
 {
 	gus_write8(0x0d, 0x03);
 }
 
-static void
-gus_set_voice_pos(int voice, long position)
+static void gus_set_voice_pos(int voice, long position)
 {
-	int             sample_no;
+	int sample_no;
 
 	if ((sample_no = sample_map[voice]) != -1)
 		if (position < samples[sample_no].len)
@@ -522,8 +507,7 @@
 				 samples[sample_no].mode & WAVE_16_BITS);
 }
 
-static void
-gus_voice_init(int voice)
+static void gus_voice_init(int voice)
 {
 	unsigned long   flags;
 
@@ -541,8 +525,7 @@
 
 }
 
-static void
-gus_voice_init2(int voice)
+static void gus_voice_init2(int voice)
 {
 	voices[voice].panning = 0;
 	voices[voice].mode = 0;
@@ -564,30 +547,30 @@
 	voices[voice].fixed_pitch = 0;
 }
 
-static void
-step_envelope(int voice)
+static void step_envelope(int voice)
 {
 	unsigned        vol, prev_vol, phase;
 	unsigned char   rate;
 	long int        flags;
 
 	if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
-	  {
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_rampoff();
-		  restore_flags(flags);
-		  return;
-		  /*
-		   * Sustain phase begins. Continue envelope after receiving note off.
-		   */
-	  }
+	{
+		save_flags(flags);
+		cli();
+		gus_select_voice(voice);
+		gus_rampoff();
+		restore_flags(flags);
+		return;
+		/*
+		 * Sustain phase begins. Continue envelope after receiving note off.
+		 */
+	}
 	if (voices[voice].env_phase >= 5)
-	  {			/* Envelope finished. Shoot the voice down */
-		  gus_voice_init(voice);
-		  return;
-	  }
+	{
+		/* Envelope finished. Shoot the voice down */
+		gus_voice_init(voice);
+		return;
+	}
 	prev_vol = voices[voice].current_volume;
 	phase = ++voices[voice].env_phase;
 	compute_volume(voice, voices[voice].midi_volume);
@@ -606,30 +589,30 @@
 	voices[voice].volume_irq_mode = VMODE_ENVELOPE;
 
 	if (((vol - prev_vol) / 64) == 0)	/* No significant volume change */
-	  {
-		  restore_flags(flags);
-		  step_envelope(voice);		/* Continue the envelope on the next step */
-		  return;
-	  }
+	{
+		restore_flags(flags);
+		step_envelope(voice);		/* Continue the envelope on the next step */
+		return;
+	}
 	if (vol > prev_vol)
-	  {
-		  if (vol >= (4096 - 64))
-			  vol = 4096 - 65;
-		  gus_ramp_range(0, vol);
-		  gus_rampon(0x20);	/* Increasing volume, with IRQ */
-	} else
-	  {
-		  if (vol <= 64)
-			  vol = 65;
-		  gus_ramp_range(vol, 4030);
-		  gus_rampon(0x60);	/* Decreasing volume, with IRQ */
-	  }
+	{
+		if (vol >= (4096 - 64))
+			vol = 4096 - 65;
+		gus_ramp_range(0, vol);
+		gus_rampon(0x20);	/* Increasing volume, with IRQ */
+	}
+	else
+	{
+		if (vol <= 64)
+			vol = 65;
+		gus_ramp_range(vol, 4030);
+		gus_rampon(0x60);	/* Decreasing volume, with IRQ */
+	}
 	voices[voice].current_volume = vol;
 	restore_flags(flags);
 }
 
-static void
-init_envelope(int voice)
+static void init_envelope(int voice)
 {
 	voices[voice].env_phase = -1;
 	voices[voice].current_volume = 64;
@@ -637,17 +620,15 @@
 	step_envelope(voice);
 }
 
-static void
-start_release(int voice, long int flags)
+static void start_release(int voice, long int flags)
 {
 	if (gus_read8(0x00) & 0x03)
 		return;		/* Voice already stopped */
 
 	voices[voice].env_phase = 2;	/* Will be incremented by step_envelope */
 
-	voices[voice].current_volume =
-	    voices[voice].initial_volume =
-	    gus_read16(0x09) >> 4;	/* Get current volume */
+	voices[voice].current_volume = voices[voice].initial_volume =
+						gus_read16(0x09) >> 4;	/* Get current volume */
 
 	voices[voice].mode &= ~WAVE_SUSTAIN_ON;
 	gus_rampoff();
@@ -655,42 +636,41 @@
 	step_envelope(voice);
 }
 
-static void
-gus_voice_fade(int voice)
+static void gus_voice_fade(int voice)
 {
-	int             instr_no = sample_map[voice], is16bits;
-	long int        flags;
+	int instr_no = sample_map[voice], is16bits;
+	long int flags;
 
 	save_flags(flags);
 	cli();
 	gus_select_voice(voice);
 
 	if (instr_no < 0 || instr_no > MAX_SAMPLE)
-	  {
-		  gus_write8(0x00, 0x03);	/* Hard stop */
-		  voice_alloc->map[voice] = 0;
-		  restore_flags(flags);
-		  return;
-	  }
+	{
+		gus_write8(0x00, 0x03);	/* Hard stop */
+		voice_alloc->map[voice] = 0;
+		restore_flags(flags);
+		return;
+	}
 	is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0;	/* 8 or 16 bits */
 
 	if (voices[voice].mode & WAVE_ENVELOPES)
-	  {
-		  start_release(voice, flags);
-		  restore_flags(flags);
-		  return;
-	  }
+	{
+		start_release(voice, flags);
+		restore_flags(flags);
+		return;
+	}
 	/*
 	 * Ramp the volume down but not too quickly.
 	 */
 	if ((int) (gus_read16(0x09) >> 4) < 100)	/* Get current volume */
-	  {
-		  gus_voice_off();
-		  gus_rampoff();
-		  gus_voice_init(voice);
-		  restore_flags(flags);
-		  return;
-	  }
+	{
+		gus_voice_off();
+		gus_rampoff();
+		gus_voice_init(voice);
+		restore_flags(flags);
+		return;
+	}
 	gus_ramp_range(65, 4030);
 	gus_ramp_rate(2, 4);
 	gus_rampon(0x40 | 0x20);	/* Down, once, with IRQ */
@@ -698,10 +678,9 @@
 	restore_flags(flags);
 }
 
-static void
-gus_reset(void)
+static void gus_reset(void)
 {
-	int             i;
+	int i;
 
 	gus_select_max_voices(24);
 	volume_base = 3071;
@@ -709,23 +688,24 @@
 	volume_method = VOL_METHOD_ADAGIO;
 
 	for (i = 0; i < 32; i++)
-	  {
-		  gus_voice_init(i);	/* Turn voice off */
-		  gus_voice_init2(i);
-	  }
+	{
+		gus_voice_init(i);	/* Turn voice off */
+		gus_voice_init2(i);
+	}
 }
 
-static void
-gus_initialize(void)
+static void gus_initialize(void)
 {
-	unsigned long   flags;
-	unsigned char   dma_image, irq_image, tmp;
+	unsigned long flags;
+	unsigned char dma_image, irq_image, tmp;
 
-	static unsigned char gus_irq_map[16] =
-	{0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
-
-	static unsigned char gus_dma_map[8] =
-	{0, 1, 0, 2, 0, 3, 4, 5};
+	static unsigned char gus_irq_map[16] = 	{
+		0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7
+	};
+
+	static unsigned char gus_dma_map[8] = {
+		0, 1, 0, 2, 0, 3, 4, 5
+	};
 
 	save_flags(flags);
 	cli();
@@ -787,37 +767,39 @@
 	irq_image = 0;
 	tmp = gus_irq_map[gus_irq];
 	if (!gus_pnp_flag && !tmp)
-		printk("Warning! GUS IRQ not selected\n");
+		printk(KERN_WARNING "Warning! GUS IRQ not selected\n");
 	irq_image |= tmp;
 	irq_image |= 0x40;	/* Combine IRQ1 (GF1) and IRQ2 (Midi) */
 
 	dual_dma_mode = 1;
 	if (gus_dma2 == gus_dma || gus_dma2 == -1)
-	  {
-		  dual_dma_mode = 0;
-		  dma_image = 0x40;	/* Combine DMA1 (DRAM) and IRQ2 (ADC) */
-
-		  tmp = gus_dma_map[gus_dma];
-		  if (!tmp)
-			  printk("Warning! GUS DMA not selected\n");
+	{
+		dual_dma_mode = 0;
+		dma_image = 0x40;	/* Combine DMA1 (DRAM) and IRQ2 (ADC) */
 
-		  dma_image |= tmp;
-	} else
+		tmp = gus_dma_map[gus_dma];
+		if (!tmp)
+			printk(KERN_WARNING "Warning! GUS DMA not selected\n");
+
+		dma_image |= tmp;
+	}
+	else
+	{
 		/* Setup dual DMA channel mode for GUS MAX */
-	  {
-		  dma_image = gus_dma_map[gus_dma];
-		  if (!dma_image)
-			  printk("Warning! GUS DMA not selected\n");
-
-		  tmp = gus_dma_map[gus_dma2] << 3;
-		  if (!tmp)
-		    {
-			    printk("Warning! Invalid GUS MAX DMA\n");
-			    tmp = 0x40;		/* Combine DMA channels */
+
+		dma_image = gus_dma_map[gus_dma];
+		if (!dma_image)
+			printk(KERN_WARNING "Warning! GUS DMA not selected\n");
+
+		tmp = gus_dma_map[gus_dma2] << 3;
+		if (!tmp)
+		{
+			printk(KERN_WARNING "Warning! Invalid GUS MAX DMA\n");
+			tmp = 0x40;		/* Combine DMA channels */
 			    dual_dma_mode = 0;
-		    }
-		  dma_image |= tmp;
-	  }
+		}
+		dma_image |= tmp;
+	}
 
 	/*
 	 * For some reason the IRQ and DMA addresses must be written twice
@@ -848,8 +830,8 @@
 	mix_image &= ~0x02;	/* Enable line out */
 	mix_image |= 0x08;	/* Enable IRQ */
 	outb((mix_image), u_Mixer);	/*
-					   * Turn mixer channels on
-					   * Note! Mic in is left off.
+					 * Turn mixer channels on
+					 * Note! Mic in is left off.
 					 */
 
 	gus_select_voice(0);	/* This disables writes to IRQ/DMA reg */
@@ -869,17 +851,16 @@
 }
 
 
-static void
-pnp_mem_init(void)
+static void pnp_mem_init(void)
 {
 #include "iwmem.h"
 #define CHUNK_SIZE (256*1024)
 #define BANK_SIZE (4*1024*1024)
 #define CHUNKS_PER_BANK (BANK_SIZE/CHUNK_SIZE)
 
-	int             bank, chunk, addr, total = 0;
-	int             bank_sizes[4];
-	int             i, j, bits = -1, nbanks = 0;
+	int bank, chunk, addr, total = 0;
+	int bank_sizes[4];
+	int i, j, bits = -1, nbanks = 0;
 
 /*
  * This routine determines what kind of RAM is installed in each of the four
@@ -902,133 +883,137 @@
  * Perform the DRAM size detection for each bank individually.
  */
 	for (bank = 0; bank < 4; bank++)
-	  {
-		  int             size = 0;
+	{
+		int size = 0;
+
+		addr = bank * BANK_SIZE;
 
-		  addr = bank * BANK_SIZE;
+		/* Clean check points of each chunk */
+		for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
+		{
+			gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
+			gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
+		}
 
-		  /* Clean check points of each chunk */
-		  for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-		    {
-			    gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-			    gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-		    }
-
-		  /* Write a value to each chunk point and verify the result */
-		  for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-		    {
-			    gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
-			    gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
+		/* Write a value to each chunk point and verify the result */
+		for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
+		{
+			gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
+			gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
 
-			    if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
+			if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
 				gus_peek(addr + chunk * CHUNK_SIZE + 1L) == 0xAA)
-			      {	/* OK. There is RAM. Now check for possible shadows */
-				      int             ok = 1, chunk2;
+			{
+				/* OK. There is RAM. Now check for possible shadows */
+				int ok = 1, chunk2;
 
-				      for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
-					      if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
-						  gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
-						      ok = 0;	/* Addressing wraps */
-
-				      if (ok)
-					      size = (chunk + 1) * CHUNK_SIZE;
-			      }
-			    gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-			    gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-		    }
-
-		  bank_sizes[bank] = size;
-		  if (size)
-			  nbanks = bank + 1;
-		  DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
-	  }
+				for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
+					if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
+							gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
+						ok = 0;	/* Addressing wraps */
+
+				if (ok)
+					size = (chunk + 1) * CHUNK_SIZE;
+			}
+			gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
+			gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
+		}
+		bank_sizes[bank] = size;
+		if (size)
+			nbanks = bank + 1;
+		DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
+	}
 
 	if (nbanks == 0)	/* No RAM - Give up */
-	  {
-		  printk("Sound: An Interwave audio chip detected but no DRAM\n");
-		  printk("Sound: Unable to work with this card.\n");
-		  gus_write8(0x19, gus_read8(0x19) & ~0x01);
-		  gus_mem_size = 0;
-		  return;
-	  }
-/*
- * Now we know how much DRAM there is in each bank. The next step is
- * to find a DRAM size encoding (0 to 12) which is best for the combination
- * we have.
- *
- * First try if any of the possible alternatives matches exactly the amount
- * of memory we have.
- */
+	{
+		printk(KERN_ERR "Sound: An Interwave audio chip detected but no DRAM\n");
+		printk(KERN_ERR "Sound: Unable to work with this card.\n");
+		gus_write8(0x19, gus_read8(0x19) & ~0x01);
+		gus_mem_size = 0;
+		return;
+	}
+
+	/*
+	 * Now we know how much DRAM there is in each bank. The next step is
+	 * to find a DRAM size encoding (0 to 12) which is best for the combination
+	 * we have.
+	 *
+	 * First try if any of the possible alternatives matches exactly the amount
+	 * of memory we have.
+	 */
 
 	for (i = 0; bits == -1 && i < 13; i++)
-	  {
-		  bits = i;
+	{
+		bits = i;
 
-		  for (j = 0; bits != -1 && j < 4; j++)
-			  if (mem_decode[i][j] != bank_sizes[j])
-				  bits = -1;	/* No hit */
-	  }
+		for (j = 0; bits != -1 && j < 4; j++)
+			if (mem_decode[i][j] != bank_sizes[j])
+				bits = -1;	/* No hit */
+	}
+
+	/*
+	 * If necessary, try to find a combination where other than the last
+	 * bank matches our configuration and the last bank is left oversized.
+	 * In this way we don't leave holes in the middle of memory.
+	 */
 
-/*
- * If necessary, try to find a combination where other than the last
- * bank matches our configuration and the last bank is left oversized.
- * In this way we don't leave holes in the middle of memory.
- */
 	if (bits == -1)		/* No luck yet */
+	{
 		for (i = 0; bits == -1 && i < 13; i++)
-		  {
-			  bits = 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 (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
-				  bits = -1;	/* The last bank is too small */
-		  }
-/*
- * 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.
- */
+			for (j = 0; bits != -1 && j < nbanks - 1; j++)
+				if (mem_decode[i][j] != bank_sizes[j])
+					bits = -1;	/* No hit */
+			if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
+				bits = -1;	/* The last bank is too small */
+		}
+	}
+	/*
+	 * 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)
-		    {
-			    printk("Interwave: Can't use all installed RAM.\n");
-			    printk("Interwave: Try reordering SIMMS.\n");
-		    }
-	  }
+	{
+		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)
+		{
+			printk(KERN_INFO "Interwave: Can't use all installed RAM.\n");
+			printk(KERN_INFO "Interwave: Try reordering SIMMS.\n");
+		}
+	}
 	if (bits == -1)
-	  {
-		  printk("Interwave: Can't find working DRAM encoding.\n");
-		  printk("Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
-		  bits = 0;
-	  }
+	{
+		printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n");
+		printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
+		bits = 0;
+	}
 	DDB(printk("Interwave: Selecting DRAM addressing mode %d\n", bits));
 
 	for (bank = 0; bank < 4; bank++)
-	  {
-		  DDB(printk("  Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
+	{
+		DDB(printk("  Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
 
-		  if (bank_sizes[bank] > mem_decode[bits][bank])
-			  total += mem_decode[bits][bank];
-		  else
-			  total += bank_sizes[bank];
-	  }
+		if (bank_sizes[bank] > mem_decode[bits][bank])
+			total += mem_decode[bits][bank];
+		else
+			total += bank_sizes[bank];
+	}
 
 	DDB(printk("Total %dk of DRAM (enhanced mode)\n", total / 1024));
-/*
- *    Set the memory addressing mode.
- */
+
+	/*
+	 *    Set the memory addressing mode.
+	 */
 	gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | bits);
 
 /*      Leave the chip into enhanced mode. Disable LFO  */
@@ -1037,8 +1022,7 @@
 	gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02);
 }
 
-int
-gus_wave_detect(int baseaddr)
+int gus_wave_detect(int baseaddr)
 {
 	unsigned long   i, max_mem = 1024L;
 	unsigned long   loc;
@@ -1059,15 +1043,18 @@
 	gus_write8(0x5b, ~val);	/* Invert all bits */
 
 	if ((gus_look8(0x5b) & 0xf0) == (val & 0xf0))	/* No change */
+	{
 		if ((gus_look8(0x5b) & 0x0f) == ((~val) & 0x0f))	/* Change */
-		  {
-			  DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
-			  gus_pnp_flag = 1;
-		} else
-		  {
-			  DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
-			  gus_pnp_flag = 0;
-		  }
+		{
+			DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
+			gus_pnp_flag = 1;
+		}
+		else
+		{
+			DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
+			gus_pnp_flag = 0;
+		}
+	}
 	gus_write8(0x5b, val);	/* Restore all bits */
 #endif
 
@@ -1084,28 +1071,26 @@
 	/* Now zero it out so that I can check for mirroring .. */
 	gus_poke(0L, 0x00);
 	for (i = 1L; i < max_mem; i++)
-	  {
-		  int             n, failed;
+	{
+		int n, failed;
 
-		  /* check for mirroring ... */
-		  if (gus_peek(0L) != 0)
-			  break;
-		  loc = i << 10;
-
-		  for (n = loc - 1, failed = 0; n <= loc; n++)
-		    {
-			    gus_poke(loc, 0xaa);
-			    if (gus_peek(loc) != 0xaa)
-				    failed = 1;
-
-			    gus_poke(loc, 0x55);
-			    if (gus_peek(loc) != 0x55)
-				    failed = 1;
-		    }
+		/* check for mirroring ... */
+		if (gus_peek(0L) != 0)
+			break;
+		loc = i << 10;
 
-		  if (failed)
-			  break;
-	  }
+		for (n = loc - 1, failed = 0; n <= loc; n++)
+		{
+			gus_poke(loc, 0xaa);
+			if (gus_peek(loc) != 0xaa)
+				failed = 1;
+			gus_poke(loc, 0x55);
+			if (gus_peek(loc) != 0x55)
+				failed = 1;
+		}
+		if (failed)
+			break;
+	}
 	gus_mem_size = i << 10;
 	return 1;
 }
@@ -1113,30 +1098,30 @@
 static int guswave_ioctl(int dev, unsigned int cmd, caddr_t arg)
 {
 
-	switch (cmd) {
-	case SNDCTL_SYNTH_INFO:
-		gus_info.nr_voices = nr_voices;
-		return __copy_to_user(arg, &gus_info, sizeof(gus_info));
-
-	case SNDCTL_SEQ_RESETSAMPLES:
-		reset_sample_memory();
-		return 0;
+	switch (cmd) 
+	{
+		case SNDCTL_SYNTH_INFO:
+			gus_info.nr_voices = nr_voices;
+			return copy_to_user(arg, &gus_info, sizeof(gus_info));
+
+		case SNDCTL_SEQ_RESETSAMPLES:
+			reset_sample_memory();
+			return 0;
 
-	case SNDCTL_SEQ_PERCMODE:
-		return 0;
+		case SNDCTL_SEQ_PERCMODE:
+			return 0;
 
-	case SNDCTL_SYNTH_MEMAVL:
-		return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
+		case SNDCTL_SYNTH_MEMAVL:
+			return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
 
-	default:
-		return -EINVAL;
+		default:
+			return -EINVAL;
 	}
 }
 
-static int
-guswave_set_instr(int dev, int voice, int instr_no)
+static int guswave_set_instr(int dev, int voice, int instr_no)
 {
-	int             sample_no;
+	int sample_no;
 
 	if (instr_no < 0 || instr_no > MAX_PATCH)
 		instr_no = 0;	/* Default to acoustic piano */
@@ -1145,103 +1130,97 @@
 		return -EINVAL;
 
 	if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-	  {
-		  voices[voice].sample_pending = instr_no;
-		  return 0;
-	  }
+	{
+		voices[voice].sample_pending = instr_no;
+		return 0;
+	}
 	sample_no = patch_table[instr_no];
 	patch_map[voice] = -1;
 
 	if (sample_no == NOT_SAMPLE)
-	  {
-		  printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);
-		  return -EINVAL;	/* Patch not defined */
-	  }
+	{
+/*		printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);*/
+		return -EINVAL;	/* Patch not defined */
+	}
 	if (sample_ptrs[sample_no] == -1)	/* Sample not loaded */
-	  {
-		  printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);
-		  return -EINVAL;
-	  }
+	{
+/*		printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);*/
+		return -EINVAL;
+	}
 	sample_map[voice] = sample_no;
 	patch_map[voice] = instr_no;
 	return 0;
 }
 
-static int
-guswave_kill_note(int dev, int voice, int note, int velocity)
+static int guswave_kill_note(int dev, int voice, int note, int velocity)
 {
-	unsigned long   flags;
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
 	/* voice_alloc->map[voice] = 0xffff; */
 	if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-	  {
-		  voices[voice].kill_pending = 1;
-		  restore_flags(flags);
-	} else
-	  {
-		  restore_flags(flags);
-		  gus_voice_fade(voice);
-	  }
+	{
+		voices[voice].kill_pending = 1;
+		restore_flags(flags);
+	}
+	else
+	{
+		restore_flags(flags);
+		gus_voice_fade(voice);
+	}
 
 	restore_flags(flags);
 	return 0;
 }
 
-static void
-guswave_aftertouch(int dev, int voice, int pressure)
+static void guswave_aftertouch(int dev, int voice, int pressure)
 {
 }
 
-static void
-guswave_panning(int dev, int voice, int value)
+static void guswave_panning(int dev, int voice, int value)
 {
 	if (voice >= 0 || voice < 32)
 		voices[voice].panning = value;
 }
 
-static void
-guswave_volume_method(int dev, int mode)
+static void guswave_volume_method(int dev, int mode)
 {
 	if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
 		volume_method = mode;
 }
 
-static void
-compute_volume(int voice, int volume)
+static void compute_volume(int voice, int volume)
 {
 	if (volume < 128)
 		voices[voice].midi_volume = volume;
 
 	switch (volume_method)
-	  {
-	  case VOL_METHOD_ADAGIO:
-		  voices[voice].initial_volume =
-		      gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
-				     voices[voice].expression_vol,
-				     voices[voice].patch_vol);
-		  break;
-
-	  case VOL_METHOD_LINEAR:	/* Totally ignores patch-volume and expression */
-		  voices[voice].initial_volume =
-		      gus_linear_vol(volume, voices[voice].main_vol);
-		  break;
-
-	  default:
-		  voices[voice].initial_volume = volume_base +
-		      (voices[voice].midi_volume * volume_scale);
-	  }
+	{
+		case VOL_METHOD_ADAGIO:
+			voices[voice].initial_volume =
+				gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
+					voices[voice].expression_vol,
+					voices[voice].patch_vol);
+			break;
+
+		case VOL_METHOD_LINEAR:	/* Totally ignores patch-volume and expression */
+			voices[voice].initial_volume = gus_linear_vol(volume, voices[voice].main_vol);
+			break;
+
+		default:
+			voices[voice].initial_volume = volume_base +
+				(voices[voice].midi_volume * volume_scale);
+	}
 
 	if (voices[voice].initial_volume > 4030)
 		voices[voice].initial_volume = 4030;
 }
 
-static void
-compute_and_set_volume(int voice, int volume, int ramp_time)
+static void compute_and_set_volume(int voice, int volume, int ramp_time)
 {
-	int             curr, target, rate;
-	unsigned long   flags;
+	int curr, target, rate;
+	unsigned long flags;
 
 	compute_volume(voice, volume);
 	voices[voice].current_volume = voices[voice].initial_volume;
@@ -1249,7 +1228,7 @@
 	save_flags(flags);
 	cli();
 	/*
-	   * CAUTION! Interrupts disabled. Enable them before returning
+	 * CAUTION! Interrupts disabled. Enable them before returning
 	 */
 
 	gus_select_voice(voice);
@@ -1258,12 +1237,12 @@
 	target = voices[voice].initial_volume;
 
 	if (ramp_time == INSTANT_RAMP)
-	  {
-		  gus_rampoff();
-		  gus_voice_volume(target);
-		  restore_flags(flags);
-		  return;
-	  }
+	{
+		gus_rampoff();
+		gus_voice_volume(target);
+		restore_flags(flags);
+		return;
+	}
 	if (ramp_time == FAST_RAMP)
 		rate = 63;
 	else
@@ -1271,34 +1250,34 @@
 	gus_ramp_rate(0, rate);
 
 	if ((target - curr) / 64 == 0)	/* Close enough to target. */
-	  {
-		  gus_rampoff();
-		  gus_voice_volume(target);
-		  restore_flags(flags);
-		  return;
-	  }
+	{
+		gus_rampoff();
+		gus_voice_volume(target);
+		restore_flags(flags);
+		return;
+	}
 	if (target > curr)
-	  {
-		  if (target > (4095 - 65))
-			  target = 4095 - 65;
-		  gus_ramp_range(curr, target);
-		  gus_rampon(0x00);	/* Ramp up, once, no IRQ */
-	} else
-	  {
-		  if (target < 65)
-			  target = 65;
+	{
+		if (target > (4095 - 65))
+			target = 4095 - 65;
+		gus_ramp_range(curr, target);
+		gus_rampon(0x00);	/* Ramp up, once, no IRQ */
+	}
+	else
+	{
+		if (target < 65)
+			target = 65;
 
-		  gus_ramp_range(target, curr);
-		  gus_rampon(0x40);	/* Ramp down, once, no irq */
-	  }
+		gus_ramp_range(target, curr);
+		gus_rampon(0x40);	/* Ramp down, once, no irq */
+	}
 	restore_flags(flags);
 }
 
-static void
-dynamic_volume_change(int voice)
+static void dynamic_volume_change(int voice)
 {
-	unsigned char   status;
-	unsigned long   flags;
+	unsigned char status;
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
@@ -1310,10 +1289,11 @@
 		return;		/* Voice was not running */
 
 	if (!(voices[voice].mode & WAVE_ENVELOPES))
-	  {
-		  compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-		  return;
-	  }
+	{
+		compute_and_set_volume(voice, voices[voice].midi_volume, 1);
+		return;
+	}
+	
 	/*
 	 * Voice is running and has envelopes.
 	 */
@@ -1325,10 +1305,10 @@
 	restore_flags(flags);
 
 	if (status & 0x03)	/* Sustain phase? */
-	  {
-		  compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-		  return;
-	  }
+	{
+		compute_and_set_volume(voice, voices[voice].midi_volume, 1);
+		return;
+	}
 	if (voices[voice].env_phase < 0)
 		return;
 
@@ -1336,8 +1316,7 @@
 
 }
 
-static void
-guswave_controller(int dev, int voice, int ctrl_num, int value)
+static void guswave_controller(int dev, int voice, int ctrl_num, int value)
 {
 	unsigned long   flags;
 	unsigned long   freq;
@@ -1346,88 +1325,84 @@
 		return;
 
 	switch (ctrl_num)
-	  {
-	  case CTRL_PITCH_BENDER:
-		  voices[voice].bender = value;
-
-		  if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-		    {
-			    freq = compute_finetune(voices[voice].orig_freq, value,
-					  voices[voice].bender_range, 0);
-			    voices[voice].current_freq = freq;
-
-			    save_flags(flags);
-			    cli();
-			    gus_select_voice(voice);
-			    gus_voice_freq(freq);
-			    restore_flags(flags);
-		    }
-		  break;
-
-	  case CTRL_PITCH_BENDER_RANGE:
-		  voices[voice].bender_range = value;
-		  break;
-	  case CTL_EXPRESSION:
-		  value /= 128;
-	  case CTRL_EXPRESSION:
-		  if (volume_method == VOL_METHOD_ADAGIO)
-		    {
-			    voices[voice].expression_vol = value;
-			    if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-				    dynamic_volume_change(voice);
-		    }
-		  break;
-
-	  case CTL_PAN:
-		  voices[voice].panning = (value * 2) - 128;
-		  break;
-
-	  case CTL_MAIN_VOLUME:
-		  value = (value * 100) / 16383;
-
-	  case CTRL_MAIN_VOLUME:
-		  voices[voice].main_vol = value;
-		  if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-			  dynamic_volume_change(voice);
-		  break;
+	{
+		case CTRL_PITCH_BENDER:
+			voices[voice].bender = value;
 
-	  default:
-		  break;
-	  }
+			if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
+			{
+				freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0);
+				voices[voice].current_freq = freq;
+
+				save_flags(flags);
+				cli();
+				gus_select_voice(voice);
+				gus_voice_freq(freq);
+				restore_flags(flags);
+			}
+			break;
+
+		case CTRL_PITCH_BENDER_RANGE:
+			voices[voice].bender_range = value;
+			break;
+		case CTL_EXPRESSION:
+			value /= 128;
+		case CTRL_EXPRESSION:
+			if (volume_method == VOL_METHOD_ADAGIO)
+			{
+				voices[voice].expression_vol = value;
+				if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
+					dynamic_volume_change(voice);
+			}
+			break;
+
+		case CTL_PAN:
+			voices[voice].panning = (value * 2) - 128;
+			break;
+
+		case CTL_MAIN_VOLUME:
+			value = (value * 100) / 16383;
+
+		case CTRL_MAIN_VOLUME:
+			voices[voice].main_vol = value;
+			if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
+				dynamic_volume_change(voice);
+			break;
+
+		default:
+			break;
+	}
 }
 
-static int
-guswave_start_note2(int dev, int voice, int note_num, int volume)
+static int guswave_start_note2(int dev, int voice, int note_num, int volume)
 {
-	int             sample, best_sample, best_delta, delta_freq;
-	int             is16bits, samplep, patch, pan;
+	int sample, best_sample, best_delta, delta_freq;
+	int is16bits, samplep, patch, pan;
 	unsigned long   note_freq, base_note, freq, flags;
 	unsigned char   mode = 0;
 
 	if (voice < 0 || voice > 31)
-	  {
-		  printk("GUS: Invalid voice\n");
-		  return -EINVAL;
-	  }
+	{
+/*		printk("GUS: Invalid voice\n");*/
+		return -EINVAL;
+	}
 	if (note_num == 255)
-	  {
-		  if (voices[voice].mode & WAVE_ENVELOPES)
-		    {
-			    voices[voice].midi_volume = volume;
-			    dynamic_volume_change(voice);
-			    return 0;
-		    }
-		  compute_and_set_volume(voice, volume, 1);
-		  return 0;
-	  }
+	{
+		if (voices[voice].mode & WAVE_ENVELOPES)
+		{
+			voices[voice].midi_volume = volume;
+			dynamic_volume_change(voice);
+			return 0;
+		}
+		compute_and_set_volume(voice, volume, 1);
+		return 0;
+	}
 	if ((patch = patch_map[voice]) == -1)
-	  {
-		  return -EINVAL;
-	  }
+		return -EINVAL;
 	if ((samplep = patch_table[patch]) == NOT_SAMPLE)
-	  {
-		  return -EINVAL;
-	  }
+	{
+		return -EINVAL;
+	}
 	note_freq = note_to_freq(note_num);
 
 	/*
@@ -1439,30 +1414,32 @@
 	best_sample = samplep;
 	best_delta = 1000000;
 	while (samplep != 0 && samplep != NOT_SAMPLE && sample == -1)
-	  {
-		  delta_freq = note_freq - samples[samplep].base_note;
-		  if (delta_freq < 0)
-			  delta_freq = -delta_freq;
-		  if (delta_freq < best_delta)
-		    {
-			    best_sample = samplep;
-			    best_delta = delta_freq;
-		    }
-		  if (samples[samplep].low_note <= note_freq &&
-		      note_freq <= samples[samplep].high_note)
-			  sample = samplep;
-		  else
-			  samplep = samples[samplep].key;	/* Link to next sample */
+	{
+		delta_freq = note_freq - samples[samplep].base_note;
+		if (delta_freq < 0)
+			delta_freq = -delta_freq;
+		if (delta_freq < best_delta)
+		{
+			best_sample = samplep;
+			best_delta = delta_freq;
+		}
+		if (samples[samplep].low_note <= note_freq &&
+			note_freq <= samples[samplep].high_note)
+		{
+			sample = samplep;
+		}
+		else
+			samplep = samples[samplep].key;	/* Link to next sample */
 	  }
 	if (sample == -1)
 		sample = best_sample;
 
 	if (sample == -1)
-	  {
-		  printk("GUS: Patch %d not defined for note %d\n", patch, note_num);
-		  return 0;	/* Should play default patch ??? */
-	  }
-	is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
+	{
+/*		printk("GUS: Patch %d not defined for note %d\n", patch, note_num);*/
+		return 0;	/* Should play default patch ??? */
+	}
+	is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
 	voices[voice].mode = samples[sample].mode;
 	voices[voice].patch_vol = samples[sample].volume;
 
@@ -1470,27 +1447,28 @@
 		gus_write8(0x15, 0x00);		/* RAM, Reset voice deactivate bit of SMSI */
 
 	if (voices[voice].mode & WAVE_ENVELOPES)
-	  {
-		  int             i;
+	{
+		int i;
 
-		  for (i = 0; i < 6; i++)
-		    {
-			    voices[voice].env_rate[i] = samples[sample].env_rate[i];
-			    voices[voice].env_offset[i] = samples[sample].env_offset[i];
-		    }
-	  }
+		for (i = 0; i < 6; i++)
+		{
+			voices[voice].env_rate[i] = samples[sample].env_rate[i];
+			voices[voice].env_offset[i] = samples[sample].env_offset[i];
+		}
+	}
 	sample_map[voice] = sample;
 
 	if (voices[voice].fixed_pitch)	/* Fixed pitch */
-	  {
+	{
 		  freq = samples[sample].base_freq;
-	} else
-	  {
-		  base_note = samples[sample].base_note / 100;
-		  note_freq /= 100;
+	}
+	else
+	{
+		base_note = samples[sample].base_note / 100;
+		note_freq /= 100;
 
-		  freq = samples[sample].base_freq * note_freq / base_note;
-	  }
+		freq = samples[sample].base_freq * note_freq / base_note;
+	}
 
 	voices[voice].orig_freq = freq;
 
@@ -1511,15 +1489,15 @@
 		pan = 15;
 
 	if (samples[sample].mode & WAVE_16_BITS)
-	  {
-		  mode |= 0x04;	/* 16 bits */
-		  if ((sample_ptrs[sample] / GUS_BANK_SIZE) !=
-		      ((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
-			  printk("GUS: Sample address error\n");
-	  }
-  /*************************************************************************
-   *    CAUTION!        Interrupts disabled. Don't return before enabling
-   *************************************************************************/
+	{
+		mode |= 0x04;	/* 16 bits */
+		if ((sample_ptrs[sample] / GUS_BANK_SIZE) !=
+			((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
+				printk(KERN_ERR "GUS: Sample address error\n");
+	}
+	/*************************************************************************
+	 *    CAUTION!        Interrupts disabled. Don't return before enabling
+	 *************************************************************************/
 
 	save_flags(flags);
 	cli();
@@ -1530,13 +1508,14 @@
 	restore_flags(flags);
 
 	if (voices[voice].mode & WAVE_ENVELOPES)
-	  {
-		  compute_volume(voice, volume);
-		  init_envelope(voice);
-	} else
-	  {
-		  compute_and_set_volume(voice, volume, 0);
-	  }
+	{
+		compute_volume(voice, volume);
+		init_envelope(voice);
+	}
+	else
+	{
+		compute_and_set_volume(voice, volume, 0);
+	}
 
 	save_flags(flags);
 	cli();
@@ -1544,43 +1523,38 @@
 
 	if (samples[sample].mode & WAVE_LOOP_BACK)
 		gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len -
-			       voices[voice].offset_pending, 0, is16bits);	/* start=end */
+			voices[voice].offset_pending, 0, is16bits);	/* start=end */
 	else
-		gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending,
-			       0, is16bits);	/* Sample start=begin */
+		gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending, 0, is16bits);	/* Sample start=begin */
 
 	if (samples[sample].mode & WAVE_LOOPING)
-	  {
-		  mode |= 0x08;
+	{
+		mode |= 0x08;
 
-		  if (samples[sample].mode & WAVE_BIDIR_LOOP)
-			  mode |= 0x10;
+		if (samples[sample].mode & WAVE_BIDIR_LOOP)
+			mode |= 0x10;
 
-		  if (samples[sample].mode & WAVE_LOOP_BACK)
-		    {
-			    gus_write_addr(0x0a,
-					   sample_ptrs[sample] + samples[sample].loop_end -
+		if (samples[sample].mode & WAVE_LOOP_BACK)
+		{
+			gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].loop_end -
 					   voices[voice].offset_pending,
 					   (samples[sample].fractions >> 4) & 0x0f, is16bits);
-			    mode |= 0x40;
-		    }
-		  gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
-				 samples[sample].fractions & 0x0f,
-				 is16bits);	/* Loop start location */
-		  gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
-				 (samples[sample].fractions >> 4) & 0x0f,
-				 is16bits);	/* Loop end location */
-	} else
-	  {
-		  mode |= 0x20;	/* Loop IRQ at the end */
-		  voices[voice].loop_irq_mode = LMODE_FINISH;	/* Ramp down at the end */
-		  voices[voice].loop_irq_parm = 1;
-		  gus_write_addr(0x02, sample_ptrs[sample],
-				 0, is16bits);	/* Loop start location */
-		  gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
-				 (samples[sample].fractions >> 4) & 0x0f,
-				 is16bits);	/* Loop end location */
-	  }
+			mode |= 0x40;
+		}
+		gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
+			samples[sample].fractions & 0x0f, is16bits);	/* Loop start location */
+		gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
+			(samples[sample].fractions >> 4) & 0x0f, is16bits);	/* Loop end location */
+	}
+	else
+	{
+		mode |= 0x20;	/* Loop IRQ at the end */
+		voices[voice].loop_irq_mode = LMODE_FINISH;	/* Ramp down at the end */
+		voices[voice].loop_irq_parm = 1;
+		gus_write_addr(0x02, sample_ptrs[sample], 0, is16bits);	/* Loop start location */
+		gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
+			(samples[sample].fractions >> 4) & 0x0f, is16bits);	/* Loop end location */
+	}
 	gus_voice_freq(freq);
 	gus_voice_balance(pan);
 	gus_voice_on(mode);
@@ -1595,82 +1569,81 @@
  * ramping.
  */
 
-static int
-guswave_start_note(int dev, int voice, int note_num, int volume)
+static int guswave_start_note(int dev, int voice, int note_num, int volume)
 {
-	long int        flags;
-	int             mode;
-	int             ret_val = 0;
+	long int flags;
+	int mode;
+	int ret_val = 0;
 
 	save_flags(flags);
 	cli();
 	if (note_num == 255)
-	  {
-		  if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-		    {
-			    voices[voice].volume_pending = volume;
-		  } else
-		    {
-			    ret_val = guswave_start_note2(dev, voice, note_num, volume);
-		    }
-	} else
-	  {
-		  gus_select_voice(voice);
-		  mode = gus_read8(0x00);
-		  if (mode & 0x20)
-			  gus_write8(0x00, mode & 0xdf);	/* No interrupt! */
-
-		  voices[voice].offset_pending = 0;
-		  voices[voice].kill_pending = 0;
-		  voices[voice].volume_irq_mode = 0;
-		  voices[voice].loop_irq_mode = 0;
-
-		  if (voices[voice].sample_pending >= 0)
-		    {
-			    restore_flags(flags);	/* Run temporarily with interrupts enabled */
-			    guswave_set_instr(voices[voice].dev_pending, voice,
-					   voices[voice].sample_pending);
-			    voices[voice].sample_pending = -1;
-			    save_flags(flags);
-			    cli();
-			    gus_select_voice(voice);	/* Reselect the voice (just to be sure) */
-		    }
-		  if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
-		    {
-			    ret_val = guswave_start_note2(dev, voice, note_num, volume);
-		  } else
-		    {
-			    voices[voice].dev_pending = dev;
-			    voices[voice].note_pending = note_num;
-			    voices[voice].volume_pending = volume;
-			    voices[voice].volume_irq_mode = VMODE_START_NOTE;
-
-			    gus_rampoff();
-			    gus_ramp_range(2000, 4065);
-			    gus_ramp_rate(0, 63);	/* Fastest possible rate */
-			    gus_rampon(0x20 | 0x40);	/* Ramp down, once, irq */
-		    }
-	  }
+	{
+		if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
+		{
+			voices[voice].volume_pending = volume;
+		}
+		else
+		{
+			ret_val = guswave_start_note2(dev, voice, note_num, volume);
+		}
+	}
+	else
+	{
+		gus_select_voice(voice);
+		mode = gus_read8(0x00);
+		if (mode & 0x20)
+			gus_write8(0x00, mode & 0xdf);	/* No interrupt! */
+
+		voices[voice].offset_pending = 0;
+		voices[voice].kill_pending = 0;
+		voices[voice].volume_irq_mode = 0;
+		voices[voice].loop_irq_mode = 0;
+
+		if (voices[voice].sample_pending >= 0)
+		{
+			restore_flags(flags);	/* Run temporarily with interrupts enabled */
+			guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending);
+			voices[voice].sample_pending = -1;
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);	/* Reselect the voice (just to be sure) */
+		}
+		if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
+		{
+			ret_val = guswave_start_note2(dev, voice, note_num, volume);
+		}
+		else
+		{
+			voices[voice].dev_pending = dev;
+			voices[voice].note_pending = note_num;
+			voices[voice].volume_pending = volume;
+			voices[voice].volume_irq_mode = VMODE_START_NOTE;
+
+			gus_rampoff();
+			gus_ramp_range(2000, 4065);
+			gus_ramp_rate(0, 63);	/* Fastest possible rate */
+			gus_rampon(0x20 | 0x40);	/* Ramp down, once, irq */
+		}
+	}
 	restore_flags(flags);
 	return ret_val;
 }
 
-static void
-guswave_reset(int dev)
+static void guswave_reset(int dev)
 {
-	int             i;
+	int i;
 
 	for (i = 0; i < 32; i++)
-	  {
-		  gus_voice_init(i);
-		  gus_voice_init2(i);
-	  }
+	{
+		gus_voice_init(i);
+		gus_voice_init2(i);
+	}
 }
 
-static int
-guswave_open(int dev, int mode)
+static int guswave_open(int dev, int mode)
 {
-	int             err;
+	int err;
 
 	if (gus_busy)
 		return -EBUSY;
@@ -1678,10 +1651,11 @@
 	voice_alloc->timestamp = 0;
 
 	if ((err = DMAbuf_open_dma(gus_devnum)) < 0)
-	  {
-		  /* printk( "GUS: Loading samples without DMA\n"); */
-		  gus_no_dma = 1;	/* Upload samples using PIO */
-	} else
+	{
+		/* printk( "GUS: Loading samples without DMA\n"); */
+		gus_no_dma = 1;	/* Upload samples using PIO */
+	}
+	else
 		gus_no_dma = 0;
 
 	dram_sleep_flag.opts = WK_NONE;
@@ -1696,8 +1670,7 @@
 	return 0;
 }
 
-static void
-guswave_close(int dev)
+static void guswave_close(int dev)
 {
 	gus_busy = 0;
 	active_device = 0;
@@ -1707,35 +1680,34 @@
 		DMAbuf_close_dma(gus_devnum);
 }
 
-static int
-guswave_load_patch(int dev, int format, const char *addr,
+static int guswave_load_patch(int dev, int format, const char *addr,
 		   int offs, int count, int pmgr_flag)
 {
 	struct patch_info patch;
-	int             instr;
-	long            sizeof_patch;
+	int instr;
+	long sizeof_patch;
 
-	unsigned long   blk_sz, blk_end, left, src_offs, target;
+	unsigned long blk_sz, blk_end, left, src_offs, target;
 
 	sizeof_patch = (long) &patch.data[0] - (long) &patch;	/* Header size */
 
 	if (format != GUS_PATCH)
-	  {
-		  printk("GUS Error: Invalid patch format (key) 0x%x\n", format);
-		  return -EINVAL;
-	  }
+	{
+/*		printk("GUS Error: Invalid patch format (key) 0x%x\n", format);*/
+		return -EINVAL;
+	}
 	if (count < sizeof_patch)
-	  {
-		  printk("GUS Error: Patch header too short\n");
+	{
+/*		  printk("GUS Error: Patch header too short\n");*/
 		  return -EINVAL;
-	  }
+	}
 	count -= sizeof_patch;
 
 	if (free_sample >= MAX_SAMPLE)
-	  {
-		  printk("GUS: Sample table full\n");
+	{
+/*		  printk("GUS: Sample table full\n");*/
 		  return -ENOSPC;
-	  }
+	}
 	/*
 	 * Copy the header from user space but ignore the first bytes which have
 	 * been transferred already.
@@ -1746,63 +1718,63 @@
 	if (patch.mode & WAVE_ROM)
 		return -EINVAL;
 	if (gus_mem_size == 0)
-
 		return -ENOSPC;
 
 	instr = patch.instr_no;
 
 	if (instr < 0 || instr > MAX_PATCH)
-	  {
-		  printk("GUS: Invalid patch number %d\n", instr);
-		  return -EINVAL;
-	  }
+	{
+/*		printk(KERN_ERR "GUS: Invalid patch number %d\n", instr);*/
+		return -EINVAL;
+	}
 	if (count < patch.len)
-	  {
-		  printk("GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);
-		  patch.len = count;
-	  }
+	{
+/*		printk(KERN_ERR "GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);*/
+		patch.len = count;
+	}
 	if (patch.len <= 0 || patch.len > gus_mem_size)
-	  {
-		  printk("GUS: Invalid sample length %d\n", (int) patch.len);
-		  return -EINVAL;
-	  }
+	{
+/*		printk(KERN_ERR "GUS: Invalid sample length %d\n", (int) patch.len);*/
+		return -EINVAL;
+	}
 	if (patch.mode & WAVE_LOOPING)
-	  {
-		  if (patch.loop_start < 0 || patch.loop_start >= patch.len)
-		    {
-			    printk("GUS: Invalid loop start\n");
-			    return -EINVAL;
-		    }
-		  if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
-		    {
-			    printk("GUS: Invalid loop end\n");
-			    return -EINVAL;
-		    }
-	  }
+	{
+		if (patch.loop_start < 0 || patch.loop_start >= patch.len)
+		{
+/*			printk(KERN_ERR "GUS: Invalid loop start\n");*/
+			return -EINVAL;
+		}
+		if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
+		{
+/*			printk(KERN_ERR "GUS: Invalid loop end\n");*/
+			return -EINVAL;
+		}
+	}
 	free_mem_ptr = (free_mem_ptr + 31) & ~31;	/* 32 byte alignment */
 
 	if (patch.mode & WAVE_16_BITS)
-	  {
-		  /*
-		   * 16 bit samples must fit one 256k bank.
-		   */
-		  if (patch.len >= GUS_BANK_SIZE)
-		    {
-			    printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);
-			    return -ENOSPC;
-		    }
-		  if ((free_mem_ptr / GUS_BANK_SIZE) !=
-		      ((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
-		    {
-			    unsigned long   tmp_mem =	/* Align to 256K */
-			    ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
+	{
+		/*
+		 * 16 bit samples must fit one 256k bank.
+		 */
+		if (patch.len >= GUS_BANK_SIZE)
+		{
+/*			 printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);*/
+			return -ENOSPC;
+		}
+		if ((free_mem_ptr / GUS_BANK_SIZE) !=
+			((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
+		{
+			unsigned long   tmp_mem =	
+				/* Align to 256K */
+					((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
 
-			    if ((tmp_mem + patch.len) > gus_mem_size)
-				    return -ENOSPC;
+			if ((tmp_mem + patch.len) > gus_mem_size)
+				return -ENOSPC;
 
-			    free_mem_ptr = tmp_mem;	/* This leaves unusable memory */
-		    }
-	  }
+			free_mem_ptr = tmp_mem;		/* This leaves unusable memory */
+		}
+	}
 	if ((free_mem_ptr + patch.len) > gus_mem_size)
 		return -ENOSPC;
 
@@ -1816,9 +1788,9 @@
 		patch.mode &= ~WAVE_TREMOLO;
 
 	if (!(patch.mode & WAVE_FRACTIONS))
-	  {
+	{
 		  patch.fractions = 0;
-	  }
+	}
 	memcpy((char *) &samples[free_sample], &patch, sizeof_patch);
 
 	/*
@@ -1837,162 +1809,154 @@
 	target = free_mem_ptr;
 
 	while (left)		/* Not completely transferred yet */
-	  {
-		  blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
-		  if (blk_sz > left)
-			  blk_sz = left;
-
-		  /*
-		   * DMA cannot cross bank (256k) boundaries. Check for that.
-		   */
-		  blk_end = target + blk_sz;
-
-		  if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE))
-		    {		/* Split the block */
-
-			    blk_end &= ~(GUS_BANK_SIZE - 1);
-			    blk_sz = blk_end - target;
-		    }
-		  if (gus_no_dma)
-		    {
-			    /*
-			     * For some reason the DMA is not possible. We have to use PIO.
-			     */
-			    long            i;
-			    unsigned char   data;
-
-			    for (i = 0; i < blk_sz; i++)
-			      {
-				      get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[sizeof_patch + i]));
-				      if (patch.mode & WAVE_UNSIGNED)
-					      if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
-						      data ^= 0x80;	/* Convert to signed */
-				      gus_poke(target + i, data);
-			      }
-		  } else
-		    {
-			    unsigned long   address, hold_address;
-			    unsigned char   dma_command;
-			    unsigned long   flags;
-
-			    if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL)
-			      {
-				      printk("GUS: DMA buffer == NULL\n");
-				      return -ENOSPC;
-			      }
-			    /*
-			     * OK, move now. First in and then out.
-			     */
-
-			    copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf, &(addr)[sizeof_patch + src_offs], blk_sz);
-
-			    save_flags(flags);
-			    cli();
-/******** INTERRUPTS DISABLED NOW ********/
-			    gus_write8(0x41, 0);	/* Disable GF1 DMA */
-			    DMAbuf_start_dma(gus_devnum,
-					     audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
-					     blk_sz, DMA_MODE_WRITE);
-
-			    /*
-			     * Set the DRAM address for the wave data
-			     */
-
-			    if (iw_mode)
-			      {
-				      /* Different address translation in enhanced mode */
-
-				      unsigned char   hi;
-
-				      if (gus_dma > 4)
-					      address = target >> 1;	/* Convert to 16 bit word address */
-				      else
-					      address = target;
-
-				      hi = (unsigned char) ((address >> 16) & 0xf0);
-				      hi += (unsigned char) (address & 0x0f);
-
-				      gus_write16(0x42, (address >> 4) & 0xffff);	/* DMA address (low) */
-				      gus_write8(0x50, hi);
-			    } else
-			      {
-				      address = target;
+	{
+		blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
+		if (blk_sz > left)
+			blk_sz = left;
 
-				      if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-					{
-						hold_address = address;
-						address = address >> 1;
-						address &= 0x0001ffffL;
-						address |= (hold_address & 0x000c0000L);
-					}
-				      gus_write16(0x42, (address >> 4) & 0xffff);	/* DRAM DMA address */
-			      }
+		/*
+		 * DMA cannot cross bank (256k) boundaries. Check for that.
+		 */
+		 
+		blk_end = target + blk_sz;
 
-			    /*
-			     * Start the DMA transfer
-			     */
-
-			    dma_command = 0x21;		/* IRQ enable, DMA start */
-			    if (patch.mode & WAVE_UNSIGNED)
-				    dma_command |= 0x80;	/* Invert MSB */
-			    if (patch.mode & WAVE_16_BITS)
-				    dma_command |= 0x40;	/* 16 bit _DATA_ */
-			    if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-				    dma_command |= 0x04;	/* 16 bit DMA _channel_ */
-
-			    gus_write8(0x41, dma_command);	/* Lets go luteet (=bugs) */
-
-			    /*
-			     * Sleep here until the DRAM DMA done interrupt is served
-			     */
-			    active_device = GUS_DEV_WAVE;
-
-
-			    {
-				    unsigned long   tlimit;
-
-				    if (HZ)
-					    current->timeout = tlimit = jiffies + (HZ);
-				    else
-					    tlimit = (unsigned long) -1;
-				    dram_sleep_flag.opts = WK_SLEEP;
-				    interruptible_sleep_on(&dram_sleeper);
-				    if (!(dram_sleep_flag.opts & WK_WAKEUP))
-				      {
-					      if (jiffies >= tlimit)
-						      dram_sleep_flag.opts |= WK_TIMEOUT;
-				      }
-				    dram_sleep_flag.opts &= ~WK_SLEEP;
-			    };
-			    if ((dram_sleep_flag.opts & WK_TIMEOUT))
-				    printk("GUS: DMA Transfer timed out\n");
-			    restore_flags(flags);
-		    }
-
-		  /*
-		   * Now the next part
-		   */
-
-		  left -= blk_sz;
-		  src_offs += blk_sz;
-		  target += blk_sz;
+		if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE))
+		{
+			/* Split the block */
+			blk_end &= ~(GUS_BANK_SIZE - 1);
+			blk_sz = blk_end - target;
+		}
+		if (gus_no_dma)
+		{
+			/*
+			 * For some reason the DMA is not possible. We have to use PIO.
+			 */
+			long i;
+			unsigned char data;
 
-		  gus_write8(0x41, 0);	/* Stop DMA */
-	  }
+			for (i = 0; i < blk_sz; i++)
+			{
+				get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[sizeof_patch + i]));
+				if (patch.mode & WAVE_UNSIGNED)
+					if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
+						data ^= 0x80;	/* Convert to signed */
+				gus_poke(target + i, data);
+			}
+		}
+		else
+		{
+			unsigned long address, hold_address;
+			unsigned char dma_command;
+			unsigned long flags;
+			unsigned long tlimit;
 
-	free_mem_ptr += patch.len;
+			if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL)
+			{
+				printk(KERN_ERR "GUS: DMA buffer == NULL\n");
+				return -ENOSPC;
+			}
+			/*
+			 * OK, move now. First in and then out.
+			 */
+
+			copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf, &(addr)[sizeof_patch + src_offs], blk_sz);
+
+			save_flags(flags);
+			cli();
+			/******** INTERRUPTS DISABLED NOW ********/
+			gus_write8(0x41, 0);	/* Disable GF1 DMA */
+			DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
+				blk_sz, DMA_MODE_WRITE);
+
+			/*
+			 * Set the DRAM address for the wave data
+			 */
 
+			if (iw_mode)
+			{
+				/* Different address translation in enhanced mode */
+
+				unsigned char   hi;
+
+				if (gus_dma > 4)
+					address = target >> 1;	/* Convert to 16 bit word address */
+				else
+					address = target;
+
+				hi = (unsigned char) ((address >> 16) & 0xf0);
+				hi += (unsigned char) (address & 0x0f);
+
+				gus_write16(0x42, (address >> 4) & 0xffff);	/* DMA address (low) */
+				gus_write8(0x50, hi);
+			}
+			else
+			{
+				address = target;
+				if (audio_devs[gus_devnum]->dmap_out->dma > 3)
+				{
+					hold_address = address;
+					address = address >> 1;
+					address &= 0x0001ffffL;
+					address |= (hold_address & 0x000c0000L);
+				}
+				gus_write16(0x42, (address >> 4) & 0xffff);	/* DRAM DMA address */
+			}
+
+			/*
+			 * Start the DMA transfer
+			 */
+
+			dma_command = 0x21;		/* IRQ enable, DMA start */
+			if (patch.mode & WAVE_UNSIGNED)
+				dma_command |= 0x80;	/* Invert MSB */
+			if (patch.mode & WAVE_16_BITS)
+				dma_command |= 0x40;	/* 16 bit _DATA_ */
+			if (audio_devs[gus_devnum]->dmap_out->dma > 3)
+				dma_command |= 0x04;	/* 16 bit DMA _channel_ */
+			
+			gus_write8(0x41, dma_command);	/* Lets go luteet (=bugs) */
+
+			/*
+			 * Sleep here until the DRAM DMA done interrupt is served
+			 */
+			active_device = GUS_DEV_WAVE;
+
+			current->timeout = tlimit = jiffies + HZ;
+			dram_sleep_flag.opts = WK_SLEEP;
+			interruptible_sleep_on(&dram_sleeper);
+			if (!(dram_sleep_flag.opts & WK_WAKEUP))
+			{
+				if (jiffies >= tlimit)
+					dram_sleep_flag.opts |= WK_TIMEOUT;
+			}
+			dram_sleep_flag.opts &= ~WK_SLEEP;
+			if ((dram_sleep_flag.opts & WK_TIMEOUT))
+				printk(KERN_WARNING "GUS: DMA Transfer timed out\n");
+			restore_flags(flags);
+		}
+
+		/*
+		 * Now the next part
+		 */
+
+		left -= blk_sz;
+		src_offs += blk_sz;
+		target += blk_sz;
+
+		gus_write8(0x41, 0);	/* Stop DMA */
+	}
+
+	free_mem_ptr += patch.len;
 	free_sample++;
 	return 0;
 }
 
-static void
-guswave_hw_control(int dev, unsigned char *event_rec)
+static void guswave_hw_control(int dev, unsigned char *event_rec)
 {
-	int             voice, cmd;
-	unsigned short  p1, p2;
-	unsigned int    plong;
-	unsigned        flags;
+	int voice, cmd;
+	unsigned short p1, p2;
+	unsigned int plong;
+	unsigned flags;
 
 	cmd = event_rec[2];
 	voice = event_rec[3];
@@ -2001,156 +1965,152 @@
 	plong = *(unsigned int *) &event_rec[4];
 
 	if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
-	    (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
+		(cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
 		do_volume_irq(voice);
 
 	switch (cmd)
-	  {
+	{
+		case _GUS_NUMVOICES:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_select_max_voices(p1);
+			restore_flags(flags);
+			break;
+
+		case _GUS_VOICESAMPLE:
+			guswave_set_instr(dev, voice, p1);
+			break;
 
-	  case _GUS_NUMVOICES:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_select_max_voices(p1);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOICESAMPLE:
-		  guswave_set_instr(dev, voice, p1);
-		  break;
-
-	  case _GUS_VOICEON:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  p1 &= ~0x20;	/* Don't allow interrupts */
-		  gus_voice_on(p1);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOICEOFF:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_voice_off();
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOICEFADE:
-		  gus_voice_fade(voice);
-		  break;
-
-	  case _GUS_VOICEMODE:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  p1 &= ~0x20;	/* Don't allow interrupts */
-		  gus_voice_mode(p1);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOICEBALA:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_voice_balance(p1);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOICEFREQ:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_voice_freq(plong);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOICEVOL:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_voice_volume(p1);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOICEVOL2:	/* Just update the software voice level */
-		  voices[voice].initial_volume =
-		      voices[voice].current_volume = p1;
-		  break;
-
-	  case _GUS_RAMPRANGE:
-		  if (voices[voice].mode & WAVE_ENVELOPES)
-			  break;	/* NO-NO */
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_ramp_range(p1, p2);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_RAMPRATE:
-		  if (voices[voice].mode & WAVE_ENVELOPES)
-			  break;	/* NJET-NJET */
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_ramp_rate(p1, p2);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_RAMPMODE:
-		  if (voices[voice].mode & WAVE_ENVELOPES)
-			  break;	/* NO-NO */
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  p1 &= ~0x20;	/* Don't allow interrupts */
-		  gus_ramp_mode(p1);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_RAMPON:
-		  if (voices[voice].mode & WAVE_ENVELOPES)
-			  break;	/* EI-EI */
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  p1 &= ~0x20;	/* Don't allow interrupts */
-		  gus_rampon(p1);
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_RAMPOFF:
-		  if (voices[voice].mode & WAVE_ENVELOPES)
-			  break;	/* NEJ-NEJ */
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_rampoff();
-		  restore_flags(flags);
-		  break;
-
-	  case _GUS_VOLUME_SCALE:
-		  volume_base = p1;
-		  volume_scale = p2;
-		  break;
-
-	  case _GUS_VOICE_POS:
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(voice);
-		  gus_set_voice_pos(voice, plong);
-		  restore_flags(flags);
-		  break;
+		case _GUS_VOICEON:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			p1 &= ~0x20;	/* Don't allow interrupts */
+			gus_voice_on(p1);
+			restore_flags(flags);
+			break;
 
-	  default:;
-	  }
+		case _GUS_VOICEOFF:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_voice_off();
+			restore_flags(flags);
+			break;
+
+		case _GUS_VOICEFADE:
+			gus_voice_fade(voice);
+			break;
+
+		case _GUS_VOICEMODE:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			p1 &= ~0x20;	/* Don't allow interrupts */
+			gus_voice_mode(p1);
+			restore_flags(flags);
+			break;
+
+		case _GUS_VOICEBALA:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_voice_balance(p1);
+			restore_flags(flags);
+			break;
+
+		case _GUS_VOICEFREQ:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_voice_freq(plong);
+			restore_flags(flags);
+			break;
+
+		case _GUS_VOICEVOL:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_voice_volume(p1);
+			restore_flags(flags);
+			break;
+
+		case _GUS_VOICEVOL2:	/* Just update the software voice level */
+			voices[voice].initial_volume = voices[voice].current_volume = p1;
+			break;
+
+		case _GUS_RAMPRANGE:
+			if (voices[voice].mode & WAVE_ENVELOPES)
+				break;	/* NO-NO */
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_ramp_range(p1, p2);
+			restore_flags(flags);
+			break;
+
+		case _GUS_RAMPRATE:
+			if (voices[voice].mode & WAVE_ENVELOPES)
+				break;	/* NJET-NJET */
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_ramp_rate(p1, p2);
+			restore_flags(flags);
+			break;
+
+		case _GUS_RAMPMODE:
+			if (voices[voice].mode & WAVE_ENVELOPES)
+				break;	/* NO-NO */
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			p1 &= ~0x20;	/* Don't allow interrupts */
+			gus_ramp_mode(p1);
+			restore_flags(flags);
+			break;
+
+		case _GUS_RAMPON:
+			if (voices[voice].mode & WAVE_ENVELOPES)
+				break;	/* EI-EI */
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			p1 &= ~0x20;	/* Don't allow interrupts */
+			gus_rampon(p1);
+			restore_flags(flags);
+			break;
+
+		case _GUS_RAMPOFF:
+			if (voices[voice].mode & WAVE_ENVELOPES)
+				break;	/* NEJ-NEJ */
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_rampoff();
+			restore_flags(flags);
+			break;
+
+		case _GUS_VOLUME_SCALE:
+			volume_base = p1;
+			volume_scale = p2;
+			break;
+
+		case _GUS_VOICE_POS:
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_set_voice_pos(voice, plong);
+			restore_flags(flags);
+			break;
+
+		default:
+	}
 }
 
-static int
-gus_audio_set_speed(int speed)
+static int gus_audio_set_speed(int speed)
 {
-
 	if (speed <= 0)
 		speed = gus_audio_speed;
 
@@ -2163,18 +2123,17 @@
 	gus_audio_speed = speed;
 
 	if (only_read_access)
-	  {
-		  /* Compute nearest valid recording speed  and return it */
+	{
+		/* Compute nearest valid recording speed  and return it */
 
-		  /* speed = (9878400 / (gus_audio_speed + 2)) / 16; */
-		  speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
-		  speed = (9878400 / (speed * 16)) - 2;
-	  }
+		/* speed = (9878400 / (gus_audio_speed + 2)) / 16; */
+		speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
+		speed = (9878400 / (speed * 16)) - 2;
+	}
 	return speed;
 }
 
-static int
-gus_audio_set_channels(int channels)
+static int gus_audio_set_channels(int channels)
 {
 	if (!channels)
 		return gus_audio_channels;
@@ -2186,8 +2145,7 @@
 	return channels;
 }
 
-static int
-gus_audio_set_bits(int bits)
+static int gus_audio_set_bits(int bits)
 {
 	if (!bits)
 		return gus_audio_bits;
@@ -2206,70 +2164,75 @@
 {
 	int val;
 
-	switch (cmd) {
-	case SOUND_PCM_WRITE_RATE:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		val = gus_audio_set_speed(val);
-		return __put_user(val, (int *)arg);
+	switch (cmd) 
+	{
+		case SOUND_PCM_WRITE_RATE:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			val = gus_audio_set_speed(val);
+			break;
 
-	case SOUND_PCM_READ_RATE:
-		return __put_user(gus_audio_speed, (int *)arg);
+		case SOUND_PCM_READ_RATE:
+			val = gus_audio_speed;
+			break;
 
-	case SNDCTL_DSP_STEREO:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		val = gus_audio_set_channels(val + 1) - 1;
-		return __put_user(val, (int *)arg);
+		case SNDCTL_DSP_STEREO:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			val = gus_audio_set_channels(val + 1) - 1;
+			break;
 
-	case SOUND_PCM_WRITE_CHANNELS:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		val = gus_audio_set_channels(val);
-		return __put_user(val, (int *)arg);
+		case SOUND_PCM_WRITE_CHANNELS:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			val = gus_audio_set_channels(val);
+			break;
 
-	case SOUND_PCM_READ_CHANNELS:
-		return __put_user(gus_audio_channels, (int *)arg);
+		case SOUND_PCM_READ_CHANNELS:
+			val = gus_audio_channels;
+			break;
 		
-	case SNDCTL_DSP_SETFMT:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		val = gus_audio_set_bits(val);
-		return __put_user(val, (int *)arg);
+		case SNDCTL_DSP_SETFMT:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			val = gus_audio_set_bits(val);
+			break;
 		
-	case SOUND_PCM_READ_BITS:
-		return __put_user(gus_audio_bits, (int *)arg);
+		case SOUND_PCM_READ_BITS:
+			val = gus_audio_bits;
+			break;
 		
-	case SOUND_PCM_WRITE_FILTER:		/* NOT POSSIBLE */
-	case SOUND_PCM_READ_FILTER:
-		return __put_user(-EINVAL, (int *)arg);
+		case SOUND_PCM_WRITE_FILTER:		/* NOT POSSIBLE */
+		case SOUND_PCM_READ_FILTER:
+			val = -EINVAL;
+			break;
+		default:
+			return -EINVAL;
 	}
-	return -EINVAL;
+	return put_user(val, (int *)arg);
 }
 
-static void
-gus_audio_reset(int dev)
+static void gus_audio_reset(int dev)
 {
 	if (recording_active)
-	  {
-		  gus_write8(0x49, 0x00);	/* Halt recording */
-		  set_input_volumes();
-	  }
+	{
+		gus_write8(0x49, 0x00);	/* Halt recording */
+		set_input_volumes();
+	}
 }
 
-static int      saved_iw_mode;	/* A hack hack hack */
+static int saved_iw_mode;	/* A hack hack hack */
 
-static int
-gus_audio_open(int dev, int mode)
+static int gus_audio_open(int dev, int mode)
 {
 	if (gus_busy)
 		return -EBUSY;
 
 	if (gus_pnp_flag && mode & OPEN_READ)
-	  {
-		  printk("GUS: Audio device #%d is playback only.\n", dev);
-		  return -EIO;
-	  }
+	{
+/*		printk(KERN_ERR "GUS: Audio device #%d is playback only.\n", dev);*/
+		return -EIO;
+	}
 	gus_initialize();
 
 	gus_busy = 1;
@@ -2280,19 +2243,19 @@
 	gus_select_max_voices(14);
 	saved_iw_mode = iw_mode;
 	if (iw_mode)
-	  {
-		  /* There are some problems with audio in enhanced mode so disable it */
-		  gus_write8(0x19, gus_read8(0x19) & ~0x01);	/* Disable enhanced mode */
-		  iw_mode = 0;
-	  }
+	{
+		/* There are some problems with audio in enhanced mode so disable it */
+		gus_write8(0x19, gus_read8(0x19) & ~0x01);	/* Disable enhanced mode */
+		iw_mode = 0;
+	}
 	pcm_active = 0;
 	dma_active = 0;
 	pcm_opened = 1;
 	if (mode & OPEN_READ)
-	  {
-		  recording_active = 1;
-		  set_input_volumes();
-	  }
+	{
+		recording_active = 1;
+		set_input_volumes();
+	}
 	only_read_access = !(mode & OPEN_WRITE);
 	only_8_bits = mode & OPEN_READ;
 	if (only_8_bits)
@@ -2303,8 +2266,7 @@
 	return 0;
 }
 
-static void
-gus_audio_close(int dev)
+static void gus_audio_close(int dev)
 {
 	iw_mode = saved_iw_mode;
 	gus_reset();
@@ -2313,40 +2275,38 @@
 	active_device = 0;
 
 	if (recording_active)
-	  {
-		  gus_write8(0x49, 0x00);	/* Halt recording */
-		  set_input_volumes();
-	  }
+	{
+		gus_write8(0x49, 0x00);	/* Halt recording */
+		set_input_volumes();
+	}
 	recording_active = 0;
 }
 
-static void
-gus_audio_update_volume(void)
+static void gus_audio_update_volume(void)
 {
-	unsigned long   flags;
-	int             voice;
+	unsigned long flags;
+	int voice;
 
 	if (pcm_active && pcm_opened)
 		for (voice = 0; voice < gus_audio_channels; voice++)
-		  {
-			  save_flags(flags);
-			  cli();
-			  gus_select_voice(voice);
-			  gus_rampoff();
-			  gus_voice_volume(1530 + (25 * gus_pcm_volume));
-			  gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-			  restore_flags(flags);
-		  }
+		{
+			save_flags(flags);
+			cli();
+			gus_select_voice(voice);
+			gus_rampoff();
+			gus_voice_volume(1530 + (25 * gus_pcm_volume));
+			gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
+			restore_flags(flags);
+		}
 }
 
-static void
-play_next_pcm_block(void)
+static void play_next_pcm_block(void)
 {
-	unsigned long   flags;
-	int             speed = gus_audio_speed;
-	int             this_one, is16bits, chn;
-	unsigned long   dram_loc;
-	unsigned char   mode[2], ramp_mode[2];
+	unsigned long flags;
+	int speed = gus_audio_speed;
+	int this_one, is16bits, chn;
+	unsigned long dram_loc;
+	unsigned char mode[2], ramp_mode[2];
 
 	if (!pcm_qlen)
 		return;
@@ -2354,95 +2314,91 @@
 	this_one = pcm_head;
 
 	for (chn = 0; chn < gus_audio_channels; chn++)
-	  {
-		  mode[chn] = 0x00;
-		  ramp_mode[chn] = 0x03;	/* Ramping and rollover off */
-
-		  if (chn == 0)
-		    {
-			    mode[chn] |= 0x20;	/* Loop IRQ */
-			    voices[chn].loop_irq_mode = LMODE_PCM;
-		    }
-		  if (gus_audio_bits != 8)
-		    {
-			    is16bits = 1;
-			    mode[chn] |= 0x04;	/* 16 bit data */
-		  } else
-			  is16bits = 0;
-
-		  dram_loc = this_one * pcm_bsize;
-		  dram_loc += chn * pcm_banksize;
-
-		  if (this_one == (pcm_nblk - 1))	/* Last fragment of the DRAM buffer */
-		    {
-			    mode[chn] |= 0x08;	/* Enable loop */
-			    ramp_mode[chn] = 0x03;	/* Disable rollover bit */
-		  } else
-		    {
-			    if (chn == 0)
-				    ramp_mode[chn] = 0x04;	/* Enable rollover bit */
-		    }
-
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(chn);
-		  gus_voice_freq(speed);
-
-		  if (gus_audio_channels == 1)
-			  gus_voice_balance(7);		/* mono */
-		  else if (chn == 0)
-			  gus_voice_balance(0);		/* left */
-		  else
-			  gus_voice_balance(15);	/* right */
-
-		  if (!pcm_active)	/* Playback not already active */
-		    {
-			    /*
-			     * The playback was not started yet (or there has been a pause).
-			     * Start the voice (again) and ask for a rollover irq at the end of
-			     * this_one block. If this_one one is last of the buffers, use just
-			     * the normal loop with irq.
-			     */
-
-			    gus_voice_off();
-			    gus_rampoff();
-			    gus_voice_volume(1530 + (25 * gus_pcm_volume));
-			    gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
+	{
+		mode[chn] = 0x00;
+		ramp_mode[chn] = 0x03;	/* Ramping and rollover off */
 
-			    gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits);	/* Starting position */
-			    gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits);	/* Loop start */
+		if (chn == 0)
+		{
+			mode[chn] |= 0x20;	/* Loop IRQ */
+			voices[chn].loop_irq_mode = LMODE_PCM;
+		}
+		if (gus_audio_bits != 8)
+		{
+			is16bits = 1;
+			mode[chn] |= 0x04;	/* 16 bit data */
+		}
+		else
+			is16bits = 0;
 
-			    if (chn != 0)
-				    gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
-						   0, is16bits);	/* Loop end location */
-		    }
-		  if (chn == 0)
-			  gus_write_addr(0x04, dram_loc + pcm_bsize - 1,
-					 0, is16bits);	/* Loop end location */
-		  else
-			  mode[chn] |= 0x08;	/* Enable looping */
+		dram_loc = this_one * pcm_bsize;
+		dram_loc += chn * pcm_banksize;
 
+		if (this_one == (pcm_nblk - 1))	/* Last fragment of the DRAM buffer */
+		{
+			mode[chn] |= 0x08;	/* Enable loop */
+			ramp_mode[chn] = 0x03;	/* Disable rollover bit */
+		}
+		else
+		{
+			if (chn == 0)
+				ramp_mode[chn] = 0x04;	/* Enable rollover bit */
+		}
+		save_flags(flags);
+		cli();
+		gus_select_voice(chn);
+		gus_voice_freq(speed);
+
+		if (gus_audio_channels == 1)
+			gus_voice_balance(7);		/* mono */
+		else if (chn == 0)
+			gus_voice_balance(0);		/* left */
+		else
+			gus_voice_balance(15);		/* right */
 
-		  restore_flags(flags);
-	  }
+		if (!pcm_active)	/* Playback not already active */
+		{
+			/*
+			 * The playback was not started yet (or there has been a pause).
+			 * Start the voice (again) and ask for a rollover irq at the end of
+			 * this_one block. If this_one one is last of the buffers, use just
+			 * the normal loop with irq.
+			 */
+
+			gus_voice_off();
+			gus_rampoff();
+			gus_voice_volume(1530 + (25 * gus_pcm_volume));
+			gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
 
-	for (chn = 0; chn < gus_audio_channels; chn++)
-	  {
-		  save_flags(flags);
-		  cli();
-		  gus_select_voice(chn);
-		  gus_write8(0x0d, ramp_mode[chn]);
-		  if (iw_mode)
-			  gus_write8(0x15, 0x00);	/* Reset voice deactivate bit of SMSI */
-		  gus_voice_on(mode[chn]);
-		  restore_flags(flags);
-	  }
+			gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits);	/* Starting position */
+			gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits);	/* Loop start */
 
+			if (chn != 0)
+				gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
+						   0, is16bits);	/* Loop end location */
+		}
+		if (chn == 0)
+			gus_write_addr(0x04, dram_loc + pcm_bsize - 1,
+					 0, is16bits);	/* Loop end location */
+		else
+			mode[chn] |= 0x08;	/* Enable looping */
+		restore_flags(flags);
+	}
+	for (chn = 0; chn < gus_audio_channels; chn++)
+	{
+		save_flags(flags);
+		cli();
+		gus_select_voice(chn);
+		gus_write8(0x0d, ramp_mode[chn]);
+		if (iw_mode)
+			gus_write8(0x15, 0x00);	/* Reset voice deactivate bit of SMSI */
+		gus_voice_on(mode[chn]);
+		restore_flags(flags);
+	}
 	pcm_active = 1;
 }
 
-static void
-gus_transfer_output_block(int dev, unsigned long buf,
+static void gus_transfer_output_block(int dev, unsigned long buf,
 			  int total_count, int intrflag, int chn)
 {
 	/*
@@ -2454,10 +2410,10 @@
 	 * right data to the area pointed by gus_page_size.
 	 */
 
-	int             this_one, count;
-	unsigned long   flags;
-	unsigned char   dma_command;
-	unsigned long   address, hold_address;
+	int this_one, count;
+	unsigned long flags;
+	unsigned char dma_command;
+	unsigned long address, hold_address;
 
 	save_flags(flags);
 	cli();
@@ -2465,15 +2421,16 @@
 	count = total_count / gus_audio_channels;
 
 	if (chn == 0)
-	  {
-		  if (pcm_qlen >= pcm_nblk)
-			  printk("GUS Warning: PCM buffers out of sync\n");
-
-		  this_one = pcm_current_block = pcm_tail;
-		  pcm_qlen++;
-		  pcm_tail = (pcm_tail + 1) % pcm_nblk;
-		  pcm_datasize[this_one] = count;
-	} else
+	{
+		if (pcm_qlen >= pcm_nblk)
+			printk(KERN_WARNING "GUS Warning: PCM buffers out of sync\n");
+
+		this_one = pcm_current_block = pcm_tail;
+		pcm_qlen++;
+		pcm_tail = (pcm_tail + 1) % pcm_nblk;
+		pcm_datasize[this_one] = count;
+	}
+	else
 		this_one = pcm_current_block;
 
 	gus_write8(0x41, 0);	/* Disable GF1 DMA */
@@ -2483,12 +2440,12 @@
 	address += chn * pcm_banksize;
 
 	if (audio_devs[dev]->dmap_out->dma > 3)
-	  {
-		  hold_address = address;
-		  address = address >> 1;
-		  address &= 0x0001ffffL;
-		  address |= (hold_address & 0x000c0000L);
-	  }
+	{
+		hold_address = address;
+		address = address >> 1;
+		address &= 0x0001ffffL;
+		address |= (hold_address & 0x000c0000L);
+	}
 	gus_write16(0x42, (address >> 4) & 0xffff);	/* DRAM DMA address */
 
 	dma_command = 0x21;	/* IRQ enable, DMA start */
@@ -2504,62 +2461,60 @@
 	gus_write8(0x41, dma_command);	/* Kick start */
 
 	if (chn == (gus_audio_channels - 1))	/* Last channel */
-	  {
-		  /*
-		   * Last (right or mono) channel data
-		   */
-		  dma_active = 1;	/* DMA started. There is a unacknowledged buffer */
-		  active_device = GUS_DEV_PCM_DONE;
-		  if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize))
-		    {
-			    play_next_pcm_block();
-		    }
-	} else
-	  {
-		  /*
-		     * Left channel data. The right channel
-		     * is transferred after DMA interrupt
-		   */
-		  active_device = GUS_DEV_PCM_CONTINUE;
-	  }
+	{
+		/*
+		 * Last (right or mono) channel data
+		 */
+		dma_active = 1;	/* DMA started. There is a unacknowledged buffer */
+		active_device = GUS_DEV_PCM_DONE;
+		if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize))
+		{
+			play_next_pcm_block();
+		}
+	}
+	else
+	{
+		/*
+		 * Left channel data. The right channel
+		 * is transferred after DMA interrupt
+		 */
+		active_device = GUS_DEV_PCM_CONTINUE;
+	}
 
 	restore_flags(flags);
 }
 
-static void
-gus_uninterleave8(char *buf, int l)
+static void gus_uninterleave8(char *buf, int l)
 {
 /* This routine uninterleaves 8 bit stereo output (LRLRLR->LLLRRR) */
-	int             i, p = 0, halfsize = l / 2;
-	char           *buf2 = buf + halfsize, *src = bounce_buf;
+	int i, p = 0, halfsize = l / 2;
+	char *buf2 = buf + halfsize, *src = bounce_buf;
 
 	memcpy(bounce_buf, buf, l);
 
 	for (i = 0; i < halfsize; i++)
-	  {
-		  buf[i] = src[p++];	/* Left channel */
-		  buf2[i] = src[p++];	/* Right channel */
-	  }
+	{
+		buf[i] = src[p++];	/* Left channel */
+		buf2[i] = src[p++];	/* Right channel */
+	}
 }
 
-static void
-gus_uninterleave16(short *buf, int l)
+static void gus_uninterleave16(short *buf, int l)
 {
 /* This routine uninterleaves 16 bit stereo output (LRLRLR->LLLRRR) */
-	int             i, p = 0, halfsize = l / 2;
-	short          *buf2 = buf + halfsize, *src = (short *) bounce_buf;
+	int i, p = 0, halfsize = l / 2;
+	short *buf2 = buf + halfsize, *src = (short *) bounce_buf;
 
 	memcpy(bounce_buf, (char *) buf, l * 2);
 
 	for (i = 0; i < halfsize; i++)
-	  {
-		  buf[i] = src[p++];	/* Left channel */
-		  buf2[i] = src[p++];	/* Right channel */
-	  }
+	{
+		buf[i] = src[p++];	/* Left channel */
+		buf2[i] = src[p++];	/* Right channel */
+	}
 }
 
-static void
-gus_audio_output_block(int dev, unsigned long buf, int total_count,
+static void gus_audio_output_block(int dev, unsigned long buf, int total_count,
 		       int intrflag)
 {
 	struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
@@ -2571,29 +2526,27 @@
 	pcm_current_intrflag = intrflag;
 	pcm_current_dev = dev;
 	if (gus_audio_channels == 2)
-	  {
-		  char           *b = dmap->raw_buf + (buf - dmap->raw_buf_phys);
+	{
+		char *b = dmap->raw_buf + (buf - dmap->raw_buf_phys);
 
-		  if (gus_audio_bits == 8)
-			  gus_uninterleave8(b, total_count);
-		  else
-			  gus_uninterleave16((short *) b, total_count / 2);
-	  }
+		if (gus_audio_bits == 8)
+			gus_uninterleave8(b, total_count);
+		else
+			gus_uninterleave16((short *) b, total_count / 2);
+	}
 	gus_transfer_output_block(dev, buf, total_count, intrflag, 0);
 }
 
-static void
-gus_audio_start_input(int dev, unsigned long buf, int count,
+static void gus_audio_start_input(int dev, unsigned long buf, int count,
 		      int intrflag)
 {
-	unsigned long   flags;
-	unsigned char   mode;
+	unsigned long flags;
+	unsigned char mode;
 
 	save_flags(flags);
 	cli();
 
 	DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ);
-
 	mode = 0xa0;		/* DMA IRQ enabled, invert MSB */
 
 	if (audio_devs[dev]->dmap_in->dma > 3)
@@ -2603,14 +2556,12 @@
 	mode |= 0x01;		/* DMA enable */
 
 	gus_write8(0x49, mode);
-
 	restore_flags(flags);
 }
 
-static int
-gus_audio_prepare_for_input(int dev, int bsize, int bcount)
+static int gus_audio_prepare_for_input(int dev, int bsize, int bcount)
 {
-	unsigned int    rate;
+	unsigned int rate;
 
 	gus_audio_bsize = bsize;
 	audio_devs[dev]->dmap_in->flags |= DMA_NODMA;
@@ -2619,19 +2570,18 @@
 	gus_write8(0x48, rate & 0xff);	/* Set sampling rate */
 
 	if (gus_audio_bits != 8)
-	  {
-		  printk("GUS Error: 16 bit recording not supported\n");
-		  return -EINVAL;
-	  }
+	{
+/*		printk("GUS Error: 16 bit recording not supported\n");*/
+		return -EINVAL;
+	}
 	return 0;
 }
 
-static int
-gus_audio_prepare_for_output(int dev, int bsize, int bcount)
+static int gus_audio_prepare_for_output(int dev, int bsize, int bcount)
 {
-	int             i;
+	int i;
 
-	long            mem_ptr, mem_size;
+	long mem_ptr, mem_size;
 
 	audio_devs[dev]->dmap_out->flags |= DMA_NODMA | DMA_NOTIMEOUT;
 	mem_ptr = 0;
@@ -2655,12 +2605,10 @@
 	if (gus_audio_bits != 8 && pcm_banksize == (256 * 1024))
 		pcm_nblk--;
 	gus_write8(0x41, 0);	/* Disable GF1 DMA */
-
 	return 0;
 }
 
-static int
-gus_local_qlen(int dev)
+static int gus_local_qlen(int dev)
 {
 	return pcm_qlen;
 }
@@ -2680,20 +2628,14 @@
 	NULL
 };
 
-static void
-guswave_setup_voice(int dev, int voice, int chn)
+static void guswave_setup_voice(int dev, int voice, int chn)
 {
-	struct channel_info *info =
-	&synth_devs[dev]->chn_info[chn];
+	struct channel_info *info = &synth_devs[dev]->chn_info[chn];
 
 	guswave_set_instr(dev, voice, info->pgm_num);
-
-	voices[voice].expression_vol =
-	    info->controllers[CTL_EXPRESSION];	/* Just MSB */
-	voices[voice].main_vol =
-	    (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
-	voices[voice].panning =
-	    (info->controllers[CTL_PAN] * 2) - 128;
+	voices[voice].expression_vol = info->controllers[CTL_EXPRESSION];	/* Just MSB */
+	voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
+	voices[voice].panning = (info->controllers[CTL_PAN] * 2) - 128;
 	voices[voice].bender = 0;
 	voices[voice].bender_range = info->bender_range;
 
@@ -2701,15 +2643,13 @@
 		voices[voice].fixed_pitch = 1;
 }
 
-static void
-guswave_bender(int dev, int voice, int value)
+static void guswave_bender(int dev, int voice, int value)
 {
-	int             freq;
+	int freq;
 	unsigned long   flags;
 
 	voices[voice].bender = value - 8192;
-	freq = compute_finetune(voices[voice].orig_freq, value - 8192,
-				voices[voice].bender_range, 0);
+	freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0);
 	voices[voice].current_freq = freq;
 
 	save_flags(flags);
@@ -2719,45 +2659,43 @@
 	restore_flags(flags);
 }
 
-static int
-guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
+static int guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
 {
-	int             i, p, best = -1, best_time = 0x7fffffff;
+	int i, p, best = -1, best_time = 0x7fffffff;
 
 	p = alloc->ptr;
 	/*
-	   * First look for a completely stopped voice
+	 * First look for a completely stopped voice
 	 */
 
 	for (i = 0; i < alloc->max_voice; i++)
-	  {
-		  if (alloc->map[p] == 0)
-		    {
-			    alloc->ptr = p;
-			    return p;
-		    }
-		  if (alloc->alloc_times[p] < best_time)
-		    {
-			    best = p;
-			    best_time = alloc->alloc_times[p];
-		    }
-		  p = (p + 1) % alloc->max_voice;
-	  }
+	{
+		if (alloc->map[p] == 0)
+		{
+			alloc->ptr = p;
+			return p;
+		}
+		if (alloc->alloc_times[p] < best_time)
+		{
+			best = p;
+			best_time = alloc->alloc_times[p];
+		}
+		p = (p + 1) % alloc->max_voice;
+	}
 
 	/*
-	   * Then look for a releasing voice
+	 * Then look for a releasing voice
 	 */
 
 	for (i = 0; i < alloc->max_voice; i++)
-	  {
-		  if (alloc->map[p] == 0xffff)
-		    {
-			    alloc->ptr = p;
-			    return p;
-		    }
-		  p = (p + 1) % alloc->max_voice;
-	  }
-
+	{
+		if (alloc->map[p] == 0xffff)
+		{
+			alloc->ptr = p;
+			return p;
+		}
+		p = (p + 1) % alloc->max_voice;
+	}
 	if (best >= 0)
 		p = best;
 
@@ -2790,11 +2728,10 @@
 	guswave_setup_voice
 };
 
-static void
-set_input_volumes(void)
+static void set_input_volumes(void)
 {
-	unsigned long   flags;
-	unsigned char   mask = 0xff & ~0x06;	/* Just line out enabled */
+	unsigned long flags;
+	unsigned char mask = 0xff & ~0x06;	/* Just line out enabled */
 
 	if (have_gus_max)	/* Don't disturb GUS MAX */
 		return;
@@ -2813,15 +2750,15 @@
 		mask |= 0x04;
 
 	if (recording_active)
-	  {
-		  /*
-		   *    Disable channel, if not selected for recording
-		   */
-		  if (!(gus_recmask & SOUND_MASK_LINE))
-			  mask |= 0x01;
-		  if (!(gus_recmask & SOUND_MASK_MIC))
-			  mask &= ~0x04;
-	  }
+	{
+		/*
+		 *    Disable channel, if not selected for recording
+		 */
+		if (!(gus_recmask & SOUND_MASK_LINE))
+			mask |= 0x01;
+		if (!(gus_recmask & SOUND_MASK_MIC))
+			mask &= ~0x04;
+	}
 	mix_image &= ~0x07;
 	mix_image |= mask & 0x07;
 	outb((mix_image), u_Mixer);
@@ -2842,115 +2779,119 @@
 	if (!access_ok(VERIFY_WRITE, (int *)arg, sizeof(int)))
 		return -EFAULT;
 
-	if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
+	if (_SIOC_DIR(cmd) & _SIOC_WRITE) 
+	{
 		if (__get_user(val, (int *) arg))
 			return -EFAULT;
 
-		switch (cmd & 0xff) {
-		case SOUND_MIXER_RECSRC:
-			gus_recmask = val & MIX_DEVS;
-			if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
-				gus_recmask = SOUND_MASK_MIC;
-			/* Note! Input volumes are updated during next open for recording */
-			val = gus_recmask;
-			break;
-
-		case SOUND_MIXER_MIC:
-			vol = val & 0xff;
-			if (vol < 0)
-				vol = 0;
-			if (vol > 100)
-				vol = 100;
-			gus_mic_vol = vol;
-			set_input_volumes();
-			val = vol | (vol << 8);
-			break;
+		switch (cmd & 0xff) 
+		{
+			case SOUND_MIXER_RECSRC:
+				gus_recmask = val & MIX_DEVS;
+				if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
+					gus_recmask = SOUND_MASK_MIC;
+				/* Note! Input volumes are updated during next open for recording */
+				val = gus_recmask;
+				break;
+
+			case SOUND_MIXER_MIC:
+				vol = val & 0xff;
+				if (vol < 0)
+					vol = 0;
+				if (vol > 100)
+					vol = 100;
+				gus_mic_vol = vol;
+				set_input_volumes();
+				val = vol | (vol << 8);
+				break;
 				
-		case SOUND_MIXER_LINE:
-			vol = val & 0xff;
-			if (vol < 0)
-				vol = 0;
-			if (vol > 100)
-				vol = 100;
-			gus_line_vol = vol;
-			set_input_volumes();
-			val = vol | (vol << 8);
-			break;
-
-		case SOUND_MIXER_PCM:
-			gus_pcm_volume = val & 0xff;
-			if (gus_pcm_volume < 0)
-				gus_pcm_volume = 0;
-			if (gus_pcm_volume > 100)
-				gus_pcm_volume = 100;
-			gus_audio_update_volume();
-			val = gus_pcm_volume | (gus_pcm_volume << 8);
-			break;
-
-		case SOUND_MIXER_SYNTH:
-			gus_wave_volume = val & 0xff;
-			if (gus_wave_volume < 0)
-				gus_wave_volume = 0;
-			if (gus_wave_volume > 100)
-				gus_wave_volume = 100;
-			if (active_device == GUS_DEV_WAVE) {
-				int voice;
-				for (voice = 0; voice < nr_voices; voice++)
+			case SOUND_MIXER_LINE:
+				vol = val & 0xff;
+				if (vol < 0)
+					vol = 0;
+				if (vol > 100)
+					vol = 100;
+				gus_line_vol = vol;
+				set_input_volumes();
+				val = vol | (vol << 8);
+				break;
+
+			case SOUND_MIXER_PCM:
+				gus_pcm_volume = val & 0xff;
+				if (gus_pcm_volume < 0)
+					gus_pcm_volume = 0;
+				if (gus_pcm_volume > 100)
+					gus_pcm_volume = 100;
+				gus_audio_update_volume();
+				val = gus_pcm_volume | (gus_pcm_volume << 8);
+				break;
+
+			case SOUND_MIXER_SYNTH:
+				gus_wave_volume = val & 0xff;
+				if (gus_wave_volume < 0)
+					gus_wave_volume = 0;
+				if (gus_wave_volume > 100)
+					gus_wave_volume = 100;
+				if (active_device == GUS_DEV_WAVE) 
+				{
+					int voice;
+					for (voice = 0; voice < nr_voices; voice++)
 					dynamic_volume_change(voice);	/* Apply the new vol */
-			}
-			val = gus_wave_volume | (gus_wave_volume << 8);
-			break;
+				}
+				val = gus_wave_volume | (gus_wave_volume << 8);
+				break;
 
-		default:
-			return -EINVAL;
+			default:
+				return -EINVAL;
 		}
-
-	} else {
-		switch (cmd & 0xff) {
-		/*
-		 * Return parameters
-		 */
-		case SOUND_MIXER_RECSRC:
-			val = gus_recmask;
-			break;
+	}
+	else
+	{
+		switch (cmd & 0xff) 
+		{
+			/*
+			 * Return parameters
+			 */
+			case SOUND_MIXER_RECSRC:
+				val = gus_recmask;
+				break;
 					
-		case SOUND_MIXER_DEVMASK:
-			val = MIX_DEVS;
-			break;
-
-		case SOUND_MIXER_STEREODEVS:
-			val = 0;
-			break;
-
-		case SOUND_MIXER_RECMASK:
-			val = SOUND_MASK_MIC | SOUND_MASK_LINE;
-			break;
-
-		case SOUND_MIXER_CAPS:
-			val = 0;
-			break;
-
-		case SOUND_MIXER_MIC:
-			val = gus_mic_vol | (gus_mic_vol << 8);
-			break;
-
-		case SOUND_MIXER_LINE:
-			val = gus_line_vol | (gus_line_vol << 8);
-			break;
+			case SOUND_MIXER_DEVMASK:
+				val = MIX_DEVS;
+				break;
+
+			case SOUND_MIXER_STEREODEVS:
+				val = 0;
+				break;
+
+			case SOUND_MIXER_RECMASK:
+				val = SOUND_MASK_MIC | SOUND_MASK_LINE;
+				break;
+
+			case SOUND_MIXER_CAPS:
+				val = 0;
+				break;
+
+			case SOUND_MIXER_MIC:
+				val = gus_mic_vol | (gus_mic_vol << 8);
+				break;
+
+			case SOUND_MIXER_LINE:
+				val = gus_line_vol | (gus_line_vol << 8);
+				break;
+
+			case SOUND_MIXER_PCM:
+				val = gus_pcm_volume | (gus_pcm_volume << 8);
+				break;
+
+			case SOUND_MIXER_SYNTH:
+				val = gus_wave_volume | (gus_wave_volume << 8);
+				break;
 
-		case SOUND_MIXER_PCM:
-			val = gus_pcm_volume | (gus_pcm_volume << 8);
-			break;
-
-		case SOUND_MIXER_SYNTH:
-			val = gus_wave_volume | (gus_wave_volume << 8);
-			break;
-
-		default:
-			return -EINVAL;
+			default:
+				return -EINVAL;
 		}
 	}
-
 	return __put_user(val, (int *)arg);
 }
 
@@ -2961,43 +2902,42 @@
 	gus_default_mixer_ioctl
 };
 
-static int
-gus_default_mixer_init(void)
+static int gus_default_mixer_init(void)
 {
-	int             n;
+	int n;
 
 	if ((n = sound_alloc_mixerdev()) != -1)
-	  {			/*
-				 * Don't install if there is another
-				 * mixer
-				 */
-		  mixer_devs[n] = &gus_mixer_operations;
-	  }
+	{	
+		/*
+		 * Don't install if there is another
+		 * mixer
+		 */
+		mixer_devs[n] = &gus_mixer_operations;
+	}
 	if (have_gus_max)
-	  {
-/*
- *  Enable all mixer channels on the GF1 side. Otherwise recording will
- *  not be possible using GUS MAX.
- */
-		  mix_image &= ~0x07;
-		  mix_image |= 0x04;	/* All channels enabled */
-		  outb((mix_image), u_Mixer);
-	  }
+	{
+		/*
+		 *  Enable all mixer channels on the GF1 side. Otherwise recording will
+		 *  not be possible using GUS MAX.
+		 */
+		mix_image &= ~0x07;
+		mix_image |= 0x04;	/* All channels enabled */
+		outb((mix_image), u_Mixer);
+	}
 	return n;
 }
 
 void gus_wave_init(struct address_info *hw_config)
 {
-	unsigned long   flags;
-	unsigned char   val;
-	char           *model_num = "2.4";
-	char            tmp[64], tmp2[64];
-	int             gus_type = 0x24;	/* 2.4 */
-
-	int             irq = hw_config->irq, dma = hw_config->dma,
-	                dma2 = hw_config->dma2;
-	int             dev;
-	int             sdev;
+	unsigned long flags;
+	unsigned char val;
+	char *model_num = "2.4";
+	char tmp[64], tmp2[64];
+	int gus_type = 0x24;	/* 2.4 */
+
+	int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
+	int dev;
+	int sdev;
 
 	hw_config->slots[0] = -1;	/* No wave */
 	hw_config->slots[1] = -1;	/* No ad1848 */
@@ -3008,14 +2948,14 @@
 	{
 		if (irq < 0 || irq > 15)
 		{
-			printk("ERROR! Invalid IRQ#%d. GUS Disabled", irq);
+			printk(KERN_ERR "ERROR! Invalid IRQ#%d. GUS Disabled", irq);
 			return;
 		}
 	}
 	
 	if (dma < 0 || dma > 7 || dma == 4)
 	{
-		printk("ERROR! Invalid DMA#%d. GUS Disabled", dma);
+		printk(KERN_ERR "ERROR! Invalid DMA#%d. GUS Disabled", dma);
 		return;
 	}
 	gus_irq = irq;
@@ -3046,7 +2986,7 @@
 		/*
 		 * It has the digital ASIC so the card is at least v3.4.
 		 * Next try to detect the true model.
-		   */
+		 */
 
 		if (gus_pnp_flag)	/* Hack hack hack */
 			val = 10;
@@ -3124,9 +3064,9 @@
 				}
 			}
 			else
-				printk(KERN_WARNING "[Where's the CS4231?]");
+				printk(KERN_WARNING "GUS: No CS4231 ??");
 #else
-			printk("\n\n\nGUS MAX support was not compiled in!!!\n\n\n\n");
+			printk(KERN_ERR "GUS MAX found, but not compiled in\n");
 #endif
 		}
 	}
@@ -3291,78 +3231,77 @@
 	parm = voices[voice].loop_irq_parm;
 
 	switch (mode)
-	  {
+	{
+		case LMODE_FINISH:	/*
+					 * Final loop finished, shoot volume down
+					 */
 
-	  case LMODE_FINISH:	/*
-				 * Final loop finished, shoot volume down
-				 */
+			if ((int) (gus_read16(0x09) >> 4) < 100)	/*
+									 * Get current volume
+									 */
+			{
+				gus_voice_off();
+				gus_rampoff();
+				gus_voice_init(voice);
+				break;
+			}
+			gus_ramp_range(65, 4065);
+			gus_ramp_rate(0, 63);		/*
+							 * Fastest possible rate
+							 */
+			gus_rampon(0x20 | 0x40);	/*
+							 * Ramp down, once, irq
+							 */
+			voices[voice].volume_irq_mode = VMODE_HALT;
+			break;
 
-		  if ((int) (gus_read16(0x09) >> 4) < 100)	/*
-								 * Get current volume
-								 */
-		    {
-			    gus_voice_off();
-			    gus_rampoff();
-			    gus_voice_init(voice);
-			    break;
-		    }
-		  gus_ramp_range(65, 4065);
-		  gus_ramp_rate(0, 63);		/*
-						 * Fastest possible rate
-						 */
-		  gus_rampon(0x20 | 0x40);	/*
-						 * Ramp down, once, irq
-						 */
-		  voices[voice].volume_irq_mode = VMODE_HALT;
-		  break;
-
-	  case LMODE_PCM_STOP:
-		  pcm_active = 0;	/* Signal to the play_next_pcm_block routine */
-	  case LMODE_PCM:
-		  {
-
-			  pcm_qlen--;
-			  pcm_head = (pcm_head + 1) % pcm_nblk;
-			  if (pcm_qlen && pcm_active)
-			    {
-				    play_next_pcm_block();
-			  } else
-			    {	/* Underrun. Just stop the voice */
-				    gus_select_voice(0);	/* Left channel */
-				    gus_voice_off();
-				    gus_rampoff();
-				    gus_select_voice(1);	/* Right channel */
-				    gus_voice_off();
-				    gus_rampoff();
-				    pcm_active = 0;
-			    }
-
-			  /*
-			   * If the queue was full before this interrupt, the DMA transfer was
-			   * suspended. Let it continue now.
-			   */
-			  if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-				  DMAbuf_outputintr(gus_devnum, 0);
-		  }
-		  break;
+		case LMODE_PCM_STOP:
+			pcm_active = 0;	/* Signal to the play_next_pcm_block routine */
+		case LMODE_PCM:
+		{
+			pcm_qlen--;
+			pcm_head = (pcm_head + 1) % pcm_nblk;
+			if (pcm_qlen && pcm_active)
+			{
+				play_next_pcm_block();
+			}
+			else
+			{
+				/* Underrun. Just stop the voice */
+				gus_select_voice(0);	/* Left channel */
+				gus_voice_off();
+				gus_rampoff();
+				gus_select_voice(1);	/* Right channel */
+				gus_voice_off();
+				gus_rampoff();
+				pcm_active = 0;
+			}
 
-	  default:;
-	  }
+			/*
+			 * If the queue was full before this interrupt, the DMA transfer was
+			 * suspended. Let it continue now.
+			 */
+			
+			if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
+				DMAbuf_outputintr(gus_devnum, 0);
+		}
+		break;
+
+		default:
+	}
 	restore_flags(flags);
 }
 
-static void
-do_volume_irq(int voice)
+static void do_volume_irq(int voice)
 {
-	unsigned char   tmp;
-	int             mode, parm;
-	unsigned long   flags;
+	unsigned char tmp;
+	int mode, parm;
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
 
 	gus_select_voice(voice);
-
 	tmp = gus_read8(0x0d);
 	tmp &= ~0x20;		/*
 				 * Disable volume ramp IRQ
@@ -3374,138 +3313,136 @@
 	parm = voices[voice].volume_irq_parm;
 
 	switch (mode)
-	  {
-	  case VMODE_HALT:	/* Decay phase finished */
-		  if (iw_mode)
-			  gus_write8(0x15, 0x02);	/* Set voice deactivate bit of SMSI */
-		  restore_flags(flags);
-		  gus_voice_init(voice);
-		  break;
-
-	  case VMODE_ENVELOPE:
-		  gus_rampoff();
-		  restore_flags(flags);
-		  step_envelope(voice);
-		  break;
-
-	  case VMODE_START_NOTE:
-		  restore_flags(flags);
-		  guswave_start_note2(voices[voice].dev_pending, voice,
+	{
+		case VMODE_HALT:	/* Decay phase finished */
+			if (iw_mode)
+				gus_write8(0x15, 0x02);	/* Set voice deactivate bit of SMSI */
+			restore_flags(flags);
+			gus_voice_init(voice);
+			break;
+
+		case VMODE_ENVELOPE:
+			gus_rampoff();
+			restore_flags(flags);
+			step_envelope(voice);
+			break;
+
+		case VMODE_START_NOTE:
+			restore_flags(flags);
+			guswave_start_note2(voices[voice].dev_pending, voice,
 				      voices[voice].note_pending, voices[voice].volume_pending);
-		  if (voices[voice].kill_pending)
-			  guswave_kill_note(voices[voice].dev_pending, voice,
+			if (voices[voice].kill_pending)
+				guswave_kill_note(voices[voice].dev_pending, voice,
 					  voices[voice].note_pending, 0);
 
-		  if (voices[voice].sample_pending >= 0)
-		    {
-			    guswave_set_instr(voices[voice].dev_pending, voice,
-					   voices[voice].sample_pending);
-			    voices[voice].sample_pending = -1;
-		    }
-		  break;
+			if (voices[voice].sample_pending >= 0)
+			{
+				guswave_set_instr(voices[voice].dev_pending, voice,
+					voices[voice].sample_pending);
+				voices[voice].sample_pending = -1;
+			}
+			break;
 
-	  default:
-		  restore_flags(flags);
-	  }
+		default:
+			restore_flags(flags);
+	}
 	restore_flags(flags);
 }
 
-void
-gus_voice_irq(void)
+void gus_voice_irq(void)
 {
-	unsigned long   wave_ignore = 0, volume_ignore = 0;
-	unsigned long   voice_bit;
+	unsigned long wave_ignore = 0, volume_ignore = 0;
+	unsigned long voice_bit;
 
-	unsigned char   src, voice;
+	unsigned char src, voice;
 
 	while (1)
-	  {
-		  src = gus_read8(0x0f);	/*
-						 * Get source info
-						 */
-		  voice = src & 0x1f;
-		  src &= 0xc0;
-
-		  if (src == (0x80 | 0x40))
-			  return;	/*
-					 * No interrupt
+	{
+		src = gus_read8(0x0f);	/*
+					 * Get source info
 					 */
+		voice = src & 0x1f;
+		src &= 0xc0;
+
+		if (src == (0x80 | 0x40))
+			return;	/*
+				 * No interrupt
+				 */
 
-		  voice_bit = 1 << voice;
+		voice_bit = 1 << voice;
 
-		  if (!(src & 0x80))	/*
+		if (!(src & 0x80))	/*
 					 * Wave IRQ pending
 					 */
-			  if (!(wave_ignore & voice_bit) && (int) voice < nr_voices)	/*
-											   * Not done
-											   * yet
+			if (!(wave_ignore & voice_bit) && (int) voice < nr_voices)	/*
+											 * Not done
+											 * yet
 											 */
-			    {
-				    wave_ignore |= voice_bit;
-				    do_loop_irq(voice);
-			    }
-		  if (!(src & 0x40))	/*
+			{
+				wave_ignore |= voice_bit;
+				do_loop_irq(voice);
+			}
+		if (!(src & 0x40))	/*
 					 * Volume IRQ pending
 					 */
-			  if (!(volume_ignore & voice_bit) && (int) voice < nr_voices)	/*
+			if (!(volume_ignore & voice_bit) && (int) voice < nr_voices)	/*
 											   * Not done
 											   * yet
 											 */
-			    {
-				    volume_ignore |= voice_bit;
-				    do_volume_irq(voice);
-			    }
-	  }
+			{
+				volume_ignore |= voice_bit;
+				do_volume_irq(voice);
+			}
+	}
 }
 
-void
-guswave_dma_irq(void)
+void guswave_dma_irq(void)
 {
 	unsigned char   status;
 
 	status = gus_look8(0x41);	/* Get DMA IRQ Status */
 	if (status & 0x40)	/* DMA interrupt pending */
 		switch (active_device)
-		  {
-		  case GUS_DEV_WAVE:
-			  if ((dram_sleep_flag.opts & WK_SLEEP))
-			    {
-				    dram_sleep_flag.opts = WK_WAKEUP;
-				    wake_up(&dram_sleeper);
-			    };
-			  break;
-
-		  case GUS_DEV_PCM_CONTINUE:	/* Left channel data transferred */
-			  gus_write8(0x41, 0);	/* Disable GF1 DMA */
-			  gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
-						    pcm_current_count,
+		{
+			case GUS_DEV_WAVE:
+				if ((dram_sleep_flag.opts & WK_SLEEP))
+				{
+					dram_sleep_flag.opts = WK_WAKEUP;
+					wake_up(&dram_sleeper);
+				}
+				break;
+
+			case GUS_DEV_PCM_CONTINUE:	/* Left channel data transferred */
+				gus_write8(0x41, 0);	/* Disable GF1 DMA */
+				gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
+						pcm_current_count,
 						pcm_current_intrflag, 1);
-			  break;
+				break;
 
-		  case GUS_DEV_PCM_DONE:	/* Right or mono channel data transferred */
-			  gus_write8(0x41, 0);	/* Disable GF1 DMA */
-			  if (pcm_qlen < pcm_nblk)
-			    {
-				    dma_active = 0;
-				    if (gus_busy)
-				      {
-					      if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-						      DMAbuf_outputintr(gus_devnum, 0);
-				      }
-			    }
-			  break;
+			case GUS_DEV_PCM_DONE:	/* Right or mono channel data transferred */
+				gus_write8(0x41, 0);	/* Disable GF1 DMA */
+				if (pcm_qlen < pcm_nblk)
+				{
+					dma_active = 0;
+					if (gus_busy)
+					{
+						if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
+							DMAbuf_outputintr(gus_devnum, 0);
+					}
+				}
+				break;
 
-		  default:;
-		  }
+			default:
+	}
 	status = gus_look8(0x49);	/*
 					 * Get Sampling IRQ Status
 					 */
 	if (status & 0x40)	/*
 				 * Sampling Irq pending
 				 */
-	  {
-		  DMAbuf_inputintr(gus_devnum);
-	  }
+	{
+		DMAbuf_inputintr(gus_devnum);
+	}
 }
 
 #if defined(CONFIG_SEQUENCER) || defined(MODULE)
@@ -3517,10 +3454,9 @@
 static volatile int select_addr, data_addr;
 static volatile int curr_timer = 0;
 
-void
-gus_timer_command(unsigned int addr, unsigned int val)
+void gus_timer_command(unsigned int addr, unsigned int val)
 {
-	int             i;
+	int i;
 
 	outb(((unsigned char) (addr & 0xff)), select_addr);
 
@@ -3533,59 +3469,54 @@
 		inb(select_addr);
 }
 
-static void
-arm_timer(int timer, unsigned int interval)
+static void arm_timer(int timer, unsigned int interval)
 {
-
 	curr_timer = timer;
 
 	if (timer == 1)
-	  {
-		  gus_write8(0x46, 256 - interval);	/* Set counter for timer 1 */
-		  gus_write8(0x45, 0x04);	/* Enable timer 1 IRQ */
-		  gus_timer_command(0x04, 0x01);	/* Start timer 1 */
-	} else
-	  {
-		  gus_write8(0x47, 256 - interval);	/* Set counter for timer 2 */
-		  gus_write8(0x45, 0x08);	/* Enable timer 2 IRQ */
-		  gus_timer_command(0x04, 0x02);	/* Start timer 2 */
-	  }
+	{
+		gus_write8(0x46, 256 - interval);	/* Set counter for timer 1 */
+		gus_write8(0x45, 0x04);			/* Enable timer 1 IRQ */
+		gus_timer_command(0x04, 0x01);		/* Start timer 1 */
+	}
+	else
+	{
+		gus_write8(0x47, 256 - interval);	/* Set counter for timer 2 */
+		gus_write8(0x45, 0x08);			/* Enable timer 2 IRQ */
+		gus_timer_command(0x04, 0x02);		/* Start timer 2 */
+	}
 
 	gus_timer_enabled = 1;
 }
 
-static unsigned int
-gus_tmr_start(int dev, unsigned int usecs_per_tick)
+static unsigned int gus_tmr_start(int dev, unsigned int usecs_per_tick)
 {
-	int             timer_no, resolution;
-	int             divisor;
+	int timer_no, resolution;
+	int divisor;
 
 	if (usecs_per_tick > (256 * 80))
-	  {
-		  timer_no = 2;
-		  resolution = 320;	/* usec */
-	} else
-	  {
-		  timer_no = 1;
-		  resolution = 80;	/* usec */
-	  }
-
+	{
+		timer_no = 2;
+		resolution = 320;	/* usec */
+	}
+	else
+	{
+		timer_no = 1;
+		resolution = 80;	/* usec */
+	}
 	divisor = (usecs_per_tick + (resolution / 2)) / resolution;
-
 	arm_timer(timer_no, divisor);
 
 	return divisor * resolution;
 }
 
-static void
-gus_tmr_disable(int dev)
+static void gus_tmr_disable(int dev)
 {
 	gus_write8(0x45, 0);	/* Disable both timers */
 	gus_timer_enabled = 0;
 }
 
-static void
-gus_tmr_restart(int dev)
+static void gus_tmr_restart(int dev)
 {
 	if (curr_timer == 1)
 		gus_write8(0x45, 0x04);		/* Start timer 1 again */
@@ -3603,8 +3534,7 @@
 	gus_tmr_restart
 };
 
-static void
-gus_tmr_install(int io_base)
+static void gus_tmr_install(int io_base)
 {
 	struct sound_lowlev_timer *tmr;
 
diff -u --recursive --new-file v2.1.80/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v2.1.80/linux/drivers/sound/soundcard.c	Tue Jan 20 16:44:57 1998
+++ linux/drivers/sound/soundcard.c	Thu Jan 22 14:46:41 1998
@@ -1101,8 +1101,7 @@
 
 		dmap->buffsize = PAGE_SIZE * (1 << sz);
 
-		start_addr = (char *) __get_free_pages(GFP_ATOMIC | GFP_DMA, sz);
-		if (start_addr == NULL)
+		if ((start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz)) == NULL)
 			dmap->buffsize /= 2;
 	}
 
diff -u --recursive --new-file v2.1.80/linux/fs/dcache.c linux/fs/dcache.c
--- v2.1.80/linux/fs/dcache.c	Tue Jan 13 20:02:49 1998
+++ linux/fs/dcache.c	Wed Jan 21 17:46:55 1998
@@ -68,6 +68,7 @@
 	if (inode) {
 		dentry->d_inode = NULL;
 		list_del(&dentry->d_alias);
+		INIT_LIST_HEAD(&dentry->d_alias);
 		if (dentry->d_op && dentry->d_op->d_iput)
 			dentry->d_op->d_iput(dentry, inode);
 		else
diff -u --recursive --new-file v2.1.80/linux/fs/fat/buffer.c linux/fs/fat/buffer.c
--- v2.1.80/linux/fs/fat/buffer.c	Thu Jan  8 14:02:41 1998
+++ linux/fs/fat/buffer.c	Wed Jan 21 17:46:56 1998
@@ -30,9 +30,9 @@
 	 * counterproductive or just plain wrong.
 	 */
 
-	if(MSDOS_SB(sb)->cvf_format)
-	  if(MSDOS_SB(sb)->cvf_format->cvf_bread)
-	    return MSDOS_SB(sb)->cvf_format->cvf_bread(sb,block);
+	if(MSDOS_SB(sb)->cvf_format &&
+	   MSDOS_SB(sb)->cvf_format->cvf_bread)
+		return MSDOS_SB(sb)->cvf_format->cvf_bread(sb,block);
 
 	if (sb->s_blocksize == 512) {
 		ret = bread (sb->s_dev,block,512);
@@ -46,37 +46,37 @@
 
 		if (real != NULL){
 			ret = (struct buffer_head *)
-			  kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
+				kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
 			if (ret != NULL) {
 				/* #Specification: msdos / strategy / special device / dummy blocks
-					Many special device (Scsi optical disk for one) use
-					larger hardware sector size. This allows for higher
-					capacity.
-
-					Most of the time, the MsDOS file system that sit
-					on this device is totally unaligned. It use logically
-					512 bytes sector size, with logical sector starting
-					in the middle of a hardware block. The bad news is
-					that a hardware sector may hold data own by two
-					different files. This means that the hardware sector
-					must be read, patch and written almost all the time.
-
-					Needless to say that it kills write performance
-					on all OS.
-
-					Internally the linux msdos fs is using 512 bytes
-					logical sector. When accessing such a device, we
-					allocate dummy buffer cache blocks, that we stuff
-					with the information of a real one (1k large).
-
-					This strategy is used to hide this difference to
-					the core of the msdos fs. The slowdown is not
-					hidden though!
-				*/
+				 * Many special device (Scsi optical disk for one) use
+				 * larger hardware sector size. This allows for higher
+				 * capacity.
+
+				 * Most of the time, the MsDOS file system that sit
+				 * on this device is totally unaligned. It use logically
+				 * 512 bytes sector size, with logical sector starting
+				 * in the middle of a hardware block. The bad news is
+				 * that a hardware sector may hold data own by two
+				 * different files. This means that the hardware sector
+				 * must be read, patch and written almost all the time.
+
+				 * Needless to say that it kills write performance
+				 * on all OS.
+
+				 * Internally the linux msdos fs is using 512 bytes
+				 * logical sector. When accessing such a device, we
+				 * allocate dummy buffer cache blocks, that we stuff
+				 * with the information of a real one (1k large).
+
+				 * This strategy is used to hide this difference to
+				 * the core of the msdos fs. The slowdown is not
+				 * hidden though!
+				 */
 				/*
-					The memset is there only to catch errors. The msdos
-					fs is only using b_data
-				*/
+				 * The memset is there only to catch errors. The msdos
+				 * fs is only using b_data
+				 */
 				memset (ret,0,sizeof(*ret));
 				ret->b_data = real->b_data;
 				if (sb->s_blocksize == 2048) {
@@ -92,26 +92,26 @@
 	}
 	return ret;
 }
-struct buffer_head *fat_getblk (
-	struct super_block *sb,
-	int block)
+
+struct buffer_head *fat_getblk(struct super_block *sb, int block)
 {
 	struct buffer_head *ret = NULL;
 	PRINTK(("fat_getblk: block=0x%x\n", block));
 
-	if(MSDOS_SB(sb)->cvf_format)
-	  if(MSDOS_SB(sb)->cvf_format->cvf_getblk)
-	    return MSDOS_SB(sb)->cvf_format->cvf_getblk(sb,block);
+	if (MSDOS_SB(sb)->cvf_format &&
+	    MSDOS_SB(sb)->cvf_format->cvf_getblk)
+		return MSDOS_SB(sb)->cvf_format->cvf_getblk(sb,block);
 
 	if (sb->s_blocksize == 512){
 		ret = getblk (sb->s_dev,block,512);
-	}else{
-		/* #Specification: msdos / special device / writing
-			A write is always preceded by a read of the complete block
-			(large hardware sector size). This defeat write performance.
-			There is a possibility to optimize this when writing large
-			chunk by making sure we are filling large block. Volunteer ?
-		*/
+	} else {
+		/*
+		 * #Specification: msdos / special device / writing
+		 * A write is always preceded by a read of the complete block
+		 * (large hardware sector size). This defeat write performance.
+		 * There is a possibility to optimize this when writing large
+		 * chunk by making sure we are filling large block. Volunteer ?
+		 */
 		ret = fat_bread (sb,block);
 	}
 	return ret;
@@ -121,10 +121,10 @@
 	struct super_block *sb,
 	struct buffer_head *bh)
 {
-	if (bh != NULL){
-		if(MSDOS_SB(sb)->cvf_format)
-          	  if(MSDOS_SB(sb)->cvf_format->cvf_brelse)
-            	    return MSDOS_SB(sb)->cvf_format->cvf_brelse(sb,bh);
+	if (bh != NULL) {
+		if (MSDOS_SB(sb)->cvf_format &&
+		    MSDOS_SB(sb)->cvf_format->cvf_brelse)
+			return MSDOS_SB(sb)->cvf_format->cvf_brelse(sb,bh);
 
 		if (sb->s_blocksize == 512){
 			brelse (bh);
@@ -141,18 +141,18 @@
 void fat_mark_buffer_dirty (
 	struct super_block *sb,
 	struct buffer_head *bh,
-	int dirty_val)
+	int dirty)
 {
-	if(MSDOS_SB(sb)->cvf_format)
-          if(MSDOS_SB(sb)->cvf_format->cvf_mark_buffer_dirty)
-          { MSDOS_SB(sb)->cvf_format->cvf_mark_buffer_dirty(sb,bh,dirty_val);
-            return;
-          }
+	if (MSDOS_SB(sb)->cvf_format &&
+	    MSDOS_SB(sb)->cvf_format->cvf_mark_buffer_dirty) {
+		MSDOS_SB(sb)->cvf_format->cvf_mark_buffer_dirty(sb,bh,dirty);
+		return;
+	}
  
 	if (sb->s_blocksize != 512){
 		bh = bh->b_next;
 	}
-	mark_buffer_dirty (bh,dirty_val);
+	mark_buffer_dirty (bh,dirty);
 }
 
 void fat_set_uptodate (
@@ -160,11 +160,11 @@
 	struct buffer_head *bh,
 	int val)
 {
-	if(MSDOS_SB(sb)->cvf_format)
-          if(MSDOS_SB(sb)->cvf_format->cvf_set_uptodate)
-          { MSDOS_SB(sb)->cvf_format->cvf_set_uptodate(sb,bh,val);
-            return;
-          }
+	if (MSDOS_SB(sb)->cvf_format && 
+	    MSDOS_SB(sb)->cvf_format->cvf_set_uptodate) {
+		MSDOS_SB(sb)->cvf_format->cvf_set_uptodate(sb,bh,val);
+		return;
+	}
  
 	if (sb->s_blocksize != 512){
 		bh = bh->b_next;
@@ -175,9 +175,9 @@
 	struct super_block *sb,
 	struct buffer_head *bh)
 {
-	if(MSDOS_SB(sb)->cvf_format)
-          if(MSDOS_SB(sb)->cvf_format->cvf_is_uptodate)
-            return MSDOS_SB(sb)->cvf_format->cvf_is_uptodate(sb,bh);
+	if(MSDOS_SB(sb)->cvf_format &&
+	   MSDOS_SB(sb)->cvf_format->cvf_is_uptodate)
+		return MSDOS_SB(sb)->cvf_format->cvf_is_uptodate(sb,bh);
  
 	if (sb->s_blocksize != 512){
 		bh = bh->b_next;
@@ -191,11 +191,11 @@
 	int nbreq,
 	struct buffer_head *bh[32])
 {
-        if(MSDOS_SB(sb)->cvf_format)
-          if(MSDOS_SB(sb)->cvf_format->cvf_ll_rw_block)
-          { MSDOS_SB(sb)->cvf_format->cvf_ll_rw_block(sb,opr,nbreq,bh);
-            return;
-          }
+        if (MSDOS_SB(sb)->cvf_format &&
+	    MSDOS_SB(sb)->cvf_format->cvf_ll_rw_block) {
+		MSDOS_SB(sb)->cvf_format->cvf_ll_rw_block(sb,opr,nbreq,bh);
+		return;
+	}
  
 	if (sb->s_blocksize == 512){
 		ll_rw_block(opr,nbreq,bh);
diff -u --recursive --new-file v2.1.80/linux/fs/fat/cache.c linux/fs/fat/cache.c
--- v2.1.80/linux/fs/fat/cache.c	Tue Jan 13 20:07:28 1998
+++ linux/fs/fat/cache.c	Wed Jan 21 17:46:56 1998
@@ -30,9 +30,9 @@
 	unsigned char *p_first,*p_last;
 	int copy,first,last,next,b;
 
-	if(MSDOS_SB(sb)->cvf_format)
-	  if(MSDOS_SB(sb)->cvf_format->fat_access)
-	    return MSDOS_SB(sb)->cvf_format->fat_access(sb,nr,new_value);
+	if (MSDOS_SB(sb)->cvf_format &&
+	    MSDOS_SB(sb)->cvf_format->fat_access)
+		return MSDOS_SB(sb)->cvf_format->fat_access(sb,nr,new_value);
 
 	if ((unsigned) (nr-2) >= MSDOS_SB(sb)->clusters)
 		return 0;
@@ -267,9 +267,8 @@
 	int cluster,offset;
 
 	sb = MSDOS_SB(inode->i_sb);
-	if(sb->cvf_format)
-	  if(sb->cvf_format->cvf_smap)
-	    return sb->cvf_format->cvf_smap(inode,sector);
+	if (sb->cvf_format && sb->cvf_format->cvf_smap)
+		return sb->cvf_format->cvf_smap(inode,sector);
 	if ((sb->fat_bits != 32) &&
 	    (inode->i_ino == MSDOS_ROOT_INO || (S_ISDIR(inode->i_mode) &&
 	     !MSDOS_I(inode)->i_start))) {
diff -u --recursive --new-file v2.1.80/linux/fs/fat/dir.c linux/fs/fat/dir.c
--- v2.1.80/linux/fs/fat/dir.c	Tue Jan 13 20:07:28 1998
+++ linux/fs/fat/dir.c	Wed Jan 21 17:46:56 1998
@@ -437,10 +437,10 @@
 	}
 	default:
 		/* forward ioctl to CVF extension */
-	       if(MSDOS_SB(inode->i_sb)->cvf_format
-	          &&MSDOS_SB(inode->i_sb)->cvf_format->cvf_dir_ioctl)
-	              return MSDOS_SB(inode->i_sb)->cvf_format->
-	                        cvf_dir_ioctl(inode,filp,cmd,arg);
+	       if (MSDOS_SB(inode->i_sb)->cvf_format &&
+		   MSDOS_SB(inode->i_sb)->cvf_format->cvf_dir_ioctl)
+		       return MSDOS_SB(inode->i_sb)->cvf_format
+			       ->cvf_dir_ioctl(inode,filp,cmd,arg);
 		return -EINVAL;
 	}
 
diff -u --recursive --new-file v2.1.80/linux/fs/fat/file.c linux/fs/fat/file.c
--- v2.1.80/linux/fs/fat/file.c	Thu Jan  8 14:02:41 1998
+++ linux/fs/fat/file.c	Wed Jan 21 17:46:56 1998
@@ -312,9 +312,10 @@
 	loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	if(MSDOS_SB(inode->i_sb)->cvf_format)
-          if(MSDOS_SB(inode->i_sb)->cvf_format->cvf_file_read)
-            return MSDOS_SB(inode->i_sb)->cvf_format->cvf_file_read(filp,buf,count,ppos);
+	if (MSDOS_SB(inode->i_sb)->cvf_format &&
+	    MSDOS_SB(inode->i_sb)->cvf_format->cvf_file_read)
+		return MSDOS_SB(inode->i_sb)->cvf_format
+			->cvf_file_read(filp,buf,count,ppos);
 
 	if (!MSDOS_I(inode)->i_binary)
 		return fat_file_read_text(filp, buf, count, ppos);
@@ -338,13 +339,16 @@
 	struct buffer_head *bh;
 	int binary_mode = MSDOS_I(inode)->i_binary;
 
+	PRINTK(("fat_file_write: dentry=%p, inode=%p, ino=%ld\n",
+		filp->f_dentry, inode, inode->i_ino));
 	if (!inode) {
 		printk("fat_file_write: inode = NULL\n");
 		return -EINVAL;
 	}
-        if(MSDOS_SB(sb)->cvf_format)
-          if(MSDOS_SB(sb)->cvf_format->cvf_file_write)
-            return MSDOS_SB(sb)->cvf_format->cvf_file_write(filp,buf,count,ppos);
+        if (MSDOS_SB(sb)->cvf_format &&
+	    MSDOS_SB(sb)->cvf_format->cvf_file_write)
+		return MSDOS_SB(sb)->cvf_format
+			->cvf_file_write(filp,buf,count,ppos);
 
 	/* S_ISLNK allows for UMSDOS. Should never happen for normal MSDOS */
 	if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) {
diff -u --recursive --new-file v2.1.80/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.1.80/linux/fs/fat/inode.c	Tue Jan 13 20:07:28 1998
+++ linux/fs/fat/inode.c	Wed Jan 21 17:46:56 1998
@@ -29,89 +29,31 @@
 #include <asm/unaligned.h>
 
 /* #define FAT_PARANOIA 1 */
+#define DEBUG_LEVEL 0
 #ifdef FAT_DEBUG
 #  define PRINTK(x) printk x
 #else
 #  define PRINTK(x)
 #endif
-
-/*
- * Free any dependent inodes at the (effective) last use.
- */
-static int fat_free_links(struct inode *inode)
-{
-	struct inode *depend, *linked, *old_inode;
-	int success = 0;
-
-	/*
-	 * Clear the fields first to avoid races
-	 */
-	depend = MSDOS_I(inode)->i_depend;
-	MSDOS_I(inode)->i_depend = NULL;
-	linked = MSDOS_I(inode)->i_linked;
-	MSDOS_I(inode)->i_linked = NULL;
-
-	if (depend) {
-#ifdef FAT_PARANOIA
-printk("fat_put_inode: depend inode is %ld, i_count=%d\n",
-depend->i_ino, depend->i_count); 
-#endif
-		old_inode = MSDOS_I(depend)->i_old;
-		if (old_inode != inode) {
-			printk("fat_free_link: Invalid depend for inode %ld: "
-				"expected 0x%p, got 0x%p\n",
-				depend->i_ino, inode, old_inode);
-			goto out;
-		}
-		MSDOS_I(depend)->i_old = NULL;
-		iput(depend);
-	}
-
-	if (linked) {
-#ifdef FAT_PARANOIA
-printk("fat_put_inode: linked inode is %ld, i_count=%d\n",
-linked->i_ino, linked->i_count); 
+#if (DEBUG_LEVEL >= 1)
+#  define PRINTK1(x) printk x
+#else
+#  define PRINTK1(x)
 #endif
-		old_inode = MSDOS_I(linked)->i_oldlink;
-		if (old_inode != inode) {
-			printk("fat_free_link: Invalid link for inode %ld: "
-				"expected 0x%p, got 0x%p\n",
-				linked->i_ino, inode, old_inode);
-			goto out;
-		}
-		MSDOS_I(linked)->i_oldlink = NULL;
-		iput(linked);
-	}
-	success = 1;
-out:
-	return success;
-}
 
-/*
- * This is a little tricky, as we may have links and may be linked
- * by other inodes. Also, we're subject to race conditions ...
- */
 void fat_put_inode(struct inode *inode)
 {
-	int last_use = 1;
-
 	/*
 	 * Check whether we're a dependent of other inodes ...
 	 */ 
-	if (MSDOS_I(inode)->i_oldlink)
-		last_use++;
-	if (MSDOS_I(inode)->i_old)
-		last_use++;
-
-	if (inode->i_count <= last_use) {
+	if (inode->i_count <= 1) {
 #ifdef FAT_PARANOIA
-printk("fat_put_inode: last use for %ld, i_count=%d\n",
-inode->i_ino, inode->i_count); 
+printk("fat_put_inode: last use for (%p,%ld), i_count=%d\n",
+inode, inode->i_ino, inode->i_count); 
 #endif
 		if (inode->i_nlink) {
 			if (MSDOS_I(inode)->i_busy)
 				fat_cache_inval_inode(inode);
-			fat_free_links(inode);
 		}
 	}
 }
@@ -121,18 +63,9 @@
 	/*
 	 * Make sure there are no active dependencies ...
 	 */
-	if (MSDOS_I(inode)->i_old)
-		printk("fat_delete_inode: inode %ld, old=%p??\n",
-			inode->i_ino, MSDOS_I(inode)->i_old);
-	if (MSDOS_I(inode)->i_oldlink)
-		printk("fat_delete_inode: inode %ld, oldlink=%p??\n",
-			inode->i_ino, MSDOS_I(inode)->i_oldlink);
-
 	fat_cache_inval_inode(inode);
 	inode->i_size = 0;
 	fat_truncate(inode);
-	if (!fat_free_links(inode))
-		fat_fs_panic(inode->i_sb,"..."); /* is this necessary? */
 	clear_inode(inode);
 }
 
@@ -140,9 +73,9 @@
 void fat_put_super(struct super_block *sb)
 {
 	lock_super(sb);
-	if(MSDOS_SB(sb)->cvf_format)
-	{ MSDOS_SB(sb)->cvf_format->unmount_cvf(sb);
-	  dec_cvf_format_use_count_by_version(MSDOS_SB(sb)->cvf_format->cvf_version);
+	if (MSDOS_SB(sb)->cvf_format) {
+		dec_cvf_format_use_count_by_version(MSDOS_SB(sb)->cvf_format->cvf_version);
+		MSDOS_SB(sb)->cvf_format->unmount_cvf(sb);
 	}
 	if (MSDOS_SB(sb)->fat_bits == 32) {
 		fat_clusters_flush(sb);
@@ -175,7 +108,7 @@
 
 static int parse_options(char *options,int *fat, int *blksize, int *debug,
 			 struct fat_mount_options *opts,
-			 char* cvf_format, char*cvf_options)
+			 char *cvf_format, char *cvf_options)
 {
 	char *this_char,*value,save,*savep;
 	char *p;
@@ -355,10 +288,10 @@
 	char cvf_format[21];
 	char cvf_options[101];
 
-	cvf_format[0]='\0';
-	cvf_options[0]='\0';
-	MSDOS_SB(sb)->cvf_format=NULL;
-	MSDOS_SB(sb)->private_data=NULL;
+	cvf_format[0] = '\0';
+	cvf_options[0] = '\0';
+	MSDOS_SB(sb)->cvf_format = NULL;
+	MSDOS_SB(sb)->private_data = NULL;
 
 	MOD_INC_USE_COUNT;
 	if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
@@ -484,9 +417,12 @@
 				/* because clusters (DOS) are often aligned */
 				/* on odd sectors. */
 	sb->s_blocksize_bits = blksize == 512 ? 9 : (blksize == 1024 ? 10 : 11);
-	if(!strcmp(cvf_format,"none"))i=-1;
-	else i=detect_cvf(sb,cvf_format);
-	if(i>=0)error=cvf_formats[i]->mount_cvf(sb,cvf_options);
+	if (!strcmp(cvf_format,"none"))
+		i = -1;
+	else
+		i = detect_cvf(sb,cvf_format);
+	if (i >= 0)
+		error = cvf_formats[i]->mount_cvf(sb,cvf_options);
 	if (error || debug) {
 		/* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
 		printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
@@ -546,9 +482,9 @@
 	sb->s_root = d_alloc_root(root_inode, NULL);
 	if (!sb->s_root)
 		goto out_no_root;
-	if(i>=0)
-	{ MSDOS_SB(sb)->cvf_format=cvf_formats[i];
-	  ++cvf_format_use_count[i];
+	if(i>=0) {
+		MSDOS_SB(sb)->cvf_format = cvf_formats[i];
+		++cvf_format_use_count[i];
 	}
 	return sb;
 
@@ -585,9 +521,9 @@
 	int free,nr;
 	struct statfs tmp;
        
-        if(MSDOS_SB(sb)->cvf_format)
-          if(MSDOS_SB(sb)->cvf_format->cvf_statfs)
-            return MSDOS_SB(sb)->cvf_format->cvf_statfs(sb,buf,bufsiz);
+        if (MSDOS_SB(sb)->cvf_format &&
+	    MSDOS_SB(sb)->cvf_format->cvf_statfs)
+		return MSDOS_SB(sb)->cvf_format->cvf_statfs(sb,buf,bufsiz);
           
 	lock_fat(sb);
 	if (MSDOS_SB(sb)->free_clusters != -1)
@@ -617,9 +553,9 @@
 	int cluster,offset;
 
 	sb = MSDOS_SB(inode->i_sb);
-	if(sb->cvf_format)
-	  if(sb->cvf_format->cvf_bmap)
-	    return sb->cvf_format->cvf_bmap(inode,block);
+	if (sb->cvf_format &&
+	    sb->cvf_format->cvf_bmap)
+		return sb->cvf_format->cvf_bmap(inode,block);
 	if ((inode->i_ino == MSDOS_ROOT_INO) && (sb->fat_bits != 32)) {
 		return sb->dir_start + block;
 	}
@@ -646,11 +582,9 @@
 	struct msdos_dir_entry *raw_entry;
 	int nr;
 
-	PRINTK(("fat_read_inode: inode=%p, sb->dir_start=0x%x\n",
-		inode, MSDOS_SB(sb)->dir_start));
+	PRINTK1(("fat_read_inode: inode=%p, ino=%ld, sb->dir_start=0x%x\n",
+		 inode, inode->i_ino, MSDOS_SB(sb)->dir_start));
 	MSDOS_I(inode)->i_busy = 0;
-	MSDOS_I(inode)->i_depend = MSDOS_I(inode)->i_old = NULL;
-	MSDOS_I(inode)->i_linked = MSDOS_I(inode)->i_oldlink = NULL;
 	MSDOS_I(inode)->i_binary = 1;
 	inode->i_uid = MSDOS_SB(sb)->options.fs_uid;
 	inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
@@ -684,6 +618,7 @@
 
 		MSDOS_I(inode)->i_attrs = 0;
 		inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
+		MSDOS_I(inode)->i_ctime_ms = 0;
 		inode->i_nlink = fat_subdirs(inode)+2;
 		    /* subdirs (neither . nor ..) plus . and "self" */
 		return;
@@ -732,10 +667,10 @@
 		       !is_exec(raw_entry->ext)))
 		    	? S_IRUGO|S_IWUGO : S_IRWXUGO)
 		    & ~MSDOS_SB(sb)->options.fs_umask) | S_IFREG;
-		if(MSDOS_SB(sb)->cvf_format)
-		  inode->i_op = (MSDOS_SB(sb)->cvf_format->flags&CVF_USE_READPAGE)
-			? &fat_file_inode_operations_readpage
-			: &fat_file_inode_operations_1024;
+		if (MSDOS_SB(sb)->cvf_format)
+			inode->i_op = (MSDOS_SB(sb)->cvf_format->flags & CVF_USE_READPAGE)
+				? &fat_file_inode_operations_readpage
+				: &fat_file_inode_operations_1024;
 		else
 		  inode->i_op = (sb->s_blocksize == 1024 || sb->s_blocksize == 2048)
 			? &fat_file_inode_operations_1024
@@ -765,6 +700,7 @@
 		MSDOS_SB(sb)->options.isvfat
 		? date_dos2unix(CF_LE_W(raw_entry->ctime),CF_LE_W(raw_entry->cdate))
 		: inode->i_mtime;
+	MSDOS_I(inode)->i_ctime_ms = raw_entry->ctime_ms;
 	fat_brelse(sb, bh);
 }
 
@@ -774,29 +710,6 @@
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *bh;
 	struct msdos_dir_entry *raw_entry;
-	struct inode *linked;
-
-	linked = MSDOS_I(inode)->i_linked;
-	if (linked) {
-		if (MSDOS_I(linked)->i_oldlink != inode) {
-			printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",
-			       linked, inode, MSDOS_I(linked)->i_oldlink);
-			fat_fs_panic(sb,"...");
-			return;
-		}
-		linked->i_version = ++event;
-		linked->i_mode = inode->i_mode;
-		linked->i_uid = inode->i_uid;
-		linked->i_gid = inode->i_gid;
-		linked->i_size = inode->i_size;
-		linked->i_atime = inode->i_atime;
-		linked->i_mtime = inode->i_mtime;
-		linked->i_ctime = inode->i_ctime;
-		linked->i_blocks = inode->i_blocks;
-		linked->i_atime = inode->i_atime;
-		MSDOS_I(linked)->i_attrs = MSDOS_I(inode)->i_attrs;
-		mark_inode_dirty(linked);
-	}
 
 	if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return;
 	if (!(bh = fat_bread(sb, inode->i_ino >> MSDOS_DPB_BITS))) {
@@ -823,6 +736,7 @@
 	raw_entry->date = CT_LE_W(raw_entry->date);
 	if (MSDOS_SB(sb)->options.isvfat) {
 		fat_date_unix2dos(inode->i_ctime,&raw_entry->ctime,&raw_entry->cdate);
+		raw_entry->ctime_ms = MSDOS_I(inode)->i_ctime_ms;
 		raw_entry->ctime = CT_LE_W(raw_entry->ctime);
 		raw_entry->cdate = CT_LE_W(raw_entry->cdate);
 	}
diff -u --recursive --new-file v2.1.80/linux/fs/fat/misc.c linux/fs/fat/misc.c
--- v2.1.80/linux/fs/fat/misc.c	Tue Jan 13 20:07:28 1998
+++ linux/fs/fat/misc.c	Wed Jan 21 17:46:56 1998
@@ -221,9 +221,9 @@
 #endif
 	sector = MSDOS_SB(sb)->data_start+(nr-2)*cluster_size;
 	last_sector = sector + cluster_size;
-	if(MSDOS_SB(sb)->cvf_format&&
-	  MSDOS_SB(sb)->cvf_format->zero_out_cluster)
-	    MSDOS_SB(sb)->cvf_format->zero_out_cluster(inode,nr);
+	if (MSDOS_SB(sb)->cvf_format &&
+	    MSDOS_SB(sb)->cvf_format->zero_out_cluster)
+		MSDOS_SB(sb)->cvf_format->zero_out_cluster(inode,nr);
 	else
 	for ( ; sector < last_sector; sector++) {
 		#ifdef DEBUG
diff -u --recursive --new-file v2.1.80/linux/fs/fat/mmap.c linux/fs/fat/mmap.c
--- v2.1.80/linux/fs/fat/mmap.c	Tue Jan 13 20:07:28 1998
+++ linux/fs/fat/mmap.c	Wed Jan 21 17:46:56 1998
@@ -97,9 +97,9 @@
 int fat_mmap(struct file * file, struct vm_area_struct * vma)
 {
 	struct inode *inode = file->f_dentry->d_inode;
-	if(MSDOS_SB(inode->i_sb)->cvf_format)
-	  if(MSDOS_SB(inode->i_sb)->cvf_format->cvf_mmap)
-	    return MSDOS_SB(inode->i_sb)->cvf_format->cvf_mmap(file,vma);
+	if (MSDOS_SB(inode->i_sb)->cvf_format &&
+	    MSDOS_SB(inode->i_sb)->cvf_format->cvf_mmap)
+		return MSDOS_SB(inode->i_sb)->cvf_format->cvf_mmap(file,vma);
 
 	if (vma->vm_flags & VM_SHARED)	/* only PAGE_COW or read-only supported now */
 		return -EINVAL;
@@ -121,10 +121,9 @@
 int fat_readpage(struct dentry * dentry, struct page * page)
 {
 	struct inode * inode = dentry->d_inode;
-	if(MSDOS_SB(inode->i_sb)->cvf_format)
-		if(MSDOS_SB(inode->i_sb)->cvf_format->cvf_readpage)
-			return MSDOS_SB(inode->i_sb)->cvf_format
-				->cvf_readpage(inode,page);
+	if (MSDOS_SB(inode->i_sb)->cvf_format &&
+	    MSDOS_SB(inode->i_sb)->cvf_format->cvf_readpage)
+		return MSDOS_SB(inode->i_sb)->cvf_format->cvf_readpage(inode,page);
 	    
 	printk("fat_readpage called with no handler (shouldn't happen)\n");
 	return -1;
diff -u --recursive --new-file v2.1.80/linux/fs/minix/inode.c linux/fs/minix/inode.c
--- v2.1.80/linux/fs/minix/inode.c	Fri Jul 18 12:42:29 1997
+++ linux/fs/minix/inode.c	Wed Jan 21 14:27:57 1998
@@ -12,9 +12,9 @@
 #include <linux/module.h>
 
 #include <linux/sched.h>
-#include <linux/minix_fs.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/malloc.h>
 #include <linux/string.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
@@ -24,6 +24,8 @@
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 
+#include <linux/minix_fs.h>
+
 static void minix_delete_inode(struct inode *inode)
 {
 	inode->i_size = 0;
@@ -62,12 +64,13 @@
 		sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state;
 		mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
 	}
-	sb->s_dev = 0;
 	for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
 		brelse(sb->u.minix_sb.s_imap[i]);
 	for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
 		brelse(sb->u.minix_sb.s_zmap[i]);
 	brelse (sb->u.minix_sb.s_sbh);
+	kfree(sb->u.minix_sb.s_imap);
+	sb->s_dev = 0;
 	unlock_super(sb);
 	MOD_DEC_USE_COUNT;
 	return;
@@ -161,30 +164,29 @@
 	return errmsg;
 }
 
-struct super_block *minix_read_super(struct super_block *s,void *data,
+struct super_block *minix_read_super(struct super_block *s, void *data,
 				     int silent)
 {
 	struct buffer_head *bh;
+	struct buffer_head **map;
 	struct minix_super_block *ms;
 	int i, block;
 	kdev_t dev = s->s_dev;
 	const char * errmsg;
 	struct inode *root_inode;
 	
+	/* N.B. These should be compile-time tests */
 	if (32 != sizeof (struct minix_inode))
 		panic("bad V1 i-node size");
 	if (64 != sizeof(struct minix2_inode))
 		panic("bad V2 i-node size");
+
 	MOD_INC_USE_COUNT;
 	lock_super(s);
 	set_blocksize(dev, BLOCK_SIZE);
-	if (!(bh = bread(dev,1,BLOCK_SIZE))) {
-		s->s_dev = 0;
-		unlock_super(s);
-		printk("MINIX-fs: unable to read superblock\n");
-		MOD_DEC_USE_COUNT;
-		return NULL;
-	}
+	if (!(bh = bread(dev,1,BLOCK_SIZE)))
+		goto out_bad_sb;
+
 	ms = (struct minix_super_block *) bh->b_data;
 	s->u.minix_sb.s_ms = ms;
 	s->u.minix_sb.s_sbh = bh;
@@ -192,6 +194,7 @@
 	s->s_blocksize = 1024;
 	s->s_blocksize_bits = 10;
 	s->u.minix_sb.s_ninodes = ms->s_ninodes;
+	s->u.minix_sb.s_nzones = ms->s_nzones;
 	s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
 	s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
 	s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
@@ -200,103 +203,74 @@
 	s->s_magic = ms->s_magic;
 	if (s->s_magic == MINIX_SUPER_MAGIC) {
 		s->u.minix_sb.s_version = MINIX_V1;
-		s->u.minix_sb.s_nzones = ms->s_nzones;
 		s->u.minix_sb.s_dirsize = 16;
 		s->u.minix_sb.s_namelen = 14;
 	} else if (s->s_magic == MINIX_SUPER_MAGIC2) {
 		s->u.minix_sb.s_version = MINIX_V1;
-		s->u.minix_sb.s_nzones = ms->s_nzones;
 		s->u.minix_sb.s_dirsize = 32;
 		s->u.minix_sb.s_namelen = 30;
 	} else if (s->s_magic == MINIX2_SUPER_MAGIC) {
 		s->u.minix_sb.s_version = MINIX_V2;
-		s->u.minix_sb.s_nzones = ms->s_zones;
 		s->u.minix_sb.s_dirsize = 16;
 		s->u.minix_sb.s_namelen = 14;
 	} else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
 		s->u.minix_sb.s_version = MINIX_V2;
-		s->u.minix_sb.s_nzones = ms->s_zones;
 		s->u.minix_sb.s_dirsize = 32;
 		s->u.minix_sb.s_namelen = 30;
-	} else {
-		s->s_dev = 0;
-		unlock_super(s);
-		brelse(bh);
-		if (!silent)
-			printk("VFS: Can't find a minix or minix V2 filesystem on dev "
-			       "%s.\n", kdevname(dev));
-		MOD_DEC_USE_COUNT;
-		return NULL;
-	}
-	for (i=0;i < MINIX_I_MAP_SLOTS;i++)
-		s->u.minix_sb.s_imap[i] = NULL;
-	for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
-		s->u.minix_sb.s_zmap[i] = NULL;
-	if (s->u.minix_sb.s_zmap_blocks > MINIX_Z_MAP_SLOTS) {
-		s->s_dev = 0;
-		unlock_super (s);
-		brelse (bh);
-		if (!silent)
-			printk ("MINIX-fs: filesystem too big\n");
-		MOD_DEC_USE_COUNT;
-		return NULL;
-	}
+	} else
+		goto out_no_fs;
+
+	if (s->u.minix_sb.s_zmap_blocks > MINIX_Z_MAP_SLOTS)
+		goto out_too_big;
+	/*
+	 * Allocate the buffer map to keep the superblock small.
+	 */
+	i = (MINIX_I_MAP_SLOTS + MINIX_Z_MAP_SLOTS) * sizeof(bh);
+	map = kmalloc(i, GFP_KERNEL);
+	if (!map)
+		goto out_no_map;
+	memset(map, 0, i);
+	s->u.minix_sb.s_imap = &map[0];
+	s->u.minix_sb.s_zmap = &map[MINIX_I_MAP_SLOTS];
+
 	block=2;
-	for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
-		if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
-			block++;
-		else
-			break;
-	for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
-		if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
-			block++;
-		else
-			break;
-	if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
-		for(i=0;i<MINIX_I_MAP_SLOTS;i++)
-			brelse(s->u.minix_sb.s_imap[i]);
-		for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
-			brelse(s->u.minix_sb.s_zmap[i]);
-		s->s_dev = 0;
-		unlock_super(s);
-		brelse(bh);
-		printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
-		MOD_DEC_USE_COUNT;
-		return NULL;
+	for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++) {
+		if (!(s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)))
+			goto out_no_bitmap;
+		block++;
+	}
+	for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++) {
+		if (!(s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)))
+			goto out_no_bitmap;
+		block++;
 	}
+	if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks)
+		goto out_no_bitmap;
+
 	minix_set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
 	minix_set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
-	unlock_super(s);
 	/* set up enough so that it can read an inode */
-	s->s_dev = dev;
 	s->s_op = &minix_sops;
-	root_inode = iget(s,MINIX_ROOT_INO);
-	s->s_root = d_alloc_root(root_inode, NULL);
-	if (!s->s_root) {
-		s->s_dev = 0;
-		brelse(bh);
-		if (!silent)
-			printk("MINIX-fs: get root inode failed\n");
-		MOD_DEC_USE_COUNT;
-		return NULL;
-	}
-
+	root_inode = iget(s, MINIX_ROOT_INO);
+	if (!root_inode)
+		goto out_no_root;
+	/*
+	 * Check the fs before we get the root dentry ...
+	 */
 	errmsg = minix_checkroot(s, root_inode);
-	if (errmsg) {
-		if (!silent)
-			printk("MINIX-fs: %s\n", errmsg);
-		d_delete(s->s_root); /* XXX Is this enough? */
-		s->s_dev = 0;
-		brelse (bh);
-		MOD_DEC_USE_COUNT;
-		return NULL;
-	}
+	if (errmsg)
+		goto out_bad_root;
+
+	s->s_root = d_alloc_root(root_inode, NULL);
+	if (!s->s_root)
+		goto out_iput;
 
 	if (!(s->s_flags & MS_RDONLY)) {
 		ms->s_state &= ~MINIX_VALID_FS;
 		mark_buffer_dirty(bh, 1);
 		s->s_dirt = 1;
 	}
+	unlock_super(s);
 	if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
 		printk ("MINIX-fs: mounting unchecked file system, "
 			"running fsck is recommended.\n");
@@ -304,6 +278,54 @@
 		printk ("MINIX-fs: mounting file system with errors, "
 			"running fsck is recommended.\n");
 	return s;
+
+out_bad_root:
+	if (!silent)
+		printk("MINIX-fs: %s\n", errmsg);
+out_iput:
+	iput(root_inode);
+	goto out_freemap;
+
+out_no_root:
+	if (!silent)
+		printk("MINIX-fs: get root inode failed\n");
+	goto out_freemap;
+
+out_no_bitmap:
+	printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
+    out_freemap:
+	for(i=0;i<MINIX_I_MAP_SLOTS;i++)
+		brelse(s->u.minix_sb.s_imap[i]);
+	for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
+		brelse(s->u.minix_sb.s_zmap[i]);
+	kfree(s->u.minix_sb.s_imap);
+	goto out_release;
+
+out_no_map:
+	if (!silent)
+		printk ("MINIX-fs: can't allocate map\n");
+	goto out_release;
+
+out_too_big:
+	if (!silent)
+		printk ("MINIX-fs: filesystem too big\n");
+	goto out_release;
+
+out_no_fs:
+	if (!silent)
+		printk("VFS: Can't find a minix or minix V2 filesystem on dev "
+		       "%s.\n", kdevname(dev));
+    out_release:
+	brelse(bh);
+	goto out_unlock;
+
+out_bad_sb:
+	printk("MINIX-fs: unable to read superblock\n");
+    out_unlock:
+	s->s_dev = 0;
+	unlock_super(s);
+	MOD_DEC_USE_COUNT;
+	return NULL;
 }
 
 int minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
diff -u --recursive --new-file v2.1.80/linux/fs/msdos/namei.c linux/fs/msdos/namei.c
--- v2.1.80/linux/fs/msdos/namei.c	Wed Dec 10 09:13:24 1997
+++ linux/fs/msdos/namei.c	Wed Jan 21 17:46:56 1998
@@ -21,8 +21,7 @@
 
 #include "../fat/msbuffer.h"
 
-#define MSDOS_PARANOIA 1	
-/* #define MSDOS_DEBUG 1 */	
+#define MSDOS_DEBUG 0
 #define PRINTK(x)
 
 /* MS-DOS "device special files" */
@@ -257,7 +256,7 @@
 	int ino,res;
 	struct msdos_dir_entry *de;
 	struct buffer_head *bh;
-	struct inode *next, *inode;
+	struct inode *inode;
 	
 	PRINTK (("msdos_lookup\n"));
 
@@ -294,20 +293,8 @@
 		return 0;
 	}
 	PRINTK (("msdos_lookup 6\n"));
-	while (MSDOS_I(inode)->i_old) {
-		next = MSDOS_I(inode)->i_old;
-#ifdef MSDOS_PARANOIA
-printk("msdos_lookup: ino %ld, old ino=%ld\n", inode->i_ino, next->i_ino);
-if (MSDOS_I(next)->i_depend != inode)
-printk("msdos_lookup: depend=%p, inode=%p??\n", MSDOS_I(next)->i_depend, inode);
-#endif
-		next->i_count++;
-		iput(inode);
-		inode = next;
-	}
-	PRINTK (("msdos_lookup 7\n"));
 	d_add(dentry, inode);
-	PRINTK (("msdos_lookup 8\n"));
+	PRINTK (("msdos_lookup 7\n"));
 	return 0;
 }
 
@@ -428,6 +415,9 @@
 		pos = 0;
 		bh = NULL;
 		while (fat_get_entry(dir,&pos,&bh,&de) > -1) {
+			/* Ignore vfat longname entries */
+			if (de->attr == ATTR_EXT)
+				continue;
 			if (!IS_FREE(de->name) && 
 			    strncmp(de->name,MSDOS_DOT   , MSDOS_NAME) &&
 			    strncmp(de->name,MSDOS_DOTDOT, MSDOS_NAME)) {
@@ -471,7 +461,7 @@
 	res = -EBUSY;
 	if (dentry->d_count > 1) {
 #ifdef MSDOS_DEBUG
-printk("rename_diff_dir: %s/%s busy, d_count=%d\n",
+printk("msdos_rmdir: %s/%s busy, d_count=%d\n",
 dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
 #endif
 		goto rmdir_done;
@@ -744,53 +734,31 @@
 		mark_inode_dirty(new_dir);
 	}
 	msdos_read_inode(free_inode);
-	/*
-	 * Check whether there's already a linked inode ...
-	 */
-	if (MSDOS_I(old_inode)->i_linked) {
-		struct inode *linked = MSDOS_I(old_inode)->i_linked;
-#ifdef MSDOS_PARANOIA
-printk("rename_diff_dir: inode %ld already has link %ld, freeing it\n",
-old_inode->i_ino, linked->i_ino);
-#endif
-		MSDOS_I(old_inode)->i_linked = NULL;
-		MSDOS_I(linked)->i_oldlink = NULL;
-		iput(linked);
-	}
-	MSDOS_I(old_inode)->i_busy = 1;
-	MSDOS_I(old_inode)->i_linked = free_inode;
-	MSDOS_I(free_inode)->i_oldlink = old_inode;
-#ifdef MSDOS_DEBUG
-printk("rename_diff_dir: inode %ld added as link of %ld\n",
-free_inode->i_ino, old_inode->i_ino);
-#endif
+
+	free_inode->i_mode   = old_inode->i_mode;
+	free_inode->i_size   = old_inode->i_size;
+	free_inode->i_blocks = old_inode->i_blocks;
+	free_inode->i_mtime  = old_inode->i_mtime;
+	free_inode->i_atime  = old_inode->i_atime;
+	free_inode->i_ctime  = old_inode->i_ctime;
+	MSDOS_I(free_inode)->i_ctime_ms = MSDOS_I(old_inode)->i_ctime_ms;
+
+	MSDOS_I(free_inode)->i_start = MSDOS_I(old_inode)->i_start;
+	MSDOS_I(free_inode)->i_logstart = MSDOS_I(old_inode)->i_logstart;
+	MSDOS_I(free_inode)->i_attrs = MSDOS_I(old_inode)->i_attrs;
+
+	/* Detach d_alias from old inode and attach to new inode */
+	list_del(&old_dentry->d_alias);
+	d_instantiate(old_dentry, free_inode);
+	iput(old_inode);
+
 	fat_cache_inval_inode(old_inode);
 	mark_inode_dirty(old_inode);
 	old_de->name[0] = DELETED_FLAG;
 	fat_mark_buffer_dirty(sb, old_bh, 1);
 	fat_mark_buffer_dirty(sb, free_bh, 1);
+
 	if (exists) {
-		/*
-		 * Check whether there's already a depend inode ...
-		 */
-		if (MSDOS_I(new_inode)->i_depend) {
-			struct inode *depend = MSDOS_I(new_inode)->i_depend;
-#ifdef MSDOS_PARANOIA
-printk("rename_diff_dir: inode %ld already has depend %ld, freeing it\n",
-new_inode->i_ino, depend->i_ino);
-#endif
-			MSDOS_I(new_inode)->i_depend = NULL;
-			MSDOS_I(depend)->i_old = NULL;
-			iput(depend);
-		}
-		MSDOS_I(new_inode)->i_depend = free_inode;
-		MSDOS_I(free_inode)->i_old = new_inode;
-		/* Two references now exist to free_inode so increase count */
-		free_inode->i_count++;
-#ifdef MSDOS_DEBUG
-printk("rename_diff_dir: inode %ld added as depend of %ld\n",
-free_inode->i_ino, new_inode->i_ino);
-#endif
 		/* free_inode is put after putting new_inode and old_inode */
 		fat_brelse(sb, new_bh);
 	}
@@ -815,6 +783,7 @@
 		iput(dotdot_inode);
 		fat_brelse(sb, dotdot_bh);
 	}
+
 	/* Update the dcache */
 	d_move(old_dentry, new_dentry);
 	error = 0;
diff -u --recursive --new-file v2.1.80/linux/fs/nfsd/export.c linux/fs/nfsd/export.c
--- v2.1.80/linux/fs/nfsd/export.c	Wed Nov 26 13:08:38 1997
+++ linux/fs/nfsd/export.c	Fri Jan 23 16:35:35 1998
@@ -433,19 +433,37 @@
 int
 exp_writelock(void)
 {
+	/* fast track */
+	if (!hash_count && !hash_lock) {
+	lock_it:
+		hash_lock = 1;
+		return 0;
+	}
+
+	current->sigpending = 0;
 	want_lock++;
-	while (hash_count || hash_lock)
+	while (hash_count || hash_lock) {
 		interruptible_sleep_on(&hash_wait);
+		if (signal_pending(current))
+			break;
+	}
 	want_lock--;
-	if (signal_pending(current))
-		return -EINTR;
-	hash_lock = 1;
-	return 0;
+
+	/* restore the task's signals */
+	spin_lock_irq(&current->sigmask_lock);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (!hash_count && !hash_lock)
+		goto lock_it;
+	return -EINTR;
 }
 
 void
 exp_unlock(void)
 {
+	if (!hash_count && !hash_lock)
+		printk(KERN_WARNING "exp_unlock: not locked!\n");
 	if (hash_count)
 		hash_count--;
 	else
diff -u --recursive --new-file v2.1.80/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.1.80/linux/fs/nfsd/nfsfh.c	Mon Jan 12 14:39:48 1998
+++ linux/fs/nfsd/nfsfh.c	Fri Jan 23 16:35:35 1998
@@ -999,21 +999,19 @@
 u32
 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
 {
+	struct knfs_fh	*fh = &fhp->fh_handle;
 	struct svc_export *exp;
 	struct dentry	*dentry;
 	struct inode	*inode;
-	struct knfs_fh	*fh = &fhp->fh_handle;
 	u32		error = 0;
 
-	if(fhp->fh_dverified)
-		goto out;
-
-	dprintk("nfsd: fh_lookup(exp %x/%ld fh %p)\n",
-			fh->fh_xdev, fh->fh_xino, fh->fh_dcookie);
+	dprintk("nfsd: fh_verify(exp %x/%ld cookie %p)\n",
+		fh->fh_xdev, fh->fh_xino, fh->fh_dcookie);
 
+	if(fhp->fh_dverified)
+		goto check_type;
 	/*
 	 * Look up the export entry.
-	 * N.B. We need to lock this while in use ...
 	 */
 	error = nfserr_stale;
 	exp = exp_get(rqstp->rq_client, fh->fh_xdev, fh->fh_xino);
@@ -1057,6 +1055,8 @@
 	 * spec says this is incorrect (implementation notes for the
 	 * write call).
 	 */
+check_type:
+	dentry = fhp->fh_dentry;
 	inode = dentry->d_inode;
 	if (type > 0 && (inode->i_mode & S_IFMT) != type) {
 		error = (type == S_IFDIR)? nfserr_notdir : nfserr_isdir;
@@ -1069,9 +1069,11 @@
 
 	/* Finally, check access permissions. */
 	error = nfsd_permission(fhp->fh_export, dentry, access);
+#ifdef NFSD_PARANOIA
 if (error)
 printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n",
 dentry->d_parent->d_name.name, dentry->d_name.name, access, error);
+#endif
 
 out:
 	return error;
diff -u --recursive --new-file v2.1.80/linux/fs/nfsd/nfssvc.c linux/fs/nfsd/nfssvc.c
--- v2.1.80/linux/fs/nfsd/nfssvc.c	Fri Dec 19 10:54:10 1997
+++ linux/fs/nfsd/nfssvc.c	Fri Jan 23 16:35:35 1998
@@ -42,6 +42,7 @@
 extern struct svc_program	nfsd_program;
 static void			nfsd(struct svc_rqst *rqstp);
 struct timeval			nfssvc_boot = { 0, 0 };
+static int			nfsd_active = 0;
 
 int
 nfsd_svc(unsigned short port, int nrservs)
@@ -97,6 +98,7 @@
 	oldumask = current->fs->umask;		/* Set umask to 0.  */
 	current->fs->umask = 0;
 	nfssvc_boot = xtime;			/* record boot time */
+	nfsd_active++;
 	lockd_up();				/* start lockd */
 
 	/*
@@ -160,6 +162,11 @@
 
 	/* Release lockd */
 	lockd_down();
+	if (!--nfsd_active) {
+		printk("nfsd: last server exiting\n");
+		/* revoke all exports */
+		nfsd_export_shutdown();
+	}
 
 	/* Destroy the thread */
 	svc_exit_thread(rqstp);
diff -u --recursive --new-file v2.1.80/linux/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- v2.1.80/linux/fs/ntfs/fs.c	Fri Jan  2 01:42:59 1998
+++ linux/fs/ntfs/fs.c	Fri Jan 23 17:38:05 1998
@@ -881,8 +881,8 @@
 ntfs_read_super_vol:
 	#ifndef NTFS_IN_LINUX_KERNEL
 	ntfs_free(vol);
-	#endif
 ntfs_read_super_dec:
+	#endif
 	ntfs_debug(DEBUG_OTHER, "read_super: done\n");
 	MOD_DEC_USE_COUNT;
 	return NULL;
diff -u --recursive --new-file v2.1.80/linux/fs/open.c linux/fs/open.c
--- v2.1.80/linux/fs/open.c	Sun Jan  4 00:53:41 1998
+++ linux/fs/open.c	Fri Jan 23 16:23:21 1998
@@ -546,6 +546,23 @@
 	int error;
 
 	lock_kernel();
+	dentry = namei(filename);
+
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		error = chown_common(dentry, user, group);
+		dput(dentry);
+	}
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage int sys_lchown(const char * filename, uid_t user, gid_t group)
+{
+	struct dentry * dentry;
+	int error;
+
+	lock_kernel();
 	dentry = lnamei(filename);
 
 	error = PTR_ERR(dentry);
diff -u --recursive --new-file v2.1.80/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.1.80/linux/fs/proc/array.c	Tue Jan 20 12:52:08 1998
+++ linux/fs/proc/array.c	Wed Jan 21 12:04:44 1998
@@ -221,20 +221,14 @@
 
 static int get_kstat(char * buffer)
 {
-	int i, j, len;
+	int i, len;
 	unsigned sum = 0;
 	extern unsigned long total_forks;
 	unsigned long ticks;
 
 	ticks = jiffies * smp_num_cpus;
-#ifndef __SMP__
 	for (i = 0 ; i < NR_IRQS ; i++)
-		sum += kstat.interrupts[0][i];
-#else
-	for (j = 0 ; j < smp_num_cpus ; j++)
-		for (i = 0 ; i < NR_IRQS ; i++)
-			sum += kstat.interrupts[cpu_logical_map[j]][i];
-#endif
+		sum += kstat_irqs(i);
 
 #ifdef __SMP__
 	len = sprintf(buffer,
@@ -246,12 +240,12 @@
 	for (i = 0 ; i < smp_num_cpus; i++)
 		len += sprintf(buffer + len, "cpu%d %u %u %u %lu\n",
 			i,
-			kstat.per_cpu_user[cpu_logical_map[i]],
-			kstat.per_cpu_nice[cpu_logical_map[i]],
-			kstat.per_cpu_system[cpu_logical_map[i]],
-			jiffies - (  kstat.per_cpu_user[cpu_logical_map[i]] \
-			           + kstat.per_cpu_nice[cpu_logical_map[i]] \
-			           + kstat.per_cpu_system[cpu_logical_map[i]]));
+			kstat.per_cpu_user[cpu_logical_map(i)],
+			kstat.per_cpu_nice[cpu_logical_map(i)],
+			kstat.per_cpu_system[cpu_logical_map(i)],
+			jiffies - (  kstat.per_cpu_user[cpu_logical_map(i)] \
+			           + kstat.per_cpu_nice[cpu_logical_map(i)] \
+			           + kstat.per_cpu_system[cpu_logical_map(i)]));
 	len += sprintf(buffer + len,
 		"disk %u %u %u %u\n"
 		"disk_rio %u %u %u %u\n"
@@ -292,17 +286,8 @@
 		kstat.pswpin,
 		kstat.pswpout,
 		sum);
-	for (i = 0 ; i < NR_IRQS ; i++) {
-#ifndef __SMP__
-		len += sprintf(buffer + len, " %u", kstat.interrupts[0][i]);
-#else
-		int sum=0;
-
-		for (j = 0 ; j < smp_num_cpus ; j++)
-			sum += kstat.interrupts[cpu_logical_map[j]][i];
-		len += sprintf(buffer + len, " %u", sum);
-#endif
-	}
+	for (i = 0 ; i < NR_IRQS ; i++)
+		len += sprintf(buffer + len, " %u", kstat_irqs(i));
 	len += sprintf(buffer + len,
 		"\nctxt %u\n"
 		"btime %lu\n"
@@ -1147,8 +1132,8 @@
 	for (i = 0 ; i < smp_num_cpus; i++)
 		len += sprintf(buffer + len, "cpu%d %lu %lu\n",
 			i,
-			tsk->per_cpu_utime[cpu_logical_map[i]],
-			tsk->per_cpu_stime[cpu_logical_map[i]]);
+			tsk->per_cpu_utime[cpu_logical_map(i)],
+			tsk->per_cpu_stime[cpu_logical_map(i)]);
 
 	return len;
 }
diff -u --recursive --new-file v2.1.80/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.1.80/linux/fs/proc/root.c	Tue Jan 20 12:52:08 1998
+++ linux/fs/proc/root.c	Fri Jan 23 16:46:45 1998
@@ -342,11 +342,6 @@
 		if (dp->ops == NULL)
 			dp->ops = &proc_file_inode_operations;
 	}
-	/*
-	 * kludge until we fixup the md device driver
-	 */
-	if (dp->low_ino == PROC_MD)
-		dp->ops = &proc_array_inode_operations;
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.80/linux/fs/smbfs/dir.c linux/fs/smbfs/dir.c
--- v2.1.80/linux/fs/smbfs/dir.c	Sun Jan  4 00:53:42 1998
+++ linux/fs/smbfs/dir.c	Wed Jan 21 10:09:31 1998
@@ -351,8 +351,6 @@
 		inode = smb_iget(dir->i_sb, &finfo);
 		if (inode)
 		{
-			/* cache the dentry pointer */
-			inode->u.smbfs_i.dentry = dentry;
 	add_entry:
 			dentry->d_op = &smbfs_dentry_operations;
 			d_add(dentry, inode);
@@ -372,8 +370,8 @@
 {
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	struct inode *inode;
-	struct smb_fattr fattr;
 	int error;
+	struct smb_fattr fattr;
 
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_instantiate: file %s/%s, fileid=%u\n",
@@ -395,8 +393,6 @@
 		inode->u.smbfs_i.access = SMB_O_RDWR;
 		inode->u.smbfs_i.open = server->generation;
 	}
-	/* cache the dentry pointer */
-	inode->u.smbfs_i.dentry = dentry;
 	d_instantiate(dentry, inode);
 out:
 	return error;
diff -u --recursive --new-file v2.1.80/linux/fs/smbfs/file.c linux/fs/smbfs/file.c
--- v2.1.80/linux/fs/smbfs/file.c	Sun Jan  4 00:53:42 1998
+++ linux/fs/smbfs/file.c	Wed Jan 21 10:09:31 1998
@@ -54,10 +54,9 @@
 static int
 smb_readpage_sync(struct dentry *dentry, struct page *page)
 {
-	struct inode *inode = dentry->d_inode;
 	char *buffer = (char *) page_address(page);
 	unsigned long offset = page->offset;
-	int rsize = smb_get_rsize(SMB_SERVER(inode));
+	int rsize = smb_get_rsize(server_from_dentry(dentry));
 	int count = PAGE_SIZE;
 	int result;
 
@@ -81,14 +80,14 @@
 		if (count < rsize)
 			rsize = count;
 
-		result = smb_proc_read(inode, offset, rsize, buffer);
+		result = smb_proc_read(dentry, offset, rsize, buffer);
 		if (result < 0)
 			goto io_error;
 
 		count -= result;
 		offset += result;
 		buffer += result;
-		inode->i_atime = CURRENT_TIME;
+		dentry->d_inode->i_atime = CURRENT_TIME;
 		if (result < rsize)
 			break;
 	} while (count);
@@ -129,7 +128,7 @@
 {
 	struct inode *inode = dentry->d_inode;
 	u8 *buffer = (u8 *) page_address(page) + offset;
-	int wsize = smb_get_wsize(SMB_SERVER(inode));
+	int wsize = smb_get_wsize(server_from_dentry(dentry));
 	int result, written = 0;
 
 	offset += page->offset;
@@ -142,7 +141,7 @@
 		if (count < wsize)
 			wsize = count;
 
-		result = smb_proc_write(inode, offset, wsize, buffer);
+		result = smb_proc_write(dentry, offset, wsize, buffer);
 		if (result < 0)
 			goto io_error;
 		/* N.B. what if result < wsize?? */
diff -u --recursive --new-file v2.1.80/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- v2.1.80/linux/fs/smbfs/inode.c	Sun Jan  4 00:53:42 1998
+++ linux/fs/smbfs/inode.c	Wed Jan 21 10:09:31 1998
@@ -181,6 +181,59 @@
 }
 
 /*
+ * This is called to update the inode attributes after
+ * we've made changes to a file or directory.
+ */
+static int
+smb_refresh_inode(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+	struct smb_fattr fattr;
+
+	error = smb_proc_getattr(dentry, &fattr);
+	if (!error)
+	{
+		smb_renew_times(dentry);
+		/*
+		 * Check whether the type part of the mode changed,
+		 * and don't update the attributes if it did.
+		 */
+		if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
+			smb_set_inode_attr(inode, &fattr);
+		else
+		{
+			/*
+			 * Big trouble! The inode has become a new object,
+			 * so any operations attempted on it are invalid.
+			 *
+			 * To limit damage, mark the inode as bad so that
+			 * subsequent lookup validations will fail.
+			 */
+#ifdef SMBFS_PARANOIA
+printk("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
+dentry->d_parent->d_name.name, dentry->d_name.name,
+inode->i_mode, fattr.f_mode);
+#endif
+			fattr.f_mode = inode->i_mode; /* save mode */
+			make_bad_inode(inode);
+			inode->i_mode = fattr.f_mode; /* restore mode */
+			/*
+			 * No need to worry about unhashing the dentry: the
+			 * lookup validation will see that the inode is bad.
+			 * But we do want to invalidate the caches ...
+			 */
+			if (!S_ISDIR(inode->i_mode))
+				invalidate_inode_pages(inode);
+			else
+				smb_invalid_dir_cache(inode);
+			error = -EIO;
+		}
+	}
+	return error;
+}
+
+/*
  * This is called when we want to check whether the inode
  * has changed on the server.  If it has changed, we must
  * invalidate our local caches.
@@ -220,7 +273,7 @@
 	 * (Note: a size change should have a different mtime.)
 	 */
 	last_time = inode->i_mtime;
-	error = smb_refresh_inode(inode);
+	error = smb_refresh_inode(dentry);
 	if (error || inode->i_mtime != last_time)
 	{
 #ifdef SMBFS_DEBUG_VERBOSE
@@ -238,99 +291,15 @@
 }
 
 /*
- * This is called to update the inode attributes after
- * we've made changes to a file or directory.
- */
-int
-smb_refresh_inode(struct inode *inode)
-{
-	struct dentry * dentry = inode->u.smbfs_i.dentry;
-	struct smb_fattr fattr;
-	int error;
-
-	pr_debug("smb_refresh_inode\n");
-	if (!dentry)
-	{
-		printk("smb_refresh_inode: no dentry, can't refresh\n");
-		error = -EIO;
-		goto out;
-	}
-
-	error = smb_proc_getattr(dentry, &fattr);
-	if (!error)
-	{
-		smb_renew_times(dentry);
-		/*
-		 * Check whether the type part of the mode changed,
-		 * and don't update the attributes if it did.
-		 */
-		if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
-			smb_set_inode_attr(inode, &fattr);
-		else
-		{
-			/*
-			 * Big trouble! The inode has become a new object,
-			 * so any operations attempted on it are invalid.
-			 *
-			 * To limit damage, mark the inode as bad so that
-			 * subsequent lookup validations will fail.
-			 */
-#ifdef SMBFS_PARANOIA
-printk("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-inode->i_mode, fattr.f_mode);
-#endif
-			fattr.f_mode = inode->i_mode; /* save mode */
-			make_bad_inode(inode);
-			inode->i_mode = fattr.f_mode; /* restore mode */
-			/*
-			 * No need to worry about unhashing the dentry: the
-			 * lookup validation will see that the inode is bad.
-			 * But we do want to invalidate the caches ...
-			 */
-			if (!S_ISDIR(inode->i_mode))
-				invalidate_inode_pages(inode);
-			else
-				smb_invalid_dir_cache(inode);
-			error = -EIO;
-		}
-	}
-out:
-	return error;
-
-}
-
-/*
- * This routine is called for every iput().
+ * This routine is called for every iput(). We clear i_nlink
+ * on the last use to force a call to delete_inode.
  */
 static void
 smb_put_inode(struct inode *ino)
 {
 	pr_debug("smb_put_inode: count = %d\n", ino->i_count);
-
-	if (ino->i_count > 1) {
-		struct dentry * dentry;
-		/*
-		 * Check whether the dentry still holds this inode. 
-		 * This looks scary, but should work ... if this is
-		 * the last use, d_inode == NULL or d_count == 0. 
-		 */
-		dentry = (struct dentry *) ino->u.smbfs_i.dentry;
-		if (dentry && (dentry->d_inode != ino || dentry->d_count == 0))
-		{
-			ino->u.smbfs_i.dentry = NULL;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_put_inode: cleared dentry for %s/%s (%ld), count=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ino->i_ino, ino->i_count);
-#endif
-		}
-	} else {
-		/*
-		 * Last use ... clear i_nlink to force
-		 * smb_delete_inode to be called.
-	 	*/
+	if (ino->i_count == 1)
 		ino->i_nlink = 0;
-	}
 }
 
 /*
@@ -379,7 +348,6 @@
 {
 	struct smb_mount_data *mnt;
 	struct inode *root_inode;
-	struct dentry *dentry;
 	struct smb_fattr root;
 
 	MOD_INC_USE_COUNT;
@@ -435,6 +403,8 @@
 		printk("SMBFS: Win 95 bug fixes enabled\n");
 	if (mnt->version & SMB_FIX_OLDATTR)
 		printk("SMBFS: Using core getattr (Win 95 speedup)\n");
+	else if (mnt->version & SMB_FIX_DIRATTR)
+		printk("SMBFS: Using dir ff getattr\n");
 
 	/*
 	 * Keep the super block locked while we get the root inode.
@@ -444,11 +414,9 @@
 	if (!root_inode)
 		goto out_no_root;
 
-	dentry = d_alloc_root(root_inode, NULL);
-	if (!dentry)
+	sb->s_root = d_alloc_root(root_inode, NULL);
+	if (!sb->s_root)
 		goto out_no_root;
-	root_inode->u.smbfs_i.dentry = dentry;
-	sb->s_root = dentry;
 
 	unlock_super(sb);
 	return sb;
@@ -465,7 +433,7 @@
 	unlock_super(sb);
 	goto out_fail;
 out_wrong_data:
-	printk("smb_read_super: need mount version %d\n", SMB_MOUNT_VERSION);
+	printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION);
 	goto out_fail;
 out_no_data:
 	printk("smb_read_super: missing data argument\n");
@@ -609,7 +577,7 @@
 
 out:
 	if (refresh)
-		smb_refresh_inode(inode);
+		smb_refresh_inode(dentry);
 	return error;
 }
 
diff -u --recursive --new-file v2.1.80/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- v2.1.80/linux/fs/smbfs/proc.c	Fri Dec 19 10:53:29 1997
+++ linux/fs/smbfs/proc.c	Wed Jan 21 10:09:31 1998
@@ -531,7 +531,8 @@
 	if (server->state == CONN_VALID)
 	{
 #ifdef SMBFS_PARANOIA
-printk("smb_retry: new connection pid=%d\n", server->conn_pid);
+printk("smb_retry: new pid=%d, generation=%d\n",
+server->conn_pid, server->generation);
 #endif
 		result = 1;
 	}
@@ -643,25 +644,17 @@
 	}
 	server->conn_pid = current->pid;
 
-#ifdef SMBFS_PARANOIA
-if (server->sock_file)
-printk("smb_newconn: old socket not closed!\n");
-#endif
-
 	filp->f_count += 1;
 	server->sock_file = filp;
 	smb_catch_keepalive(server);
 	server->opt = *opt;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_newconn: protocol=%d, max_xmit=%d\n",
-server->opt.protocol, server->opt.max_xmit);
-#endif
 	server->generation += 1;
 	server->state = CONN_VALID;
-#ifdef SMBFS_PARANOIA
-printk("smb_newconn: state valid, pid=%d\n", server->conn_pid);
-#endif
 	error = 0;
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_newconn: protocol=%d, max_xmit=%d, pid=%d\n",
+server->opt.protocol, server->opt.max_xmit, server->conn_pid);
+#endif
 
 out:
 	wake_up_interruptible(&server->wait);
@@ -987,9 +980,9 @@
    file-id would not be valid after a reconnection. */
 
 int
-smb_proc_read(struct inode *ino, off_t offset, int count, char *data)
+smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
 {
-	struct smb_sb_info *server = SMB_SERVER(ino);
+	struct smb_sb_info *server = server_from_dentry(dentry);
 	__u16 returned_count, data_len;
 	char *buf;
 	int result;
@@ -997,7 +990,7 @@
 	smb_lock_server(server);
 	smb_setup_header(server, SMBread, 5, 0);
 	buf = server->packet;
-	WSET(buf, smb_vwv0, ino->u.smbfs_i.fileid);
+	WSET(buf, smb_vwv0, dentry->d_inode->u.smbfs_i.fileid);
 	WSET(buf, smb_vwv1, count);
 	DSET(buf, smb_vwv2, offset);
 	WSET(buf, smb_vwv4, 0);
@@ -1022,29 +1015,27 @@
 out:
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_read: file %s/%s, count=%d, result=%d\n",
-((struct dentry *) ino->u.smbfs_i.dentry)->d_parent->d_name.name, 
-((struct dentry *) ino->u.smbfs_i.dentry)->d_name.name, count, result);
+dentry->d_parent->d_name.name, dentry->d_name.name, count, result);
 #endif
 	smb_unlock_server(server);
 	return result;
 }
 
 int
-smb_proc_write(struct inode *ino, off_t offset, int count, const char *data)
+smb_proc_write(struct dentry *dentry, off_t offset, int count, const char *data)
 {
-	struct smb_sb_info *server = SMB_SERVER(ino);
+	struct smb_sb_info *server = server_from_dentry(dentry);
 	int result;
 	__u8 *p;
 
-	smb_lock_server(server);
 #if SMBFS_DEBUG_VERBOSE
 printk("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
-((struct dentry *)ino->u.smbfs_i.dentry)->d_parent->d_name.name, 
-((struct dentry *)ino->u.smbfs_i.dentry)->d_name.name, 
+dentry->d_parent->d_name.name, dentry->d_name.name, 
 count, offset, server->packet_size);
 #endif
+	smb_lock_server(server);
 	p = smb_setup_header(server, SMBwrite, 5, count + 3);
-	WSET(server->packet, smb_vwv0, ino->u.smbfs_i.fileid);
+	WSET(server->packet, smb_vwv0, dentry->d_inode->u.smbfs_i.fileid);
 	WSET(server->packet, smb_vwv1, count);
 	DSET(server->packet, smb_vwv2, offset);
 	WSET(server->packet, smb_vwv4, 0);
@@ -1544,9 +1535,10 @@
 	 * Check whether to change the info level.  There appears to be
 	 * a bug in Win NT 4.0's handling of info level 1, whereby it
 	 * truncates the directory scan for certain patterns of files.
-	 * Hence we use level 259 for NT. (And Win 95 as well ...)
+	 * Hence we use level 259 for NT.
 	 */
-	if (server->opt.protocol >= SMB_PROTOCOL_NT1)
+	if (server->opt.protocol >= SMB_PROTOCOL_NT1 &&
+	    !(server->mnt->version & SMB_FIX_WIN95))
 		info_level = 259;
 
 	smb_lock_server(server);
@@ -1639,8 +1631,8 @@
 		if (server->rcls != 0)
 		{ 
 #ifdef SMBFS_PARANOIA
-printk("smb_proc_readdir_long: rcls=%d, err=%d, breaking\n",
-server->rcls, server->err);
+printk("smb_proc_readdir_long: name=%s, entries=%d, rcls=%d, err=%d\n",
+mask, entries, server->rcls, server->err);
 #endif
 			entries = -smb_errno(server);
 			break;
@@ -1750,6 +1742,94 @@
 }
 
 /*
+ * This version uses the trans2 TRANSACT2_FINDFIRST message 
+ * to get the attribute data.
+ * Note: called with the server locked.
+ *
+ * Bugs Noted:
+ */
+static int
+smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
+			struct smb_fattr *fattr)
+{
+	char *param = server->temp_buf, *mask = param + 12;
+	__u16 date, time;
+	unsigned char *resp_data = NULL;
+	unsigned char *resp_param = NULL;
+	int resp_data_len = 0;
+	int resp_param_len = 0;
+	int mask_len, result;
+
+retry:
+	mask_len = smb_encode_path(server, mask, dentry, NULL) - mask;
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_proc_getattr_ff: name=%s, len=%d\n", mask, mask_len);
+#endif
+	WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
+	WSET(param, 2, 1);	/* max count */
+	WSET(param, 4, 1);	/* close after this call */
+	WSET(param, 6, 1);	/* info_level */
+	DSET(param, 8, 0);
+
+	result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
+				    0, NULL, 12 + mask_len + 1, param,
+				    &resp_data_len, &resp_data,
+				    &resp_param_len, &resp_param);
+	if (result < 0)
+	{
+		if (smb_retry(server))
+			goto retry;
+		goto out;
+	}
+	if (server->rcls != 0)
+	{ 
+		result = -smb_errno(server);
+#ifdef SMBFS_PARANOIA
+if (result != -ENOENT)
+printk("smb_proc_getattr_ff: error for %s, rcls=%d, err=%d\n",
+mask, server->rcls, server->err);
+#endif
+		goto out;
+	}
+	/* Make sure we got enough data ... */
+	result = -EINVAL;
+	if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)
+	{
+#ifdef SMBFS_PARANOIA
+printk("smb_proc_getattr_ff: bad result for %s, len=%d, count=%d\n",
+mask, resp_data_len, WVAL(resp_param, 2));
+#endif
+		goto out;
+	}
+
+	/*
+	 * Decode the response into the fattr ...
+	 */
+	date = WVAL(resp_data, 0);
+	time = WVAL(resp_data, 2);
+	fattr->f_ctime = date_dos2unix(date, time);
+
+	date = WVAL(resp_data, 4);
+	time = WVAL(resp_data, 6);
+	fattr->f_atime = date_dos2unix(date, time);
+
+	date = WVAL(resp_data, 8);
+	time = WVAL(resp_data, 10);
+	fattr->f_mtime = date_dos2unix(date, time);
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_proc_getattr_ff: name=%s, date=%x, time=%x, mtime=%ld\n",
+mask, date, time, fattr->f_mtime);
+#endif
+	fattr->f_size = DVAL(resp_data, 12);
+	/* ULONG allocation size */
+	fattr->attr = WVAL(resp_data, 20);
+	result = 0;
+
+out:
+	return result;
+}
+
+/*
  * Note: called with the server locked.
  */
 static int
@@ -1883,11 +1963,17 @@
 	 * Win 95 is painfully slow at returning trans2 getattr info,
 	 * so we provide the SMB_FIX_OLDATTR option switch.
  	 */
-	if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 &&
-	    !(server->mnt->version & SMB_FIX_OLDATTR))
-		result = smb_proc_getattr_trans2(server, dir, fattr);
-	else
+	if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) {
+		if (server->mnt->version & SMB_FIX_OLDATTR)
+			goto core_attr;
+		if (server->mnt->version & SMB_FIX_DIRATTR)
+			result = smb_proc_getattr_ff(server, dir, fattr);
+		else
+			result = smb_proc_getattr_trans2(server, dir, fattr);
+	} else {
+	core_attr:
 		result = smb_proc_getattr_core(server, dir, fattr);
+	}
 
 	smb_finish_dirent(server, fattr);
 
diff -u --recursive --new-file v2.1.80/linux/fs/super.c linux/fs/super.c
--- v2.1.80/linux/fs/super.c	Mon Jan 12 15:12:00 1998
+++ linux/fs/super.c	Wed Jan 21 14:29:34 1998
@@ -95,28 +95,37 @@
 	/* NOTREACHED */
 }
 
-struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_name)
+static struct vfsmount *add_vfsmnt(struct super_block *sb,
+			const char *dev_name, const char *dir_name)
 {
 	struct vfsmount *lptr;
-	char *tmp;
+	char *tmp, *name;
 
 	lptr = (struct vfsmount *)kmalloc(sizeof(struct vfsmount), GFP_KERNEL);
-        if (!lptr)
-		return NULL;
+	if (!lptr)
+		goto out;
 	memset(lptr, 0, sizeof(struct vfsmount));
 
-	lptr->mnt_dev = dev;
+	lptr->mnt_sb = sb;
+	lptr->mnt_dev = sb->s_dev;
+	lptr->mnt_flags = sb->s_flags;
 	sema_init(&lptr->mnt_sem, 1);
+
+	/* N.B. Is it really OK to have a vfsmount without names? */
 	if (dev_name && !IS_ERR(tmp = getname(dev_name))) {
-		if ((lptr->mnt_devname =
-		    (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
-			strcpy(lptr->mnt_devname, tmp);
+		name = (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL);
+		if (name) {
+			strcpy(name, tmp);
+			lptr->mnt_devname = name;
+		}
 		putname(tmp);
 	}
 	if (dir_name && !IS_ERR(tmp = getname(dir_name))) {
-		if ((lptr->mnt_dirname =
-		    (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
-			strcpy(lptr->mnt_dirname, tmp);
+		name = (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL);
+		if (name) {
+			strcpy(name, tmp);
+			lptr->mnt_dirname = name;
+		}
 		putname(tmp);
 	}
 
@@ -126,10 +135,11 @@
 		vfsmnttail->mnt_next = lptr;
 		vfsmnttail = lptr;
 	}
-	return (lptr);
+out:
+	return lptr;
 }
 
-void remove_vfsmnt(kdev_t dev)
+static void remove_vfsmnt(kdev_t dev)
 {
 	struct vfsmount *lptr, *tofree;
 
@@ -496,6 +506,23 @@
 	return err;
 }
 
+/*
+ * Find a super_block with no device assigned.
+ */
+static struct super_block *get_empty_super(void)
+{
+	struct super_block *s = 0+super_blocks;
+
+	for (; s < NR_SUPER+super_blocks; s++) {
+		if (s->s_dev)
+			continue;
+		if (!s->s_lock)
+			return s;
+		printk("VFS: empty superblock %p locked!\n", s);
+	}
+	return NULL;
+}
+
 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
 				       void *data, int silent)
 {
@@ -503,44 +530,39 @@
 	struct file_system_type *type;
 
 	if (!dev)
-		goto out_fail;
+		goto out_null;
 	check_disk_change(dev);
 	s = get_super(dev);
 	if (s)
-		return s;
+		goto out;
+
 	type = get_fs_type(name);
 	if (!type) {
 		printk("VFS: on device %s: get_fs_type(%s) failed\n",
 		       kdevname(dev), name);
-		goto out_fail;
-	}
-	for (s = 0+super_blocks ;; s++) {
-		if (s >= NR_SUPER+super_blocks)
-			goto out_fail;
-		if (s->s_dev)
-			continue;
-		if (s->s_lock) {
-			printk("VFS: empty superblock %p locked!\n", s);
-			continue;
-		}
-		break;
+		goto out;
 	}
+	s = get_empty_super();
+	if (!s)
+		goto out;
 	s->s_dev = dev;
 	s->s_flags = flags;
 	s->s_dirt = 0;
 	/* N.B. Should lock superblock now ... */
-	if (!type->read_super(s,data, silent))
-		goto fail;
+	if (!type->read_super(s, data, silent))
+		goto out_fail;
 	s->s_dev = dev; /* N.B. why do this again?? */
 	s->s_rd_only = 0;
 	s->s_type = type;
+out:
 	return s;
 
 	/* N.B. s_dev should be cleared in type->read_super */
-fail:
-	s->s_dev = 0;
 out_fail:
-	return NULL;
+	s->s_dev = 0;
+out_null:
+	s = NULL;
+	goto out;
 }
 
 /*
@@ -603,17 +625,16 @@
 	dentry->d_covers = covered;
 }
 
-static int do_umount(kdev_t dev,int unmount_root)
+static int do_umount(kdev_t dev, int unmount_root)
 {
 	struct super_block * sb;
 	int retval;
 	
+	retval = -ENOENT;
 	sb = get_super(dev);
-	if (!sb)
-		return -ENOENT;
+	if (!sb || !sb->s_root)
+		goto out;
 
-	if (!sb->s_root)
-		return -ENOENT;
 	/*
 	 * Before checking whether the filesystem is still busy,
 	 * make sure the kernel doesn't hold any quotafiles open
@@ -659,7 +680,6 @@
 			sb->s_op->put_super(sb);
 	}
 	remove_vfsmnt(dev);
-	retval = 0;
 out:
 	return retval;
 }
@@ -781,7 +801,7 @@
 
 int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
 {
-	struct dentry * dir_d = NULL;
+	struct dentry * dir_d;
 	struct super_block * sb;
 	struct vfsmount *vfsmnt;
 	int error;
@@ -806,15 +826,13 @@
 		goto dput_and_out;
 
 	/*
-	 * Check whether to read the super block
+	 * Note: If the superblock already exists,
+	 * read_super just does a get_super().
 	 */
-	sb = get_super(dev);
-	if (!sb || !sb->s_root) {
-		error = -EINVAL;
-		sb = read_super(dev,type,flags,data,0);
-		if (!sb)
-			goto dput_and_out;
-	}
+	error = -EINVAL;
+	sb = read_super(dev, type, flags, data, 0);
+	if (!sb)
+		goto dput_and_out;
 
 	/*
 	 * We may have slept while reading the super block, 
@@ -825,20 +843,19 @@
 		goto dput_and_out;
 
 	error = -ENOMEM;
-	vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
-	if (vfsmnt) {
-		vfsmnt->mnt_sb = sb;
-		vfsmnt->mnt_flags = flags;
-		d_mount(dir_d, sb->s_root);
-		error = 0;
-		goto out;		/* we don't dput(dir) - see umount */
-	}
+	vfsmnt = add_vfsmnt(sb, dev_name, dir_name);
+	if (!vfsmnt)
+		goto dput_and_out;
+	d_mount(dir_d, sb->s_root);
+	error = 0;	/* we don't dput(dir_d) - see umount */
 
-dput_and_out:
-	dput(dir_d);
 out:
 	up(&mount_sem);
 	return error;	
+
+dput_and_out:
+	dput(dir_d);
+	goto out;
 }
 
 
@@ -1063,14 +1080,11 @@
 	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 		ROOT_DEV = 0;
 		if ((fs_type = get_fs_type("nfs"))) {
-			if ((vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/"))) {
-
-				sb = &super_blocks[0];
-				while (sb->s_dev) sb++;
-				vfsmnt->mnt_sb = sb;
-
-				sb->s_dev = get_unnamed_dev();
-				sb->s_flags = root_mountflags & ~MS_RDONLY;
+			sb = get_empty_super(); /* "can't fail" */
+			sb->s_dev = get_unnamed_dev();
+			sb->s_flags = root_mountflags & ~MS_RDONLY;
+			vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
+			if (vfsmnt) {
 				if (nfs_root_mount(sb) >= 0) {
 					sb->s_rd_only = 0;
 					sb->s_dirt = 0;
@@ -1081,9 +1095,10 @@
 					printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
 					return;
 				}
-				sb->s_dev = 0;
-				put_unnamed_dev(sb->s_dev);
+				remove_vfsmnt(sb->s_dev);
 			}
+			put_unnamed_dev(sb->s_dev);
+			sb->s_dev = 0;
 		}
 		if (!ROOT_DEV) {
 			printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
@@ -1136,12 +1151,10 @@
 			printk ("VFS: Mounted root (%s filesystem)%s.\n",
 				fs_type->name,
 				(sb->s_flags & MS_RDONLY) ? " readonly" : "");
-			vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/");
-			if (!vfsmnt)
-				panic("VFS: add_vfsmnt failed for root fs");
-			vfsmnt->mnt_sb = sb;
-			vfsmnt->mnt_flags = root_mountflags;
-			return;
+			vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
+			if (vfsmnt)
+				return;
+			panic("VFS: add_vfsmnt failed for root fs");
 		}
 	}
 	panic("VFS: Unable to mount root fs on %s",
@@ -1225,10 +1238,8 @@
 		return error;
 	}
 	remove_vfsmnt(old_root_dev);
-	vfsmnt = add_vfsmnt(old_root_dev,"/dev/root.old",put_old);
+	vfsmnt = add_vfsmnt(old_root->d_sb, "/dev/root.old", put_old);
 	if (vfsmnt) {
-		vfsmnt->mnt_sb = old_root->d_inode->i_sb;
-		vfsmnt->mnt_flags = vfsmnt->mnt_sb->s_flags;
 		d_mount(dir_d,old_root);
 		return 0;
 	}
diff -u --recursive --new-file v2.1.80/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.1.80/linux/fs/vfat/namei.c	Tue Jan 13 20:07:28 1998
+++ linux/fs/vfat/namei.c	Wed Jan 21 17:46:56 1998
@@ -27,10 +27,21 @@
 
 #include "../fat/msbuffer.h"
 
-#if 0
-# define PRINTK(x) printk x
+#define DEBUG_LEVEL 0
+#if (DEBUG_LEVEL >= 1)
+#  define PRINTK1(x) printk x
+#else
+#  define PRINTK1(x)
+#endif
+#if (DEBUG_LEVEL >= 2)
+#  define PRINTK2(x) printk x
 #else
-# define PRINTK(x)
+#  define PRINTK2(x)
+#endif
+#if (DEBUG_LEVEL >= 3)
+#  define PRINTK3(x) printk x
+#else
+#  define PRINTK3(x)
 #endif
 
 #ifndef DEBUG
@@ -114,6 +125,7 @@
 
 static int vfat_revalidate(struct dentry *dentry)
 {
+	PRINTK1(("vfat_revalidate: %s\n", dentry->d_name.name));
 	if (dentry->d_time == dentry->d_parent->d_inode->i_version) {
 		return 1;
 	}
@@ -309,6 +321,9 @@
 		MOD_DEC_USE_COUNT;
 	} else {
 		MSDOS_SB(sb)->options.dotsOK = 0;
+		if (MSDOS_SB(sb)->options.posixfs) {
+			MSDOS_SB(sb)->options.name_check = 's';
+		}
 		if (MSDOS_SB(sb)->options.name_check != 's') {
 			sb->s_root->d_op = &vfat_dentry_ops[0];
 		} else {
@@ -600,7 +615,7 @@
 	const char *name_start;
 	struct qstr qname;
 
-	PRINTK(("Entering vfat_create_shortname: name=%s, len=%d\n", name, len));
+	PRINTK2(("Entering vfat_create_shortname: name=%s, len=%d\n", name, len));
 	sz = 0;			/* Make compiler happy */
 	if (len && name[len-1]==' ') return -EINVAL;
 	if (len <= 12) {
@@ -625,17 +640,17 @@
 			res = vfat_format_name(msdos_name, len, name_res, 1, utf8);
 		}
 		if (res > -1) {
-			PRINTK(("vfat_create_shortname 1\n"));
+			PRINTK3(("vfat_create_shortname 1\n"));
 			qname.name=msdos_name;
 			qname.len=len;
 			res = vfat_find(dir, &qname, 0, 0, 0, &sinfo);
-			PRINTK(("vfat_create_shortname 2\n"));
+			PRINTK3(("vfat_create_shortname 2\n"));
 			if (res > -1) return -EEXIST;
 			return 0;
 		}
 	}
 
-	PRINTK(("vfat_create_shortname 3\n"));
+	PRINTK3(("vfat_create_shortname 3\n"));
 	/* Now, we need to create a shortname from the long name */
 	ext_start = end = &name[len];
 	while (--ext_start >= name) {
@@ -793,7 +808,7 @@
 	int res;
 	int added;
 
-	PRINTK(("vfat_find_free_slots: find %d free slots\n", slots));
+	PRINTK2(("vfat_find_free_slots: find %d free slots\n", slots));
 	offset = curr = 0;
 	bh = NULL;
 	row = 0;
@@ -807,7 +822,7 @@
 				if (inode) {
 					/* Directory slots of busy deleted files aren't available yet. */
 					done = !MSDOS_I(inode)->i_busy;
-					/* PRINTK(("inode %d still busy\n", ino)); */
+					/* PRINTK3(("inode %d still busy\n", ino)); */
 					iput(inode);
 				}
 			}
@@ -934,18 +949,18 @@
 	for (cksum = i = 0; i < 11; i++) {
 		cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
 	}
-	PRINTK(("vfat_fill_long_slots 3: slots=%d\n",*slots));
+	PRINTK3(("vfat_fill_long_slots 3: slots=%d\n",*slots));
 
 	for (ps = ds, slot = *slots; slot > 0; slot--, ps++) {
 		int end, j;
 
-		PRINTK(("vfat_fill_long_slots 4\n"));
+		PRINTK3(("vfat_fill_long_slots 4\n"));
 		ps->id = slot;
 		ps->attr = ATTR_EXT;
 		ps->reserved = 0;
 		ps->alias_checksum = cksum;
 		ps->start = 0;
-		PRINTK(("vfat_fill_long_slots 5: uniname=%s\n",uniname));
+		PRINTK3(("vfat_fill_long_slots 5: uniname=%s\n",uniname));
 		offset = (slot - 1) * 26;
 		ip = &uniname[offset];
 		j = offset;
@@ -954,22 +969,22 @@
 			ps->name0_4[i] = *ip++;
 			ps->name0_4[i+1] = *ip++;
 		}
-		PRINTK(("vfat_fill_long_slots 6\n"));
+		PRINTK3(("vfat_fill_long_slots 6\n"));
 		for (i = 0; i < 12; i += 2) {
 			ps->name5_10[i] = *ip++;
 			ps->name5_10[i+1] = *ip++;
 		}
-		PRINTK(("vfat_fill_long_slots 7\n"));
+		PRINTK3(("vfat_fill_long_slots 7\n"));
 		for (i = 0; i < 4; i += 2) {
 			ps->name11_12[i] = *ip++;
 			ps->name11_12[i+1] = *ip++;
 		}
 	}
-	PRINTK(("vfat_fill_long_slots 8\n"));
+	PRINTK3(("vfat_fill_long_slots 8\n"));
 	ds[0].id |= 0x40;
 
 	de = (struct msdos_dir_entry *) ps;
-	PRINTK(("vfat_fill_long_slots 9\n"));
+	PRINTK3(("vfat_fill_long_slots 9\n"));
 	strncpy(de->name, msdos_name, MSDOS_NAME);
 
 	free_page(page);
@@ -984,7 +999,7 @@
 	int res, xlate, utf8;
 	struct nls_table *nls;
 
-	PRINTK(("Entering vfat_build_slots: name=%s, len=%d\n", name, len));
+	PRINTK2(("Entering vfat_build_slots: name=%s, len=%d\n", name, len));
 	de = (struct msdos_dir_entry *) ds;
 	xlate = MSDOS_SB(dir->i_sb)->options.unicode_xlate;
 	utf8 = MSDOS_SB(dir->i_sb)->options.utf8;
@@ -997,12 +1012,12 @@
 	} else if (len == 2 && name[0] == '.' && name[1] == '.') {
 		strncpy(de->name, MSDOS_DOT, MSDOS_NAME);
 	} else {
-		PRINTK(("vfat_build_slots 4\n"));
+		PRINTK3(("vfat_build_slots 4\n"));
 		res = vfat_valid_shortname(name, len, 1, utf8);
 		if (res > -1) {
-			PRINTK(("vfat_build_slots 5a\n"));
+			PRINTK3(("vfat_build_slots 5a\n"));
 			res = vfat_format_name(name, len, de->name, 1, utf8);
-			PRINTK(("vfat_build_slots 5b\n"));
+			PRINTK3(("vfat_build_slots 5b\n"));
 		} else {
 			res = vfat_create_shortname(dir, name, len, msdos_name, utf8);
 			if (res < 0) {
@@ -1082,7 +1097,7 @@
 	int slots, slot;
 	int res;
 
-	PRINTK(("Entering vfat_find\n"));
+	PRINTK2(("Entering vfat_find\n"));
 
 	ds = (struct msdos_dir_slot *)
 	    kmalloc(sizeof(struct msdos_dir_slot)*MSDOS_SLOTS, GFP_KERNEL);
@@ -1096,7 +1111,7 @@
 	vf.posix = MSDOS_SB(sb)->options.posixfs;
 	vf.anycase = (MSDOS_SB(sb)->options.name_check != 's');
 	res = fat_readdirx(dir,&fil,(void *)&vf,vfat_readdir_cb,NULL,1,find_long,0);
-	PRINTK(("vfat_find: Debug 1\n"));
+	PRINTK3(("vfat_find: Debug 1\n"));
 	if (res < 0) goto cleanup;
 	if (vf.found) {
 		if (new_filename) {
@@ -1110,12 +1125,12 @@
 		sinfo_out->total_slots = vf.long_slots + 1;
 		sinfo_out->ino = vf.ino;
 
-		PRINTK(("vfat_find: Debug 2\n"));
+		PRINTK3(("vfat_find: Debug 2\n"));
 		res = 0;
 		goto cleanup;
 	}
 
-	PRINTK(("vfat_find: Debug 3\n"));
+	PRINTK3(("vfat_find: Debug 3\n"));
 	if (!vf.found && !new_filename) {
 		res = -ENOENT;
 		goto cleanup;
@@ -1129,7 +1144,7 @@
 
 	bh = NULL;
 	if (new_filename) {
-		PRINTK(("vfat_find: create file 1\n"));
+		PRINTK3(("vfat_find: create file 1\n"));
 		if (is_long) slots++;
 		offset = vfat_find_free_slots(dir, slots);
 		if (offset < 0) {
@@ -1137,14 +1152,14 @@
 			goto cleanup;
 		}
 
-		PRINTK(("vfat_find: create file 2\n"));
+		PRINTK3(("vfat_find: create file 2\n"));
 		/* Now create the new entry */
 		bh = NULL;
 		for (slot = 0, ps = ds; slot < slots; slot++, ps++) {
-			PRINTK(("vfat_find: create file 3, slot=%d\n",slot));
+			PRINTK3(("vfat_find: create file 3, slot=%d\n",slot));
 			sinfo_out->ino = fat_get_entry(dir,&offset,&bh,&de);
 			if (sinfo_out->ino < 0) {
-				PRINTK(("vfat_find: problem\n"));
+				PRINTK3(("vfat_find: problem\n"));
 				res = sinfo_out->ino;
 				goto cleanup;
 			}
@@ -1152,11 +1167,11 @@
 			fat_mark_buffer_dirty(sb, bh, 1);
 		}
 
-		PRINTK(("vfat_find: create file 4\n"));
+		PRINTK3(("vfat_find: create file 4\n"));
 		dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
 		mark_inode_dirty(dir);
 
-		PRINTK(("vfat_find: create file 5\n"));
+		PRINTK3(("vfat_find: create file 5\n"));
 
 		fat_date_unix2dos(dir->i_mtime,&de->time,&de->date);
 		de->ctime_ms = 0;
@@ -1198,7 +1213,7 @@
 	struct inode *result;
 	int table;
 	
-	PRINTK (("vfat_lookup: name=%s, len=%d\n", 
+	PRINTK2(("vfat_lookup: name=%s, len=%d\n", 
 		 dentry->d_name.name, dentry->d_name.len));
 
 	table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;
@@ -1210,17 +1225,17 @@
 		table++;
 		goto error;
 	}
-	PRINTK (("vfat_lookup 4.5\n"));
+	PRINTK3(("vfat_lookup 4.5\n"));
 	if (!(result = iget(dir->i_sb,sinfo.ino)))
 		return -EACCES;
-	PRINTK (("vfat_lookup 5\n"));
+	PRINTK3(("vfat_lookup 5\n"));
 	if (MSDOS_I(result)->i_busy) { /* mkdir in progress */
 		iput(result);
 		result = NULL;
 		table++;
 		goto error;
 	}
-	PRINTK (("vfat_lookup 6\n"));
+	PRINTK3(("vfat_lookup 6\n"));
 error:
 	dentry->d_op = &vfat_dentry_ops[table];
 	dentry->d_time = dentry->d_parent->d_inode->i_version;
@@ -1240,7 +1255,7 @@
 	struct vfat_slot_info sinfo;
 
 	*result=0;
-	PRINTK(("vfat_create_entry 1\n"));
+	PRINTK1(("vfat_create_entry: Entering\n"));
 	res = vfat_find(dir, qname, 1, 1, is_dir, &sinfo);
 	if (res < 0) {
 		return res;
@@ -1248,16 +1263,16 @@
 
 	offset = sinfo.shortname_offset;
 
-	PRINTK(("vfat_create_entry 2\n"));
+	PRINTK3(("vfat_create_entry 2\n"));
 	bh = NULL;
 	ino = fat_get_entry(dir, &offset, &bh, &de);
 	if (ino < 0) {
-		PRINTK(("vfat_mkdir problem\n"));
+		PRINTK3(("vfat_mkdir problem\n"));
 		if (bh)
 			fat_brelse(sb, bh);
 		return ino;
 	}
-	PRINTK(("vfat_create_entry 3\n"));
+	PRINTK3(("vfat_create_entry 3\n"));
 
 	if ((*result = iget(dir->i_sb,ino)) != NULL)
 		vfat_read_inode(*result);
@@ -1283,7 +1298,7 @@
 	res = vfat_create_entry(dir,&dentry->d_name,0,&result);
 	fat_unlock_creation();
 	if (res < 0) {
-		PRINTK(("vfat_create: unable to get new entry\n"));
+		PRINTK3(("vfat_create: unable to get new entry\n"));
 	} else {
 		dentry->d_time = dentry->d_parent->d_inode->i_version;
 		d_instantiate(dentry,result);
@@ -1298,7 +1313,7 @@
 	struct super_block *sb = dir->i_sb;
 	struct inode *dot;
 
-	PRINTK(("vfat_create_a_dotdir 1\n"));
+	PRINTK2(("vfat_create_a_dotdir: Entering\n"));
 
 	/*
 	 * XXX all times should be set by caller upon successful completion.
@@ -1336,7 +1351,7 @@
 
 	iput(dot);
 
-	PRINTK(("vfat_create_a_dotdir 2\n"));
+	PRINTK3(("vfat_create_a_dotdir 2\n"));
 	return 0;
 }
 
@@ -1348,31 +1363,31 @@
 	struct msdos_dir_entry *de;
 	loff_t offset;
 
-	PRINTK(("vfat_create_dotdirs 1\n"));
+	PRINTK2(("vfat_create_dotdirs: Entering\n"));
 	if ((res = fat_add_cluster(dir)) < 0) return res;
 
-	PRINTK(("vfat_create_dotdirs 2\n"));
+	PRINTK3(("vfat_create_dotdirs 2\n"));
 	offset = 0;
 	bh = NULL;
 	if ((res = fat_get_entry(dir,&offset,&bh,&de)) < 0) return res;
 	
-	PRINTK(("vfat_create_dotdirs 3\n"));
+	PRINTK3(("vfat_create_dotdirs 3\n"));
 	res = vfat_create_a_dotdir(dir, parent, bh, de, res, MSDOS_DOT, 1);
-	PRINTK(("vfat_create_dotdirs 4\n"));
+	PRINTK3(("vfat_create_dotdirs 4\n"));
 	if (res < 0) {
 		fat_brelse(sb, bh);
 		return res;
 	}
-	PRINTK(("vfat_create_dotdirs 5\n"));
+	PRINTK3(("vfat_create_dotdirs 5\n"));
 
 	if ((res = fat_get_entry(dir,&offset,&bh,&de)) < 0) {
 		fat_brelse(sb, bh);
 		return res;
 	}
-	PRINTK(("vfat_create_dotdirs 6\n"));
+	PRINTK3(("vfat_create_dotdirs 6\n"));
 
 	res = vfat_create_a_dotdir(dir, parent, bh, de, res, MSDOS_DOTDOT, 0);
-	PRINTK(("vfat_create_dotdirs 7\n"));
+	PRINTK3(("vfat_create_dotdirs 7\n"));
 	fat_brelse(sb, bh);
 
 	return res;
@@ -1386,12 +1401,6 @@
 	struct buffer_head *bh;
 	struct msdos_dir_entry *de;
 
-	/*
-	 * Prune any child dentries, then verify that
-	 * the directory is empty and not in use.
-	 */
-	shrink_dcache_sb(sb); /* should be child prune */
-
 	if (dir->i_count > 1) {
 		return -EBUSY;
 	}
@@ -1427,6 +1436,7 @@
 	if (dir->i_dev != dentry->d_inode->i_dev || dir == dentry->d_inode) {
 		return -EBUSY;
 	}
+
 	res = vfat_empty(dentry->d_inode);
 	if (res) {
 		return res;
@@ -1498,11 +1508,13 @@
 	return 0;
 }
 
-static void vfat_delete_dentries(struct dentry *dentry)
+/* Replace inodes in alias dentries and drop all but the initial dentry */
+static void drop_replace_inodes(struct dentry *dentry, struct inode *inode)
 {
 	struct list_head *head, *next, *tmp;
 	struct dentry *alias;
 
+	PRINTK1(("drop_replace_inodes: dentry=%p, inode=%p\n", dentry, inode));
 	head = &dentry->d_inode->i_dentry;
 	if (dentry->d_inode) {
 		next = dentry->d_inode->i_dentry.next;
@@ -1510,10 +1522,19 @@
 			tmp = next;
 			next = tmp->next;
 			alias = list_entry(tmp, struct dentry, d_alias);
-			d_delete(alias);
+			if (inode) {
+				list_del(&alias->d_alias);
+				iput(alias->d_inode);
+				d_instantiate(alias, inode);
+				/* dentry is already accounted for */
+				if (alias != dentry) {
+					inode->i_count++;
+				}
+			}
+			if (alias != dentry) {
+				d_drop(alias);
+			}
 		}
-	} else {
-		d_delete(dentry);
 	}
 }
 
@@ -1524,6 +1545,7 @@
 	struct buffer_head *bh;
 	struct vfat_slot_info sinfo;
 
+	PRINTK1(("vfat_rmdirx: dentry=%p\n", dentry));
 	res = vfat_find(dir,&dentry->d_name,1,0,0,&sinfo);
 
 	if (res >= 0 && sinfo.total_slots > 0) {
@@ -1542,9 +1564,11 @@
 int vfat_rmdir(struct inode *dir,struct dentry* dentry)
 {
 	int res;
+	PRINTK1(("vfat_rmdir: dentry=%p, inode=%p\n", dentry, dentry->d_inode));
 	res = vfat_rmdirx(dir, dentry);
 	if (res >= 0) {
-		vfat_delete_dentries(dentry);
+		drop_replace_inodes(dentry, NULL);
+		d_delete(dentry);
 	}
 	return res;
 }
@@ -1559,6 +1583,7 @@
 	struct buffer_head *bh;
 	struct vfat_slot_info sinfo;
 
+	PRINTK1(("vfat_unlinkx: dentry=%p, inode=%p\n", dentry, dentry->d_inode));
 	bh = NULL;
 	res = vfat_find(dir,&dentry->d_name,1,0,0,&sinfo);
 
@@ -1579,6 +1604,7 @@
 	struct inode *inode;
 	int res;
 
+	PRINTK1(("vfat_mkdir: dentry=%p, inode=%p\n", dentry, dentry->d_inode));
 	fat_lock_creation();
 	if ((res = vfat_create_entry(dir,&dentry->d_name,1,&inode)) < 0) {
 		fat_unlock_creation();
@@ -1606,9 +1632,11 @@
 {
 	int res;
 
+	PRINTK1(("vfat_unlink: dentry=%p, inode=%p\n", dentry, dentry->d_inode));
 	res = vfat_unlinkx (dir,dentry,1);
 	if (res >= 0) {
-		vfat_delete_dentries(dentry);
+		drop_replace_inodes(dentry, NULL);
+		d_delete(dentry);
 	}
 	return res;
 }
@@ -1636,8 +1664,12 @@
 	int res, is_dir, i;
 	int locked = 0;
 	struct vfat_slot_info sinfo;
+	int put_new_inode = 0;
 
-	PRINTK(("vfat_rename 1\n"));
+	PRINTK1(("vfat_rename: Entering: old_dentry=%p, old_inode=%p, old ino=%ld, new_dentry=%p, new_inode=%p, new ino=%ld\n",
+		 old_dentry, old_dentry->d_inode, old_dentry->d_inode->i_ino,
+		 new_dentry, new_dentry->d_inode,
+		 new_dentry->d_inode ? new_dentry->d_inode->i_ino : 0));
 	if (old_dir == new_dir && 
 	    old_dentry->d_name.len == new_dentry->d_name.len &&
 	    strncmp(old_dentry->d_name.name, new_dentry->d_name.name, 
@@ -1647,7 +1679,7 @@
 	old_bh = new_bh = NULL;
 	old_inode = new_inode = NULL;
 	res = vfat_find(old_dir,&old_dentry->d_name,1,0,0,&sinfo);
-	PRINTK(("vfat_rename 2\n"));
+	PRINTK3(("vfat_rename 2\n"));
 	if (res < 0) goto rename_done;
 
 	old_slots = sinfo.total_slots;
@@ -1655,7 +1687,7 @@
 	old_offset = sinfo.shortname_offset;
 	old_ino = sinfo.ino;
 	res = fat_get_entry(old_dir, &old_offset, &old_bh, &old_de);
-	PRINTK(("vfat_rename 3\n"));
+	PRINTK3(("vfat_rename 3\n"));
 	if (res < 0) goto rename_done;
 
 	res = -ENOENT;
@@ -1678,15 +1710,15 @@
 
 	res = vfat_find(new_dir,&new_dentry->d_name,1,0,is_dir,&sinfo);
 
-	PRINTK(("vfat_rename 4\n"));
+	PRINTK3(("vfat_rename 4\n"));
 	if (res > -1) {
 		int new_is_dir;
 
-		PRINTK(("vfat_rename 5\n"));
+		PRINTK3(("vfat_rename 5\n"));
 		/* Filename currently exists.  Need to delete it */
 		new_offset = sinfo.shortname_offset;
 		res = fat_get_entry(new_dir, &new_offset, &new_bh, &new_de);
-		PRINTK(("vfat_rename 6\n"));
+		PRINTK3(("vfat_rename 6\n"));
 		if (res < 0) goto rename_done;
 
 		if (!(new_inode = iget(new_dir->i_sb,res)))
@@ -1694,82 +1726,67 @@
 		new_is_dir = S_ISDIR(new_inode->i_mode);
 		iput(new_inode);
 		if (new_is_dir) {
-			PRINTK(("vfat_rename 7\n"));
+			PRINTK3(("vfat_rename 7\n"));
 			res = vfat_rmdirx(new_dir,new_dentry);
-			PRINTK(("vfat_rename 8\n"));
+			PRINTK3(("vfat_rename 8\n"));
 			if (res < 0) goto rename_done;
 		} else {
 			/* Is this the same file, different case? */
 			if (new_inode != old_inode) {
-				PRINTK(("vfat_rename 9\n"));
+				PRINTK3(("vfat_rename 9\n"));
 				res = vfat_unlink(new_dir,new_dentry);
-				PRINTK(("vfat_rename 10\n"));
+				PRINTK3(("vfat_rename 10\n"));
 				if (res < 0) goto rename_done;
 			}
 		}
 	}
 
-	PRINTK(("vfat_rename 11\n"));
+	PRINTK3(("vfat_rename 11\n"));
 	fat_lock_creation(); locked = 1;
 	res = vfat_find(new_dir,&new_dentry->d_name,1,1,is_dir,&sinfo);
 
-	PRINTK(("vfat_rename 12\n"));
+	PRINTK3(("vfat_rename 12\n"));
 	if (res < 0) goto rename_done;
 
 	new_offset = sinfo.shortname_offset;
 	new_ino = sinfo.ino;
-	res = fat_get_entry(new_dir, &new_offset, &new_bh, &new_de);
-	PRINTK(("vfat_rename 13\n"));
-	if (res < 0) goto rename_done;
-
-	new_de->attr = old_de->attr;
-	new_de->time = old_de->time;
-	new_de->date = old_de->date;
-	new_de->ctime_ms = old_de->ctime_ms;
-	new_de->cdate = old_de->cdate;
-	new_de->adate = old_de->adate;
-	new_de->start = old_de->start;
-	new_de->starthi = old_de->starthi;
-	new_de->size = old_de->size;
+	PRINTK3(("vfat_rename 13: new_ino=%d\n", new_ino));
 
 	if (!(new_inode = iget(new_dir->i_sb,new_ino))) goto rename_done;
-	PRINTK(("vfat_rename 14\n"));
+	put_new_inode = 1;
 
-	/* At this point, we have the inodes of the old file and the
-	 * new file.  We need to transfer all information from the old
-	 * inode to the new inode and then delete the slots of the old
-	 * entry
-	 */
+	new_inode->i_mode   = old_inode->i_mode;
+	new_inode->i_size   = old_inode->i_size;
+	new_inode->i_blocks = old_inode->i_blocks;
+	new_inode->i_mtime  = old_inode->i_mtime;
+	new_inode->i_atime  = old_inode->i_atime;
+	new_inode->i_ctime  = old_inode->i_ctime;
+	MSDOS_I(new_inode)->i_ctime_ms = MSDOS_I(old_inode)->i_ctime_ms;
+
+	MSDOS_I(new_inode)->i_start = MSDOS_I(old_inode)->i_start;
+	MSDOS_I(new_inode)->i_logstart = MSDOS_I(old_inode)->i_logstart;
+	MSDOS_I(new_inode)->i_attrs = MSDOS_I(old_inode)->i_attrs;
+
+	mark_inode_dirty(new_inode);
 
-	vfat_read_inode(new_inode);
-	MSDOS_I(old_inode)->i_busy = 1;
-	MSDOS_I(old_inode)->i_linked = new_inode;
-	MSDOS_I(new_inode)->i_oldlink = old_inode;
-	fat_cache_inval_inode(old_inode);
-	PRINTK(("vfat_rename 15: old_slots=%d\n",old_slots));
-	mark_inode_dirty(old_inode);
 	old_dir->i_version = ++event;
+	new_dir->i_version = ++event;
+
+	PRINTK3(("vfat_rename 14: old_slots=%d\n",old_slots));
 
 	/* remove the old entry */
 	for (i = old_slots; i > 0; --i) {
 		res = fat_get_entry(old_dir, &old_longname_offset, &old_bh, &old_de);
 		if (res < 0) {
-			printk("vfat_unlinkx: problem 1\n");
+			printk("vfat_rename: problem 1\n");
 			continue;
 		}
 		old_de->name[0] = DELETED_FLAG;
 		old_de->attr = 0;
 		fat_mark_buffer_dirty(sb, old_bh, 1);
 	}
-	PRINTK(("vfat_rename 15b\n"));
-
-	fat_mark_buffer_dirty(sb, new_bh, 1);
+	PRINTK3(("vfat_rename 15b\n"));
 
-	/* XXX: There is some code in the original MSDOS rename that
-	 * is not duplicated here and it might cause a problem in
-	 * certain circumstances.
-	 */
-	
 	if (S_ISDIR(old_inode->i_mode)) {
 		if ((res = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
 		    &dotdot_de,&dotdot_ino,SCAN_ANY)) < 0) goto rename_done;
@@ -1793,8 +1810,11 @@
 	}
 
 	if (res > 0) res = 0;
+
 	if (res == 0) {
+		drop_replace_inodes(old_dentry, new_inode);
 		d_move(old_dentry, new_dentry);
+		put_new_inode = 0;
 	}
 
 rename_done:
@@ -1804,6 +1824,8 @@
 		fat_brelse(sb, old_bh);
 	if (new_bh)
 		fat_brelse(sb, new_bh);
+	if (put_new_inode)
+		iput(new_inode);
 	return res;
 }
 
diff -u --recursive --new-file v2.1.80/linux/include/asm-i386/hardirq.h linux/include/asm-i386/hardirq.h
--- v2.1.80/linux/include/asm-i386/hardirq.h	Tue Jan 20 12:52:08 1998
+++ linux/include/asm-i386/hardirq.h	Fri Jan 23 13:08:54 1998
@@ -15,7 +15,6 @@
 #define hardirq_exit(cpu)	(local_irq_count[cpu]--)
 
 #define synchronize_irq()	do { } while (0)
-#define synchronize_one_irq(x)	do { } while (0)
 
 #else
 
@@ -30,7 +29,7 @@
 	/* if we didn't own the irq lock, just ignore.. */
 	if (global_irq_holder == (unsigned char) cpu) {
 		global_irq_holder = NO_PROC_ID;
-		global_irq_lock = 0;
+		clear_bit(0,&global_irq_lock);
 	}
 }
 
@@ -70,7 +69,6 @@
 }
 
 extern void synchronize_irq(void);
-extern void synchronize_one_irq(unsigned int irq);
 
 #endif /* __SMP__ */
 
diff -u --recursive --new-file v2.1.80/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v2.1.80/linux/include/asm-i386/smp.h	Sun Dec 21 17:27:18 1997
+++ linux/include/asm-i386/smp.h	Wed Jan 21 12:04:45 1998
@@ -159,7 +159,6 @@
 extern unsigned char boot_cpu_id;
 extern unsigned long cpu_present_map;
 extern volatile int cpu_number_map[NR_CPUS];
-extern volatile int cpu_logical_map[NR_CPUS];
 extern volatile unsigned long smp_invalidate_needed;
 extern void smp_flush_tlb(void);
 extern volatile unsigned long kernel_flag, kernel_counter;
@@ -171,6 +170,11 @@
 extern void smp_invalidate_rcv(void);		/* Process an NMI */
 extern void smp_local_timer_interrupt(struct pt_regs * regs);
 extern void setup_APIC_clock (void);
+extern volatile int __cpu_logical_map[NR_CPUS];
+extern inline int cpu_logical_map(int cpu)
+{
+	return __cpu_logical_map[cpu];
+}
 
 
 /*
@@ -235,5 +239,12 @@
 #define SMP_FROM_INT		1
 #define SMP_FROM_SYSCALL	2
 
+#else
+#ifndef ASSEMBLY
+extern inline int cpu_logical_map(int cpu)
+{
+	return cpu;
+}
+#endif
 #endif
 #endif
diff -u --recursive --new-file v2.1.80/linux/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h
--- v2.1.80/linux/include/asm-i386/softirq.h	Tue Jan 20 12:57:40 1998
+++ linux/include/asm-i386/softirq.h	Fri Jan 23 13:39:52 1998
@@ -4,6 +4,9 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
+extern unsigned int local_bh_count[NR_CPUS];
+#define in_bh()	(local_bh_count[smp_processor_id()] != 0)
+
 #define get_active_bhs()	(bh_mask & bh_active)
 #define clear_active_bhs(x)	atomic_clear_mask((x),&bh_active)
 
@@ -25,23 +28,6 @@
 	set_bit(nr, &bh_active);
 }
 
-/*
- * These use a mask count to correctly handle
- * nested disable/enable calls
- */
-extern inline void disable_bh(int nr)
-{
-	bh_mask &= ~(1 << nr);
-	bh_mask_count[nr]++;
-	synchronize_irq();
-}
-
-extern inline void enable_bh(int nr)
-{
-	if (!--bh_mask_count[nr])
-		bh_mask |= 1 << nr;
-}
-
 #ifdef __SMP__
 
 /*
@@ -49,52 +35,83 @@
  * is entirely private to an implementation, it should not be
  * referenced at all outside of this file.
  */
-extern atomic_t __intel_bh_counter;
+extern atomic_t global_bh_lock;
+extern atomic_t global_bh_count;
 
-extern inline void start_bh_atomic(void)
+extern void synchronize_bh(void);
+
+static inline void start_bh_atomic(void)
 {
-	atomic_inc(&__intel_bh_counter);
-	synchronize_irq();
+	atomic_inc(&global_bh_lock);
+	synchronize_bh();
 }
 
-extern inline void end_bh_atomic(void)
+static inline void end_bh_atomic(void)
 {
-	atomic_dec(&__intel_bh_counter);
+	atomic_dec(&global_bh_lock);
 }
 
 /* These are for the irq's testing the lock */
-static inline int softirq_trylock(void)
+static inline int softirq_trylock(int cpu)
 {
-	atomic_inc(&__intel_bh_counter);
-	if (atomic_read(&__intel_bh_counter) != 1) {
-		atomic_dec(&__intel_bh_counter);
+	unsigned long flags;
+
+	__save_flags(flags);
+	__cli();
+	atomic_inc(&global_bh_count);
+	if (atomic_read(&global_bh_count) != 1 || atomic_read(&global_bh_lock) != 0) {
+		atomic_dec(&global_bh_count);
+		__restore_flags(flags);
 		return 0;
 	}
+	++local_bh_count[cpu];
 	return 1;
 }
 
-#define softirq_endlock()	atomic_dec(&__intel_bh_counter)
+static inline void softirq_endlock(int cpu)
+{
+	__cli();
+	atomic_dec(&global_bh_count);
+	local_bh_count[cpu]--;
+	__sti();
+}
 
 #else
 
-extern int __intel_bh_counter;
-
 extern inline void start_bh_atomic(void)
 {
-	__intel_bh_counter++;
+	local_bh_count[smp_processor_id()]++;
 	barrier();
 }
 
 extern inline void end_bh_atomic(void)
 {
 	barrier();
-	__intel_bh_counter--;
+	local_bh_count[smp_processor_id()]--;
 }
 
 /* These are for the irq's testing the lock */
-#define softirq_trylock()	(__intel_bh_counter ? 0 : (__intel_bh_counter=1))
-#define softirq_endlock()	(__intel_bh_counter = 0)
+#define softirq_trylock()	(in_bh ? 0 : (local_bh_count[smp_processor_id()]=1))
+#define softirq_endlock()	(local_bh_count[smp_processor_id()] = 0)
+#define synchronize_bh()	do { } while (0)
 
 #endif	/* SMP */
+
+/*
+ * These use a mask count to correctly handle
+ * nested disable/enable calls
+ */
+extern inline void disable_bh(int nr)
+{
+	bh_mask &= ~(1 << nr);
+	bh_mask_count[nr]++;
+	synchronize_bh();
+}
+
+extern inline void enable_bh(int nr)
+{
+	if (!--bh_mask_count[nr])
+		bh_mask |= 1 << nr;
+}
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.1.80/linux/include/asm-i386/uaccess.h linux/include/asm-i386/uaccess.h
--- v2.1.80/linux/include/asm-i386/uaccess.h	Tue Jan 20 16:51:57 1998
+++ linux/include/asm-i386/uaccess.h	Fri Jan 23 17:18:35 1998
@@ -263,7 +263,7 @@
 		"	.long 0b,3b\n"					\
 		"	.long 1b,2b\n"					\
 		".previous"						\
-		: "=c"(size)						\
+		: "=&c"(size)						\
 		: "r"(size & 3), "0"(size / 4), "D"(to), "S"(from)	\
 		: "di", "si", "memory")
 
diff -u --recursive --new-file v2.1.80/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.1.80/linux/include/asm-i386/unistd.h	Mon Dec  1 11:16:19 1997
+++ linux/include/asm-i386/unistd.h	Fri Jan 23 16:24:01 1998
@@ -187,6 +187,7 @@
 #define __NR_rt_sigsuspend	179
 #define __NR_pread		180
 #define __NR_pwrite		181
+#define __NR_lchown		182
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
diff -u --recursive --new-file v2.1.80/linux/include/asm-mips/ioctls.h linux/include/asm-mips/ioctls.h
--- v2.1.80/linux/include/asm-mips/ioctls.h	Tue Dec 16 12:46:07 1997
+++ linux/include/asm-mips/ioctls.h	Fri Jan 23 16:39:04 1998
@@ -98,6 +98,7 @@
 #define TIOCTTYGSTRUCT	0x5487  /* For debugging only */
 #define TIOCSBRK	0x5427  /* BSD compatibility */
 #define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
 
 #define TIOCSERCONFIG	0x5488
 #define TIOCSERGWILD	0x5489
diff -u --recursive --new-file v2.1.80/linux/include/linux/blk.h linux/include/linux/blk.h
--- v2.1.80/linux/include/linux/blk.h	Tue Jan 20 16:51:57 1998
+++ linux/include/linux/blk.h	Fri Jan 23 17:38:05 1998
@@ -39,6 +39,9 @@
 #ifdef CONFIG_CDROM
 extern int cdrom_init(void);
 #endif CONFIG_CDROM 
+#ifdef CONFIG_ISP16_CDI
+extern int isp16_init(void);
+#endif CONFIG_ISP16_CDI
 #ifdef CONFIG_CDU31A
 extern int cdu31a_init(void);
 #endif CONFIG_CDU31A
diff -u --recursive --new-file v2.1.80/linux/include/linux/kernel_stat.h linux/include/linux/kernel_stat.h
--- v2.1.80/linux/include/linux/kernel_stat.h	Tue Jan 20 12:57:40 1998
+++ linux/include/linux/kernel_stat.h	Wed Jan 21 12:13:57 1998
@@ -2,6 +2,7 @@
 #define _LINUX_KERNEL_STAT_H
 
 #include <asm/irq.h>
+#include <asm/smp.h>
 #include <linux/smp.h>
 #include <linux/tasks.h>
 
@@ -25,7 +26,7 @@
 	unsigned int dk_drive_wblk[DK_NDRIVE];
 	unsigned int pgpgin, pgpgout;
 	unsigned int pswpin, pswpout;
-	unsigned int interrupts[NR_CPUS][NR_IRQS];
+	unsigned int irqs[NR_CPUS][NR_IRQS];
 	unsigned int ipackets, opackets;
 	unsigned int ierrors, oerrors;
 	unsigned int collisions;
@@ -33,5 +34,18 @@
 };
 
 extern struct kernel_stat kstat;
+
+/*
+ * Number of interrupts per specific IRQ source, since bootup
+ */
+extern inline int kstat_irqs (int irq)
+{
+	int i, sum=0;
+
+	for (i = 0 ; i < smp_num_cpus ; i++)
+		sum += kstat.irqs[cpu_logical_map(i)][irq];
+
+	return sum;
+}
 
 #endif /* _LINUX_KERNEL_STAT_H */
diff -u --recursive --new-file v2.1.80/linux/include/linux/minix_fs_sb.h linux/include/linux/minix_fs_sb.h
--- v2.1.80/linux/include/linux/minix_fs_sb.h	Thu Jan  4 04:07:58 1996
+++ linux/include/linux/minix_fs_sb.h	Wed Jan 21 14:27:57 1998
@@ -12,10 +12,10 @@
 			unsigned long s_firstdatazone;
 			unsigned long s_log_zone_size;
 			unsigned long s_max_size;
-			struct buffer_head * s_imap[8];
-			struct buffer_head * s_zmap[64];
 			unsigned long s_dirsize;
 			unsigned long s_namelen;
+			struct buffer_head ** s_imap;
+			struct buffer_head ** s_zmap;
 			struct buffer_head * s_sbh;
 			struct minix_super_block * s_ms;
 			unsigned short s_mount_state;
diff -u --recursive --new-file v2.1.80/linux/include/linux/msdos_fs_i.h linux/include/linux/msdos_fs_i.h
--- v2.1.80/linux/include/linux/msdos_fs_i.h	Thu Oct 23 14:00:15 1997
+++ linux/include/linux/msdos_fs_i.h	Wed Jan 21 17:46:56 1998
@@ -28,16 +28,9 @@
 	int i_start;	/* first cluster or 0 */
 	int i_logstart;	/* logical first cluster */
 	int i_attrs;	/* unused attribute bits */
+	int i_ctime_ms;	/* unused change time in milliseconds */
 	int i_busy;	/* file is either deleted but still open, or
 			   inconsistent (mkdir) */
-	struct inode *i_depend; /* pointer to inode that depends on the
-				   current inode */
-	struct inode *i_old;	/* pointer to the old inode this inode
-				   depends on */
-	struct inode *i_linked;	/* pointer to inode linked to the current one,
-				   happens when an open file is moved */
-	struct inode *i_oldlink;/* pointer to open inode that references
-				   the same file */
 	int i_binary;	/* file contains non-text data */
 };
 
diff -u --recursive --new-file v2.1.80/linux/include/linux/nfsd/nfsfh.h linux/include/linux/nfsd/nfsfh.h
--- v2.1.80/linux/include/linux/nfsd/nfsfh.h	Tue Jan 20 16:53:27 1998
+++ linux/include/linux/nfsd/nfsfh.h	Fri Jan 23 17:20:30 1998
@@ -116,12 +116,16 @@
 	dfprintk(FILEOP, "nfsd: fh_lock(%x/%ld) locked = %d\n",
 			SVCFH_DEV(fhp), SVCFH_INO(fhp), fhp->fh_locked);
 	 */
-	if (!fhp->fh_locked) {
-		down(&inode->i_sem);
-		if (!fhp->fh_pre_mtime)
-			fhp->fh_pre_mtime = inode->i_mtime;
-		fhp->fh_locked = 1;
+	if (fhp->fh_locked) {
+		printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
+			fhp->fh_dentry->d_parent->d_name.name,
+			fhp->fh_dentry->d_name.name);
+		return;
 	}
+	down(&inode->i_sem);
+	if (!fhp->fh_pre_mtime)
+		fhp->fh_pre_mtime = inode->i_mtime;
+	fhp->fh_locked = 1;
 }
 
 /*
@@ -130,9 +134,8 @@
 static inline void
 fh_unlock(struct svc_fh *fhp)
 {
-	struct inode	*inode = fhp->fh_dentry->d_inode;
-
 	if (fhp->fh_locked) {
+		struct inode *inode = fhp->fh_dentry->d_inode;
 		if (!fhp->fh_post_version)
 			fhp->fh_post_version = inode->i_version;
 		fhp->fh_locked = 0;
diff -u --recursive --new-file v2.1.80/linux/include/linux/signal.h linux/include/linux/signal.h
--- v2.1.80/linux/include/linux/signal.h	Tue Dec  9 09:31:46 1997
+++ linux/include/linux/signal.h	Fri Jan 23 17:38:05 1998
@@ -174,6 +174,11 @@
 	set->sig[0] &= ~mask;
 }
 
+extern inline int sigtestsetmask(sigset_t *set, unsigned long mask)
+{
+	return (set->sig[0] & mask) != 0;
+}
+
 extern inline void siginitset(sigset_t *set, unsigned long mask)
 {
 	set->sig[0] = mask;
diff -u --recursive --new-file v2.1.80/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h
--- v2.1.80/linux/include/linux/smb_fs.h	Tue Jan 20 16:53:52 1998
+++ linux/include/linux/smb_fs.h	Fri Jan 23 17:21:03 1998
@@ -76,6 +76,7 @@
  */
 #define SMB_FIX_WIN95	0x0001	/* Win 95 server */
 #define SMB_FIX_OLDATTR	0x0002	/* Use core getattr (Win 95 speedup) */
+#define SMB_FIX_DIRATTR	0x0004	/* Use find_first for getattr */
 
 /* linux/fs/smbfs/mmap.c */
 int smb_mmap(struct file *, struct vm_area_struct *);
@@ -95,7 +96,6 @@
 void smb_get_inode_attr(struct inode *, struct smb_fattr *);
 void smb_invalidate_inodes(struct smb_sb_info *);
 int  smb_revalidate_inode(struct dentry *);
-int  smb_refresh_inode(struct inode *);
 int  smb_notify_change(struct dentry *, struct iattr *);
 unsigned long smb_invent_inos(unsigned long);
 struct inode *smb_iget(struct super_block *, struct smb_fattr *);
@@ -112,8 +112,8 @@
 void smb_close_dentry(struct dentry *);
 int smb_close_fileid(struct dentry *, __u16);
 int smb_open(struct dentry *, int);
-int smb_proc_read(struct inode *, off_t, int, char *);
-int smb_proc_write(struct inode *, off_t, int, const char *);
+int smb_proc_read(struct dentry *, off_t, int, char *);
+int smb_proc_write(struct dentry *, off_t, int, const char *);
 int smb_proc_create(struct dentry *, __u16, time_t, __u16 *);
 int smb_proc_mv(struct dentry *, struct dentry *);
 int smb_proc_mkdir(struct dentry *);
diff -u --recursive --new-file v2.1.80/linux/include/linux/smb_fs_i.h linux/include/linux/smb_fs_i.h
--- v2.1.80/linux/include/linux/smb_fs_i.h	Tue Dec  9 00:07:19 1997
+++ linux/include/linux/smb_fs_i.h	Wed Jan 21 10:09:31 1998
@@ -21,15 +21,14 @@
 	 * file handles are local to a connection. A file is open if
 	 * (open == generation).
 	 */
-        unsigned int open;
+        unsigned int open;	/* open generation */
 	__u16 fileid;		/* What id to handle a file with? */
 	__u16 attr;		/* Attribute fields, DOS value */
 
-	__u16 access;		/* Access bits. */
+	__u16 access;		/* Access mode */
 	__u16 cache_valid;	/* dircache valid? */
 	unsigned long oldmtime;	/* last time refreshed */
 	unsigned long closed;	/* timestamp when closed */
-	void * dentry;		/* The dentry we were opened with */
 };
 
 #endif
diff -u --recursive --new-file v2.1.80/linux/include/linux/smp.h linux/include/linux/smp.h
--- v2.1.80/linux/include/linux/smp.h	Tue Jan 20 12:52:08 1998
+++ linux/include/linux/smp.h	Wed Jan 21 12:10:52 1998
@@ -61,5 +61,6 @@
 #define smp_message_pass(t,m,d,w)	
 #define smp_threads_ready		1
 #define kernel_lock()
+
 #endif
 #endif
diff -u --recursive --new-file v2.1.80/linux/include/linux/tty.h linux/include/linux/tty.h
--- v2.1.80/linux/include/linux/tty.h	Tue Jan 20 16:51:56 1998
+++ linux/include/linux/tty.h	Fri Jan 23 17:38:05 1998
@@ -303,6 +303,7 @@
 extern int pcxe_init(void);
 extern int pc_init(void);
 extern int vcs_init(void);
+extern int rp_init(void);
 extern int cy_init(void);
 extern int stl_init(void);
 extern int stli_init(void);
@@ -351,10 +352,6 @@
 /* pcxx.c */
 
 extern int pcxe_open(struct tty_struct *tty, struct file *filp);
-
-/* epca.c */
-
-extern int pc_open(struct tty_struct *tty, struct file *filp);
 
 /* console.c */
 
diff -u --recursive --new-file v2.1.80/linux/include/linux/videodev.h linux/include/linux/videodev.h
--- v2.1.80/linux/include/linux/videodev.h	Mon Jan 12 14:48:22 1998
+++ linux/include/linux/videodev.h	Fri Jan 23 17:38:05 1998
@@ -173,4 +173,14 @@
 #define VID_HARDWARE_PMS	3
 #define VID_HARDWARE_QCAM_C	4
 
+/*
+ *	Initialiser list
+ */
+ 
+struct video_init
+{
+	char *name;
+	int (*init)(struct video_init *);
+};
+
 #endif
diff -u --recursive --new-file v2.1.80/linux/init/main.c linux/init/main.c
--- v2.1.80/linux/init/main.c	Tue Jan 20 12:52:08 1998
+++ linux/init/main.c	Wed Jan 21 13:00:05 1998
@@ -927,8 +927,6 @@
 
 #else
 
-extern void setup_IO_APIC(void);
-
 /*
  *	Multiprocessor idle thread is in arch/...
  */
@@ -1051,7 +1049,6 @@
 	printk("POSIX conformance testing by UNIFIX\n");
 #ifdef __SMP__
 	smp_init();
-	setup_IO_APIC();
 #endif
 #ifdef CONFIG_SYSCTL
 	sysctl_init();
diff -u --recursive --new-file v2.1.80/linux/kernel/acct.c linux/kernel/acct.c
--- v2.1.80/linux/kernel/acct.c	Mon Dec  1 10:34:12 1997
+++ linux/kernel/acct.c	Fri Jan 23 17:38:05 1998
@@ -268,8 +268,8 @@
 
 
 	/*
-	 * Fill the accounting struct with the needed info as recorded by the different
-	 * kernel functions.
+	 * Fill the accounting struct with the needed info as recorded
+	 * by the different kernel functions.
 	 */
 	memset((caddr_t)&ac, 0, sizeof(struct acct));
 
@@ -304,7 +304,7 @@
 	}
 	vsize = vsize / 1024;
 	ac.ac_mem = encode_comp_t(vsize);
-	ac.ac_io = encode_comp_t(current->io_usage);
+	ac.ac_io = encode_comp_t(current->io_usage);	/* %% */
 	ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
 	ac.ac_minflt = encode_comp_t(current->min_flt);
 	ac.ac_majflt = encode_comp_t(current->maj_flt);
diff -u --recursive --new-file v2.1.80/linux/kernel/fork.c linux/kernel/fork.c
--- v2.1.80/linux/kernel/fork.c	Wed Jan 14 13:21:14 1998
+++ linux/kernel/fork.c	Wed Jan 21 10:06:56 1998
@@ -437,7 +437,6 @@
  */
 int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
 {
-        int i;
 	int nr;
 	int error = -ENOMEM;
 	struct task_struct *p;
@@ -483,11 +482,14 @@
 	p->times.tms_utime = p->times.tms_stime = 0;
 	p->times.tms_cutime = p->times.tms_cstime = 0;
 #ifdef __SMP__
-	p->has_cpu = 0;
-	p->processor = NO_PROC_ID;
-	/* ?? should we just memset this ?? */
-	for(i = 0; i < smp_num_cpus; i++)
-		p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0;
+	{
+		int i;
+		p->has_cpu = 0;
+		p->processor = NO_PROC_ID;
+		/* ?? should we just memset this ?? */
+		for(i = 0; i < smp_num_cpus; i++)
+			p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0;
+	}
 #endif
 	p->lock_depth = 0;
 	p->start_time = jiffies;
diff -u --recursive --new-file v2.1.80/linux/kernel/printk.c linux/kernel/printk.c
--- v2.1.80/linux/kernel/printk.c	Tue Jan 20 16:45:08 1998
+++ linux/kernel/printk.c	Fri Jan 23 16:53:00 1998
@@ -229,9 +229,7 @@
 	static signed char msg_level = -1;
 	long flags;
 
-	__save_flags(flags);
-	__cli();
-	spin_lock(&console_lock);
+	spin_lock_irqsave(&console_lock, flags);
 	va_start(args, fmt);
 	i = vsprintf(buf + 3, fmt, args); /* hopefully i < sizeof(buf)-4 */
 	buf_end = buf + 3 + i;
@@ -279,9 +277,8 @@
 		if (line_feed)
 			msg_level = -1;
 	}
-	spin_unlock(&console_lock);
-	__restore_flags(flags);
-/*	wake_up_interruptible(&log_wait);*/
+	spin_unlock_irqrestore(&console_lock, flags);
+	wake_up_interruptible(&log_wait);
 	return i;
 }
 
diff -u --recursive --new-file v2.1.80/linux/kernel/softirq.c linux/kernel/softirq.c
--- v2.1.80/linux/kernel/softirq.c	Tue May 13 22:41:20 1997
+++ linux/kernel/softirq.c	Fri Jan 23 15:38:20 1998
@@ -62,14 +62,14 @@
 
 asmlinkage void do_bottom_half(void)
 {
-	if (softirq_trylock()) {
-		int cpu = smp_processor_id();
+	int cpu = smp_processor_id();
 
+	if (softirq_trylock(cpu)) {
 		if (hardirq_trylock(cpu)) {
 			__sti();
 			run_bottom_halves();
 			hardirq_endlock(cpu);
 		}
-		softirq_endlock();
+		softirq_endlock(cpu);
 	}
 }
diff -u --recursive --new-file v2.1.80/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v2.1.80/linux/net/ipv4/arp.c	Mon Jan 12 15:28:25 1998
+++ linux/net/ipv4/arp.c	Wed Jan 21 10:11:32 1998
@@ -392,7 +392,9 @@
 
 /* END OF OBSOLETE FUNCTIONS */
 
-
+/*
+ * Note: requires bh_atomic locking.
+ */
 int arp_bind_neighbour(struct dst_entry *dst)
 {
 	struct device *dev = dst->dev;
@@ -734,11 +736,9 @@
 	start_bh_atomic();
 	neigh = __neigh_lookup(&arp_tbl, &ip, dev, 1);
 	if (neigh) {
-		unsigned state = 0;
-		if (r->arp_flags&ATF_PERM)
+		unsigned state = NUD_STALE;
+		if (r->arp_flags & ATF_PERM)
 			state = NUD_PERMANENT;
-		else
-			state = NUD_STALE;
 		err = neigh_update(neigh, (r->arp_flags&ATF_COM) ?
 				   r->arp_ha.sa_data : NULL, state, 1, 0);
 		neigh_release(neigh);
@@ -764,16 +764,21 @@
 static int arp_req_get(struct arpreq *r, struct device *dev)
 {
 	u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
-	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
+	struct neighbour *neigh;
+	int err = -ENXIO;
+
+	start_bh_atomic();
+	neigh = __neigh_lookup(&arp_tbl, &ip, dev, 0);
 	if (neigh) {
 		memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
 		r->arp_ha.sa_family = dev->type;
 		strncpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
 		r->arp_flags = arp_state_to_flags(neigh);
 		neigh_release(neigh);
-		return 0;
+		err = 0;
 	}
-	return -ENXIO;
+	end_bh_atomic();
+	return err;
 }
 
 int arp_req_delete(struct arpreq *r, struct device * dev)
@@ -802,7 +807,7 @@
 
 	err = -ENXIO;
 	start_bh_atomic();
-	neigh = neigh_lookup(&arp_tbl, &ip, dev);
+	neigh = __neigh_lookup(&arp_tbl, &ip, dev, 0);
 	if (neigh) {
 		err = neigh_update(neigh, NULL, NUD_FAILED, 1, 0);
 		neigh_release(neigh);
@@ -856,6 +861,11 @@
 		err = -EINVAL;
 		if ((r.arp_flags & ATF_COM) && r.arp_ha.sa_family != dev->type)
 			goto out;
+	} else if (cmd != SIOCSARP) {
+		/* dev has not been set ... */
+		printk(KERN_ERR "arp_ioctl: invalid, null device\n");
+		err = -EINVAL;
+		goto out;
 	}
 
 	switch(cmd) {
@@ -863,6 +873,7 @@
 	        err = arp_req_delete(&r, dev);
 		break;
 	case SIOCSARP:
+		/* This checks for dev == NULL */
 		err = arp_req_set(&r, dev);
 		break;
 	case SIOCGARP:
diff -u --recursive --new-file v2.1.80/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.1.80/linux/net/ipv4/tcp.c	Sun Jan 18 12:28:34 1998
+++ linux/net/ipv4/tcp.c	Wed Jan 21 09:41:19 1998
@@ -614,7 +614,7 @@
 			mask |= POLLIN | POLLRDNORM;
 
 #if 1 /* This needs benchmarking and real world tests */
-		space = sk->dst_cache->pmtu + 128;
+		space = (sk->dst_cache ? sk->dst_cache->pmtu : sk->mss) + 128;
 		if (space < 2048) /* XXX */
 			space = 2048;
 #else /* 2.0 way */
@@ -663,7 +663,7 @@
 			return put_user(amount, (int *)arg);
 		}
 		default:
-			return(-EINVAL);
+			return(-ENOIOCTLCMD);
 	};
 }
 
diff -u --recursive --new-file v2.1.80/linux/scripts/Menuconfig linux/scripts/Menuconfig
--- v2.1.80/linux/scripts/Menuconfig	Mon Jan  5 01:41:01 1998
+++ linux/scripts/Menuconfig	Wed Jan 21 17:51:41 1998
@@ -40,6 +40,9 @@
 #
 # 221297 Michael Chastain (mec@shout.net) - make define_bool actually
 # define its arguments so that later tests on them work right.
+#
+# 160198 Michael Chastain (mec@shout.net) - fix bug with 'c' command
+# (complement existing value) when used on virgin uninitialized variables.
 #----------------------------------------------------------------------------
 
 
@@ -349,6 +352,7 @@
 		   	case $x in
 		   	y) eval $1=n ;;
 		   	n) eval $1=y ;;
+			*) eval $1=y ;;
 		   	esac ;;
 		*)	eval $1=n ;;
 		esac
@@ -392,6 +396,7 @@
 			case $x in
 			m) eval $1=n ;;
 			n) eval $1=m ;;
+			*) eval $1=m ;;
 			esac ;;
 		*)	eval $1=n ;;
 		esac
@@ -416,6 +421,7 @@
 		   y) eval $1=n ;;
 		   n) eval $1=m ;;
 		   m) eval $1=y ;;
+		   *) eval $1=y ;;
 		   esac ;;
 		*) eval $1=n ;;
 		esac
